Можно ли передать параметр в представление в Microsoft SQL Server?
Я попытался create view
следующим образом, но он не работает:
create or replace view v_emp(eno number) as select * from emp where emp_id=&eno;
Можно ли передать параметр в представление в Microsoft SQL Server?
Я попытался create view
следующим образом, но он не работает:
create or replace view v_emp(eno number) as select * from emp where emp_id=&eno;
Как уже было сказано, вы не можете.
Возможным решением было бы реализовать хранимую функцию, например:
CREATE FUNCTION v_emp (@pintEno INT)
RETURNS TABLE
AS
RETURN
SELECT * FROM emp WHERE [email protected];
Это позволяет вам использовать его как обычный вид с помощью:
SELECT * FROM v_emp(10)
Есть два способа добиться того, чего вы хотите неудачно, и не может быть сделано с помощью представления.
Вы можете создать пользовательскую функцию, зависящую от таблицы, которая принимает требуемый параметр и возвращает результат запроса
Или вы можете сделать почти то же самое, но создать хранимую процедуру вместо пользовательской функции.
Пример
хранимая процедура будет выглядеть как
CREATE PROCEDURE s_emp
(
@enoNumber INT
)
AS
SELECT
*
FROM
emp
WHERE
[email protected]
Или пользовательская функция будет выглядеть как
CREATE FUNCTION u_emp
(
@enoNumber INT
)
RETURNS TABLE
AS
RETURN
(
SELECT
*
FROM
emp
WHERE
[email protected]
)
Нет, вы не можете, как сказал Младен Прадждич. Представьте себе представление как "статический фильтр" на столе или комбинацию таблиц. Например: представление может объединять таблицы Order
и Customer
, поэтому вы получаете новую "таблицу" строк из Order
вместе с новыми столбцами, содержащими имя клиента и номер клиента (комбинацию таблиц). Или вы можете создать представление, которое выбирает только необработанные заказы из таблицы Order
(статический фильтр).
Затем вы выбираете из представления, как вы бы выбрали из любой другой "нормальной" таблицы - вся "нестатическая" фильтрация должна выполняться вне представления (например, "Получать все заказы для клиентов под названием" Миллер "или" Получите необработанные заказы, которые пришли 24 декабря ").
Обычно представления не параметризованы. Но вы всегда можете ввести некоторые параметры. Например, используя контекст сеанса:
CREATE VIEW my_view
AS
SELECT *
FROM tab
WHERE num = SESSION_CONTEXT(N'my_num');
Призвание:
EXEC sp_set_session_context 'my_num', 1;
SELECT * FROM my_view;
И другой:
EXEC sp_set_session_context 'my_num', 2;
SELECT * FROM my_view;
То же самое применимо для Oracle (конечно, синтаксис для функции контекста отличается).
Хакерным способом сделать это без хранимых процедур или функций будет создание таблицы настроек в вашей базе данных с столбцами Id, Param1, Param2 и т.д. Вставьте строку в эту таблицу, содержащую значения Id = 1, Param1 = 0, Param2 = 0 и т.д. Затем вы можете добавить соединение к этой таблице в своем представлении, чтобы создать желаемый эффект, и обновить таблицу параметров перед запуском представления. Если у вас есть несколько пользователей, обновляющих таблицу параметров и одновременное выполнение представления, это может пойти не так, но в противном случае оно должно работать нормально. Что-то вроде:
CREATE VIEW v_emp
AS
SELECT *
FROM emp E
INNER JOIN settings S
ON S.Id = 1 AND E.emp_id = S.Param1
Зачем вам нужен параметр? Вы можете просто использовать предложение WHERE
.
create view v_emp as select * from emp ;
и ваш запрос должен выполнить задание:
select * from v_emp where emp_id=&eno;
нет. если вы должны затем использовать определенную пользователем функцию, с которой вы можете передать параметры.
Нет, представление запрашивается не иначе, как выбор из таблицы.
Чтобы сделать то, что вы хотите, используйте определенную пользователем табличную функцию с одним или несколькими параметрами
Представление представляет собой не что иное, как предваряемый оператор SELECT. Итак, единственный реальный ответ: Нет, вы не можете.
Я думаю, что вы действительно хотите сделать, это создать хранимую процедуру, где в принципе вы можете использовать любой действующий SQL, чтобы делать все, что хотите, включая принимать параметры и выбирать данные.
Кажется вероятным, что вам действительно нужно только добавить предложение where, когда вы выберете из своего представления, но вы действительно не предоставили достаточно подробностей, чтобы быть уверенным.
мы можем написать хранимую процедуру с входными параметрами, а затем использовать эту хранимую процедуру для получения набора результатов из представления. см. пример ниже.
хранимая процедура
CREATE PROCEDURE [dbo].[sp_Report_LoginSuccess] -- [sp_Report_LoginSuccess] '01/01/2010','01/30/2010'
@fromDate datetime,
@toDate datetime,
@RoleName varchar(50),
@Success int
as
If @RoleName != 'All'
Begin
If @Success!=2
Begin
--fetch based on true or false
Select * from vw_Report_LoginSuccess
where logindatetime between dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
And RTrim(Upper(RoleName)) = RTrim(Upper(@RoleName)) and [email protected]
End
Else
Begin
-- fetch all
Select * from vw_Report_LoginSuccess
where logindatetime between dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
And RTrim(Upper(RoleName)) = RTrim(Upper(@RoleName))
End
End
Else
Begin
If @Success!=2
Begin
Select * from vw_Report_LoginSuccess
where logindatetime between dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
and [email protected]
End
Else
Begin
Select * from vw_Report_LoginSuccess
where logindatetime between dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
End
End
и представление, из которого мы можем получить результирующий набор,
CREATE VIEW [dbo].[vw_Report_LoginSuccess]
AS
SELECT '3' AS UserDetailID, dbo.tblLoginStatusDetail.Success, CONVERT(varchar, dbo.tblLoginStatusDetail.LoginDateTime, 101) AS LoginDateTime,
CONVERT(varchar, dbo.tblLoginStatusDetail.LogoutDateTime, 101) AS LogoutDateTime, dbo.tblLoginStatusDetail.TokenID,
dbo.tblUserDetail.SubscriberID, dbo.aspnet_Roles.RoleId, dbo.aspnet_Roles.RoleName
FROM dbo.tblLoginStatusDetail INNER JOIN
dbo.tblUserDetail ON dbo.tblLoginStatusDetail.UserDetailID = dbo.tblUserDetail.UserDetailID INNER JOIN
dbo.aspnet_UsersInRoles ON dbo.tblUserDetail.UserID = dbo.aspnet_UsersInRoles.UserId INNER JOIN
dbo.aspnet_Roles ON dbo.aspnet_UsersInRoles.RoleId = dbo.aspnet_Roles.RoleId
WHERE (dbo.tblLoginStatusDetail.Success = 0)
UNION all
SELECT dbo.tblLoginStatusDetail.UserDetailID, dbo.tblLoginStatusDetail.Success, CONVERT(varchar, dbo.tblLoginStatusDetail.LoginDateTime, 101)
AS LoginDateTime, CONVERT(varchar, dbo.tblLoginStatusDetail.LogoutDateTime, 101) AS LogoutDateTime, dbo.tblLoginStatusDetail.TokenID,
dbo.tblUserDetail.SubscriberID, dbo.aspnet_Roles.RoleId, dbo.aspnet_Roles.RoleName
FROM dbo.tblLoginStatusDetail INNER JOIN
dbo.tblUserDetail ON dbo.tblLoginStatusDetail.UserDetailID = dbo.tblUserDetail.UserDetailID INNER JOIN
dbo.aspnet_UsersInRoles ON dbo.tblUserDetail.UserID = dbo.aspnet_UsersInRoles.UserId INNER JOIN
dbo.aspnet_Roles ON dbo.aspnet_UsersInRoles.RoleId = dbo.aspnet_Roles.RoleId
WHERE (dbo.tblLoginStatusDetail.Success = 1) AND (dbo.tblUserDetail.SubscriberID LIKE N'P%')
Как я знаю, представление может быть чем-то вроде команды select. Вы также можете добавить параметры для этого выбора, например, в таких выражениях, как:
WHERE (exam_id = @var)
Нет, представление статично. Одна вещь, которую вы можете сделать (в зависимости от версии SQl-сервера), - это индексировать представление.
В вашем примере (только для одной таблицы) индексированное представление не имеет никакого преимущества просто запросить таблицу с индексом на нем, но если вы делаете много соединений в таблицах с условиями соединения, индексированное представление может сильно улучшить производительность.
Если вы не хотите использовать функцию, вы можете использовать что-то вроде этого
-- VIEW
CREATE VIEW [dbo].[vwPharmacyProducts]
AS
SELECT PharmacyId, ProductId
FROM dbo.Stock
WHERE (TotalQty > 0)
-- Use of view inside a stored procedure
CREATE PROCEDURE [dbo].[usp_GetProductByFilter]
( @pPharmacyId int ) AS
IF @pPharmacyId = 0 BEGIN SET @pPharmacyId = NULL END
SELECT P.[ProductId], P.[strDisplayAs] FROM [Product] P
WHERE (P.[bDeleted] = 0)
AND (P.[ProductId] IN (Select vPP.ProductId From vwPharmacyProducts vPP
Where vPP.PharmacyId = @pPharmacyId)
OR @pPharmacyId IS NULL
)
Надеюсь, что это поможет
нет вы можете передать этот параметр процедуре в виде
Вот вариант, который я пока не видел:
Просто добавьте столбец, который вы хотите ограничить представлению:
create view emp_v as (
select emp_name, emp_id from emp;
)
select emp_v.emp_name from emp_v
where emp_v.emp_id = (id to restrict by)
Вы можете обойти только для запуска представления, SQL будет вином и криком, но просто сделайте это и запустите его! Вы не можете сохранить.
create or replace view v_emp(eno number) as select * from emp where (emp_id = @Parameter1);
Ваше представление может ссылаться на внешнюю таблицу, содержащую ваши параметры.
Как уже упоминалось, представление SQL Server не может иметь внешние входные параметры. Однако вы можете легко подделывать переменную в своем представлении с помощью CTE. Вы можете протестировать его в своей версии SQL Server.
CREATE VIEW vwImportant_Users AS
WITH params AS (
SELECT
varType='%Admin%',
varMinStatus=1)
SELECT status, name
FROM sys.sysusers, params
WHERE status > varMinStatus OR name LIKE varType
SELECT * FROM vwImportant_Users
выход:
status name
12 dbo
0 db_accessadmin
0 db_securityadmin
0 db_ddladmin
также через JOIN
WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name
FROM sys.sysusers INNER JOIN params ON 1=1
WHERE status > varMinStatus OR name LIKE varType
также через CROSS APPLY
WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name
FROM sys.sysusers CROSS APPLY params
WHERE status > varMinStatus OR name LIKE varType
У меня есть идея, которую я еще не попробовал. Ты можешь сделать:
CREATE VIEW updated_customers AS
SELECT * FROM customer as aa
LEFT JOIN customer_rec as bb
ON aa.id = bb.customer_id
WHERE aa.updated_at between (SELECT start_date FROM config WHERE active = 1)
and (SELECT end_date FROM config WHERE active = 1)
Ваши параметры будут сохранены и изменены в таблице настроек.
Я понял эту задачу для своих нужд следующим образом
set nocount on;
declare @ToDate date = dateadd(month,datediff(month,0,getdate())-1,0)
declare @year varchar(4) = year(@ToDate)
declare @month varchar(2) = month(@ToDate)
declare @sql nvarchar(max)
set @sql = N'
create or alter view dbo.wTempLogs
as
select * from dbo.y2019
where
year(LogDate) = ''_year_''
and
month(LogDate) = ''_month_'' '
select @sql = replace(replace(@sql,'_year_',@year),'_month_',@month)
execute sp_executesql @sql
declare @errmsg nvarchar(max)
set @errMsg = @sql
raiserror (@errMsg, 0,1) with nowait