在SQL Server 2008中创建参数化的VIEW


72

我们可以在SQL Server 2008中创建参数化的VIEW吗?

或对此有其他选择吗?

Answers:


124

尝试创建一个内联表值函数。例:

CREATE FUNCTION dbo.fxnExample (@Parameter1 INTEGER)
RETURNS TABLE
AS
RETURN
(
    SELECT Field1, Field2
    FROM SomeTable
    WHERE Field3 = @Parameter1
)

-- Then call like this, just as if it's a table/view just with a parameter
SELECT * FROM dbo.fxnExample(1)

如果您查看SELECT的执行计划,您将根本看不到该功能,而只会向您显示要查询的基础表。这很好,因为这意味着在生成查询的执行计划时将使用基础表的统计信息。

避免使用多语句表值函数,因为将不使用基础表统计信息,并且由于执行计划不当而导致性能不佳。
避免的示例:

CREATE FUNCTION dbo.fxnExample (@Parameter1 INTEGER)
    RETURNS @Results TABLE(Field1 VARCHAR(10), Field2 VARCHAR(10))
AS
BEGIN
    INSERT @Results
    SELECT Field1, Field2
    FROM SomeTable
    WHERE Field3 = @Parameter1

    RETURN
END

稍有不同,但在查询中使用该函数时,性能可能存在很大差异。


这对我来说是一个有用的答案。感谢AdaTheDev!
TWood 2012年

2
如果需要在链接服务器之间进行调用,则会出现问题,不允许使用表值函数。
Timofey 2012年

7
避免的例子非常非常重要。我只是做了一个更改以使我的功能与第一个示例相匹配(将其从“应避免的事物”上移开了),并且我获得了巨大的性能提升。
Jeff Widmer

1
“良好”示例中的UNION是否会将其移至“避免”类别?
G. Stoynev


7

实际上,存在一个技巧:

create view view_test as

select
  * 
from 
  table 
where id = (select convert(int, convert(binary(4), context_info)) from master.dbo.sysprocesses
where
spid = @@spid)

...在sql-query中:

set context_info 2
select * from view_test

将与相同

select * from table where id = 2

但使用udf更可取


17
我会认真哭泣哭了很多,水桶满了。不眠之夜...
Adriaan Stander 2010年

17
没什么不尊重的,但这是一个很好的例子,说明了您可以做什么与应该(不应该)做什么之间的区别。
gjvdkamp 2010年

7
我不坚持那个解决方案。我自己从未在mssql中使用过它。我刚刚提到从理论上讲这是可能的
十六进制(2010年

为有趣的骇客而投票。并不是说应该使用它。
克里斯·库德莫

2

正如旁观者所提到的,您可以使用UDF做到这一点。但是,对于使用标量函数的大型集合(与内联表函数相对应),由于逐行评估该函数,因此性能会很差。或者,您可以通过存储过程执行相同的结果,该存储过程使用占位符替换参数值来执行固定查询。

这是有关标量UDF的逐行处理的过时但仍然有意义的文章。)

编辑:评论重新。调整了可降低的性能,以使其清楚地适用于标量UDF。


3
如果将UDF作为内联表值函数编写,则完全没有理由导致性能下降。如果您在谈论标量函数,则可以,该函数将针对每一行进行评估
AdaTheDev 2010年

很抱歉造成您的疏忽-您说的很对。我将编辑我的答案以使其清楚。
davek 2010年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.