您忘记告诉我们您使用的是什么版本的 SQL Server。当然,对于每个新版本,我们都会获得帮助我们以更有效的方式解决问题的能力。
在 SQL Server 2005+ 中,您可以使用这样的简单表值函数来实现连接:
CREATE FUNCTION [dbo].[SplitInts]
(
@List VARCHAR(MAX),
@Delimiter CHAR(1)
)
RETURNS TABLE
AS
RETURN ( SELECT Item FROM ( SELECT Item = x.i.value('(./text())[1]', 'int') FROM
( SELECT [XML] = CONVERT(XML, '<i>' + REPLACE(@List, @Delimiter, '</i><i>')
+ '</i>').query('.') ) AS a CROSS APPLY [XML].nodes('i') AS x(i)
) AS y WHERE Item IS NOT NULL
);
GO
现在传入你的大名单并加入:
CREATE PROCEDURE dbo.GetData
@List VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
SELECT t.col1, t.col2 --, ...
FROM dbo.DataTable AS t
INNER JOIN dbo.SplitInts(@List, ',') AS i
ON t.ColumnID = i.Item;
END
GO
这不是很好(我在这里写了关于各种方法的性能的博客,在 5000 值以下几乎没有区别),但可能比临时IN (...huge list...)
查询表现得更好。
在 SQL Server 2008+ 中,您可以使用表值参数。与上面类似,您可以将 DataTable 或 C# 中的任何结构传递到存储过程并执行连接。如果您使用的是 2008 或更高版本,我也可以为此添加一个示例。