2009-11-06 2 views
76

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

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

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

Вид хранимая SQL текст запроса на выборку. Параметры не обсуждаются. Когда ваш сохраненный запрос возвращает столбец, в который вы хотите отфильтровать, вы можете сделать это в вызывающем запросе. Например. "SELECT * FROM v_emp WHERE emp_id =?" – Epicurist

ответ

5

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

11

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

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

4

Нет, запрос не запрашивается иначе, чем SELECTing из таблицы.

Чтобы сделать то, что вы хотите, используйте table-valued user-defined function с одним или несколькими параметрами

24

Есть 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] 
) 
4

нет вы можете передать параметр в процедуре в целях

94

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

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

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

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

SELECT * FROM v_emp(10) 
+0

Каковы практические различия между этим и представлением? Можете ли вы назначить права доступа только для доступа к этой функции? – MikeMurko

+0

В MySQL вы пишете хранимую процедуру и получите последнюю инструкцию в процедуре, которую вы хотите вернуть. – bobobobo

+0

можно ли использовать этот запрос без каких-либо проблем с кодом JDBC в java? – mounaim

4

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

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

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

4

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

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

4

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

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

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

Hacky способ сделать это без хранимых процедур или функций было бы создать таблицу параметров в вашей базе данных с столбцами Id, Param1, Param2 и т. д. Вставьте строку в эту таблицу, содержащую значения Id = 1, Param1 = 0, Param2 = 0 и т. д. Затем вы можете добавить соединение к этой таблице в своей таблице просмотреть, чтобы создать желаемый эффект, и обновить таблицу настроек перед запуском vie ш. Если у вас есть несколько пользователей, обновляющих таблицу параметров и одновременное выполнение представления, это может пойти не так, но в противном случае оно должно работать нормально. Что-то вроде:

CREATE VIEW v_emp 
AS 
SELECT  * 
FROM  emp E 
INNER JOIN settings S 
ON   S.Id = 1 AND E.emp_id = S.Param1 
+7

Да, вы правы. Это ужасное решение. – Ben

+0

было бы ужасно использовать его для запроса на просмотр. Но в качестве конфигурации/стадии/среды действительно полезно использовать такие скрытые параметры. Для меня это плюс. – TPAKTOPA

3

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

WHERE (exam_id = @var) 
+0

Это должен быть принятый ответ. Просто, легко и точно. Большое спасибо :) – FrenkyB

5

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

create view v_emp as select * from emp ; 

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

select * from v_emp where emp_id=&eno; 
+3

В некоторых случаях будет большое улучшение производительности, когда это 'WHERE' для таблицы, а не' WHERE' для представления. –

3

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

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

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

1

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

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

Вот вариант я не видел до сих пор:

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

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

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

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