Можем ли мы передать параметры в представление в SQL?

Можно ли передать параметр в представление в Microsoft SQL Server?

Я попытался create view следующим образом, но он не работает:

create or replace view v_emp(eno number) as select * from emp where emp_id=&eno;

Ответ 1

Как уже было сказано, вы не можете.

Возможным решением было бы реализовать хранимую функцию, например:

CREATE FUNCTION v_emp (@pintEno INT)
RETURNS TABLE
AS
RETURN
   SELECT * FROM emp WHERE [email protected];

Это позволяет вам использовать его как обычный вид с помощью:

SELECT * FROM v_emp(10)

Ответ 2

Есть два способа добиться того, чего вы хотите неудачно, и не может быть сделано с помощью представления.

Вы можете создать пользовательскую функцию, зависящую от таблицы, которая принимает требуемый параметр и возвращает результат запроса

Или вы можете сделать почти то же самое, но создать хранимую процедуру вместо пользовательской функции.

Пример

хранимая процедура будет выглядеть как

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]
)

Ответ 3

Нет, вы не можете, как сказал Младен Прадждич. Представьте себе представление как "статический фильтр" на столе или комбинацию таблиц. Например: представление может объединять таблицы Order и Customer, поэтому вы получаете новую "таблицу" строк из Order вместе с новыми столбцами, содержащими имя клиента и номер клиента (комбинацию таблиц). Или вы можете создать представление, которое выбирает только необработанные заказы из таблицы Order (статический фильтр).

Затем вы выбираете из представления, как вы бы выбрали из любой другой "нормальной" таблицы - вся "нестатическая" фильтрация должна выполняться вне представления (например, "Получать все заказы для клиентов под названием" Миллер "или" Получите необработанные заказы, которые пришли 24 декабря ").

Ответ 4

Обычно представления не параметризованы. Но вы всегда можете ввести некоторые параметры. Например, используя контекст сеанса:

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;

DBFiddle Demo

То же самое применимо для Oracle (конечно, синтаксис для функции контекста отличается).

Ответ 5

Хакерным способом сделать это без хранимых процедур или функций будет создание таблицы настроек в вашей базе данных с столбцами 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

Ответ 6

Зачем вам нужен параметр? Вы можете просто использовать предложение WHERE.

create view v_emp as select * from emp ;

и ваш запрос должен выполнить задание:

select * from v_emp where emp_id=&eno;

Ответ 7

нет. если вы должны затем использовать определенную пользователем функцию, с которой вы можете передать параметры.

Ответ 9

Представление представляет собой не что иное, как предваряемый оператор SELECT. Итак, единственный реальный ответ: Нет, вы не можете.

Я думаю, что вы действительно хотите сделать, это создать хранимую процедуру, где в принципе вы можете использовать любой действующий SQL, чтобы делать все, что хотите, включая принимать параметры и выбирать данные.

Кажется вероятным, что вам действительно нужно только добавить предложение where, когда вы выберете из своего представления, но вы действительно не предоставили достаточно подробностей, чтобы быть уверенным.

Ответ 10

мы можем написать хранимую процедуру с входными параметрами, а затем использовать эту хранимую процедуру для получения набора результатов из представления. см. пример ниже.

хранимая процедура

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%')  

Ответ 11

Как я знаю, представление может быть чем-то вроде команды select. Вы также можете добавить параметры для этого выбора, например, в таких выражениях, как:

 WHERE  (exam_id = @var)

Ответ 12

Нет, представление статично. Одна вещь, которую вы можете сделать (в зависимости от версии SQl-сервера), - это индексировать представление.

В вашем примере (только для одной таблицы) индексированное представление не имеет никакого преимущества просто запросить таблицу с индексом на нем, но если вы делаете много соединений в таблицах с условиями соединения, индексированное представление может сильно улучшить производительность.

Ответ 13

Если вы не хотите использовать функцию, вы можете использовать что-то вроде этого

-- 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
        )

Надеюсь, что это поможет

Ответ 14

нет вы можете передать этот параметр процедуре в виде

Ответ 15

Вот вариант, который я пока не видел:

Просто добавьте столбец, который вы хотите ограничить представлению:

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)

Ответ 16

Вы можете обойти только для запуска представления, SQL будет вином и криком, но просто сделайте это и запустите его! Вы не можете сохранить.

create or replace view v_emp(eno number) as select * from emp where (emp_id = @Parameter1);

Ответ 17

Ваше представление может ссылаться на внешнюю таблицу, содержащую ваши параметры.

Как уже упоминалось, представление 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

Ответ 18

У меня есть идея, которую я еще не попробовал. Ты можешь сделать:

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)

Ваши параметры будут сохранены и изменены в таблице настроек.

Ответ 19

Я понял эту задачу для своих нужд следующим образом

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