如何在 SQL Server 的 IN 子句中使用存储过程输出

Posted

技术标签:

【中文标题】如何在 SQL Server 的 IN 子句中使用存储过程输出【英文标题】:How to use stored procedures output in IN clause in SQL Server 【发布时间】:2012-05-14 12:19:48 【问题描述】:

我的应用程序中有一个视图,它与另一个视图和一个表有一个 INNER JOIN。

view ViewName
select * from AnotherView inner join TableName ON conditions

使用 INNER JOIN 语句专门执行此视图需要太多时间。所以我正在尝试使用 SP 来提高性能。我正在尝试删除物理表上的 INNER JOIN。

我的 SP 将获取更多子句所需的数据。

所以代码将如下所示,

view ViewName
select * from AnotherView where columnName in (result of SP)

我尝试了表变量,在视图中调用视图。但是每次执行的时间似乎都是一样的,只是有些细微的差别。

谁能帮我理解这一点?有可能吗?有没有其他更好的方法来实现这一点。我不想使用 openrowset。

提前致谢, 维杰

【问题讨论】:

听起来你想要一个表值函数,而不是存储过程——如果你想利用结果集的话。 是什么让您认为存储过程会提高性能? - 如果查询目前表现不佳,您应该检查索引 - 不要引入优化器可以less处理的新的、不透明的代码。 您确定问题的原因了吗?连接可能会使查询变慢,但它应该是真正的问题吗?例如,您的AnotherView 是什么样的? AnotherView 只是一个从其他一些视图和物理表中填充数据的视图。我随机选择了SP。如果我删除内部连接,查询的第一部分将在 2 秒内执行。使用内部连接,几乎 40K 记录需要 30 秒。 【参考方案1】:

将以下查询放在您的视图中,它将使用 sp 的结果创建一个内连接。

您可以在 View 中使用 OpenRowSet 访问 sp。

SELECT * 
FROM   AnotherView 
       INNER JOIN (SELECT a.* 
                   FROM   OPENROWSET('SQLNCLI', 
                                     'Server=(local);TRUSTED_CONNECTION=YES;', 
                                     'EXEC database.dbo.Spname') AS a) AS b 
         ON AnotherView.columnName = b.columnname 

如果凭据不受开发人员的控制,那么您可以创建一个链接服务器并在 openrowset 中传递服务器的名称。无需传递凭据。

如何创建链接服务器到数据库:

 EXEC master.dbo.sp_addlinkedserver
@server = N'LinkServerName',
@srvproduct=N'MSSQL',
@provider=N'SQLNCLI',
@provstr=N'PROVIDER=SQLOLEDB;SERVER=.\SQLEXPRESS;Database=DbName'

EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'LinkServerName',
@useself=N'True',
@locallogin=NULL

如何在视图中执行sp:

SELECT * From OPENQUERY([LinkServerName],DbName.dbo.spname)

【讨论】:

我无法使用 OPENROWSET。它是一个通用数据库,可根据客户进行更改。此设置不受开发者控制。【参考方案2】:

将结果放入临时表并与之进行内部连接。

将结果放入一个变量(或输出变量)中,使用Dynamic SQL来使用。


要提高性能,请对条件中使用的列使用索引。

【讨论】:

我对数据库知之甚少。你能指导我吗? 您只需要关注其中之一:google.com/…

以上是关于如何在 SQL Server 的 IN 子句中使用存储过程输出的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 使用 in 子句从表中选择字符串

SQL Server:NOT IN in where 子句不能与 NVARCHAR 一起使用

Not in 子句不使用开放查询过滤 SQL Server

Sql server not in 子句不起作用

PL/SQL - 如何在 IN 子句中使用数组

SQL Server - 带有声明变量的In子句[重复]