我们能在SQL中向视图传递参数吗?

172

我们能否在Microsoft SQL Server中向视图传递参数?

我尝试以以下方式创建视图,但它不起作用:

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

一个 view 是一个存储了 select 查询的 SQL 文本。参数不在讨论范围内。当你的存储查询返回你想要过滤的列时,你可以在调用查询中进行操作。例如:"SELECT * FROM v_emp WHERE emp_id = ?" - Epicurist
2
@ Epicurist“参数不在讨论范围内”这是一个过于大胆的陈述。反例 - Lukasz Szozda
使用存储过程怎么样? - farid wahyu
22个回答

5

一个视图只是一个预定义的“SELECT”语句。所以唯一真正的答案就是:不能。

我认为你真正想做的是创建一个存储过程,在原则上,您可以使用任何有效的SQL来执行您想要的任何操作,包括接受参数和选择数据。

但是看起来您只需要在从视图中选择时添加一个where子句,但您没有提供足够的细节来确定。


4

如果您不想使用一个函数,可以使用类似以下的方法

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

希望这可以帮助到您


4
不,视图是静态的。你可以做的一件事(取决于SQL Server的版本)就是为视图建立索引。
在你的例子中(仅查询一个表),对于已经有索引的表来说,索引视图没有什么好处,但是如果你在连接带有连接条件的表时进行了大量的连接操作,那么索引视图可以极大地提高性能。

4

我有一个还未尝试的想法。你可以这样做:

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)

您的参数将被保存并在配置表中进行更改。


2
如果你对一个回答的真实性有疑问,在确认它至少是一个“足够”的解决方案之前,请不要发布它。就目前而言,这更像是一个问题而不是一个答案。 - chb
1
这个解决方案的一个问题是,如果查询在多个会话中运行,则可能使用配置表中的错误数据。 - User1010
视图没有显式的参数传递机制。但是你可以隐式地传递参数。使用一个特殊的表来实现这一点是一个很好的解决方案,它适用于任何数据库管理系统,而不仅仅是MS SQL。 - undefined

2

不,你可以将参数传递给视图中的过程。


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

1
它应该是相似的(PL/SQL和T-SQL在许多方面都很相似),但有不止一种方法可以找出来 :) 试试看吧。 - Oleg Melnikov

1
虽然问题已经得到很好的回答,但我想要补充一点。大多数情况下,我们认为视图是发送数据的查询,但视图不仅如此... 视图还可以用于更新底层表中的数据。您可以在SSMS中右键单击视图,然后找到“编辑前200行”的选项。
我认为为了启用此编辑数据的功能,对于视图的查询有一定的限制,它需要是静态查询。
因此,与用户定义函数或存储过程不同(它们发送查询的数据并关闭),视图可以维护实时连接(例如,在Microsoft Access链接的表/视图中)并将更新写回数据库。
因此,在您只想获得具有特定动态条件的数据集的情况下,应使用具有所需参数的UDF / SP。

1

只需使用此视图调用存储过程并传入必要的参数(例如,在SQL Server中),并在查询视图中传递参数值。

创建具有视图/表的存储过程:_spCallViewWithParameters

enter image description here

执行过程:

enter image description here


0

您可以绕过保存,仅运行视图。 SQL会哭泣,但只需这样做并运行即可!

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接