我们可以将参数传递给SQL中的视图吗?

问题描述:

我们可以将参数传递给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

没有。 如果您必须使用可以将参数传递到的用户定义函数。

不,你不能像Mladen Prajdic说的那样。将视图想象为一个表或一组表上的“静态过滤器”。例如:一个视图可以合并表OrderCustomer,这样您可以从Order中获得一个新的“表”行,以及包含客户名称和客户编号(表格组合)的新列。或者您可以创建一个仅从Order表中选择未处理的订单的视图(静态过滤器)。

然后,您可以从视图中选择,就像您从任何其他“普通”表中选择的那样 - 所有“非静态”过滤都必须在视图外完成(例如“获取所有客户的订单” “获取12月24日发布的未经处理的订单”)。

不,对查询的查询没有区别于从表中进行选择。

做你想做什么,可以使用一个table-valued user-defined function有一个或多个参数

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

没有 可以将参数传递给在视图的程序

如前所述你不能。

一个可能的解决方案是实现存储功能,如:

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

视图是无非一个预先设定的'SELECT'语句。所以唯一真正的答案是:不,你不能。

我觉得你真的想要做的是创建一个存储过程,原则上,你可以使用任何有效的SQL做任何你想要的,包括接受参数和选择数据。

这很可能是你真的只需要添加一个where子句当您从您的视图,虽然选择,但你并没有真正提供足够的细节以确保万无一失。

没有,视图是静态的。你可以做的一件事(取决于SQl服务器的版本)是索引视图。

在你的例子中(查询只有一个表),索引视图没有任何好处,只是查询带有索引的表,但如果你在有连接条件的表上进行大量连接,索引视图可以大大提高性能。

我们可以编写带有输入参数的存储过程,然后使用该存储过程来从视图的结果集。 请参阅下面的示例。

存储过程是

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

哈克的方式做到这一点,而不存储过程或函数是创建一个在你的数据库中设置表,包括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

因为我知道视图可以像选择命令一样。

WHERE (exam_id = @var) 
+0

这应该是可以接受的答案。简单,简单,直至重点。非常感谢:) – FrenkyB 2017-06-03 13:44:50

为什么你需要考虑的参数: 还可以,语句像这样的参数添加到这个选择,例如?您可能只需使用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

如果你不想使用的功能,你可以使用类似这样

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

希望这将有助于

你可以绕过刚刚运行来看,SQL将酒和哭的,但只是这样做并运行它!你无法保存。

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

这是我至今为止还没有看到一个选项:

只需添加你要限制到视图中的列:

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