如何在 "Where" 子句中使用 CSV 字符串作为条件参数制作 SQL Select 语句?



下面是我正在尝试做的事情的一个例子。

Declare @PersonIds varchar(500)
Set @PersonIds = '1, 3, 5'
Select PersonId, FirstName, LastName
From   tblPerson
Where  PersonId in @PersonIds

谢谢。

您可以使用

like

WHERE ', ' + @PersonIds + ', ' like '%, ' + cast(PersonId as varchar(255)) + ', %'

这不会有很好的性能,因为您不能使用索引。

如果要利用索引,则需要使用动态 SQL 并构造 IN 语句或拆分字符串。

您可以在 Web 上找到一个splitstring()函数并执行以下操作:

Select p.PersonId, p.FirstName, p.LastName
From   tblPerson p cross apply
       SplitString(@PersonIds, ', ') as s(val)
Where s.val = i.PersonId;

您可以声明一个table-valued function,用于分解以逗号分隔的整数值列表并将其转换为表:

CREATE FUNCTION tvf_StringToIntTable 
(
    -- Add the parameters for the function here
    @string VARCHAR(MAX), 
    @delimiter CHAR(1) -- could be ',', ';', etc
)
RETURNS 
@output TABLE 
(
    data int
)
AS
BEGIN
    -- Fill the table variable with the rows for your result set
    DECLARE @start INT, @end INT
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string)
    WHILE @start < LEN(@string) + 1 
    BEGIN
        IF @end = 0 
            SET @end = LEN(@string) + 1
        INSERT INTO @output (data) 
        VALUES(CONVERT(int, SUBSTRING(@string, @start, @end - @start)))
        SET @start = @end + 1
        SET @end = CHARINDEX(@delimiter, @string, @start)
    END 
    RETURN 
END
GO

然后在您的 select 语句中使用此函数,如下所示:

Select PersonId, FirstName, LastName
From   tblPerson
Where  PersonId in (select data from tvf_StringToIntTable(@PersonIds, ','))

编辑:

如果值串非常大,则应使用更有效的拆分函数,比如这个。

如果您在选择

的表中只有少量记录,那么执行其他答案中提到的其他方法之一应该是可以的。但是,要针对更大的行量进行扩展,您应该分两步执行此操作:

  1. 将 CSV 拆分为临时表(如果 CSV 列表相当小,则表变量应该有效)
  2. 在本地临时表上执行内部联接以将其用作筛选器。

例如:

Declare @PersonIds varchar(500);
Set @PersonIds = '1, 3, 5';
CREATE TABLE #PersonsToSelect (PersonID INT NOT NULL PRIMARY KEY);
INSERT INTO #PersonsToSelect (PersonID)
   SELECT vals.SplitVal
   FROM   dbo.XmlOrClrSplitter(@PersonIDs, ',');
Select PersonId, FirstName, LastName
From   tblPerson per
INNER JOIN  #PersonsToSelect tmp
        ON  tmp.PersonID = per.PersonId;

最新更新