我们可以将参数传递给SQL中的视图吗?
我们可以将参数传递给Microsoft SQL Server中的视图吗?我们可以将参数传递给SQL中的视图吗?
我试图create view
以下面的方式,但它不工作:
create or replace view v_emp(eno number) as select * from emp where emp_id=&eno;
没有。 如果您必须使用可以将参数传递到的用户定义函数。
不,你不能像Mladen Prajdic说的那样。将视图想象为一个表或一组表上的“静态过滤器”。例如:一个视图可以合并表Order
和Customer
,这样您可以从Order
中获得一个新的“表”行,以及包含客户名称和客户编号(表格组合)的新列。或者您可以创建一个仅从Order
表中选择未处理的订单的视图(静态过滤器)。
然后,您可以从视图中选择,就像您从任何其他“普通”表中选择的那样 - 所有“非静态”过滤都必须在视图外完成(例如“获取所有客户的订单” “获取12月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]
)
没有 可以将参数传递给在视图的程序
如前所述你不能。
一个可能的解决方案是实现存储功能,如:
CREATE FUNCTION v_emp (@pintEno INT)
RETURNS TABLE
AS
RETURN
SELECT * FROM emp WHERE [email protected];
这使您可以使用它作为一个普通视图,用:
SELECT * FROM v_emp(10)
视图是无非一个预先设定的'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
因为我知道视图可以像选择命令一样。
WHERE (exam_id = @var)
这应该是可以接受的答案。简单,简单,直至重点。非常感谢:) – FrenkyB 2017-06-03 13:44:50
为什么你需要考虑的参数: 还可以,语句像这样的参数添加到这个选择,例如?您可能只需使用WHERE
子句。
create view v_emp as select * from emp ;
和您的查询应该做的工作:
select * from v_emp where emp_id=&eno;
在某些情况下,当它是表的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
视图是一个选择查询的存储的SQL文。讨论中没有参数。当存储的查询返回要过滤的列时,可以在调用查询中进行。例如。 “SELECT * FROM v_emp WHERE emp_id =?” – Epicurist 2017-03-28 09:52:20