2009-11-06 152 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 2017-03-28 09:52:20

回答

5

沒有。 如果您必須使用可以將參數傳遞到的用戶定義函數。

11

不,你不能像Mladen Prajdic說的那樣。將視圖想象爲一個表或一組表上的「靜態過濾器」。例如:一個視圖可以合併表OrderCustomer,這樣您可以從Order中獲得一個新的「表」行,以及包含客戶名稱和客戶編號(表格組合)的新列。或者您可以創建一個僅從Order表中選擇未處理的訂單的視圖(靜態過濾器)。

然後,您可以從視圖中選擇,就像您從任何其他「普通」表中選擇的那樣 - 所有「非靜態」過濾都必須在視圖外完成(例如「獲取所有客戶的訂單」 「獲取12月24日發佈的未經處理的訂單」)。

24

有2種方式來acheive你想要什麼不幸的是既可以使用視圖來完成。

您可以創建一個表值用戶定義的函數,它需要的參數和返回查詢結果

或者你也可以做幾乎同樣的事情,而是創建一個存儲過程,而不是一個用戶定義的函數。

對於實施例

存儲過程將類似於

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 2012-10-22 17:44:44

+0

在MySQL中,您編寫了一個存儲過程,並讓過程中的最後一個語句成爲您要返回的結果集。 – bobobobo 2013-06-06 19:23:17

+0

我們可以使用該請求沒有任何問題從Java中的JDBC代碼? – mounaim 2014-12-17 13:23:45

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

哈克的方式做到這一點,而不存儲過程或函數是創建一個在你的數據庫中設置表,包括Id,Param1,Param2等。在表中插入一行,其中包含Id = 1,Param1 = 0,Param2 = 0等值。然後,你可以在你的表中添加一個連接到你的表中視圖來創建所需的效果,並在運行vie之前更新設置表W上。如果您有多個用戶更新設置表並同時運行視圖,則可能會出錯,但否則應該可以正常工作。類似於:

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 2012-10-20 12:14:02

+0

將它用於請求查看會很糟糕。但作爲配置/舞臺/環境,使用這種隱藏參數是非常有用的。 A Plus對於我來說。 – TPAKTOPA 2016-04-19 13:26:50

3

因爲我知道視圖可以像選擇命令一樣。

WHERE (exam_id = @var) 
+0

這應該是可以接受的答案。簡單,簡單,直至重點。非常感謝:) – FrenkyB 2017-06-03 13:44:50

5

爲什麼你需要考慮的參數: 還可以,語句像這樣的參數添加到這個選擇,例如?您可能只需使用WHERE子句。

create view v_emp as select * from emp ; 

和您的查詢應該做的工作:

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

在某些情況下,當它是表的WHERE,而不是視圖的WHERE時,會有很大的性能提升。 – 2014-12-19 17:50:56

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 
相關問題