如何将逗号分隔的NVARCHAR转换为SQL Server 2005中的表记录?

Sna*_*yes 12 sql sql-server-2005

我有一个由逗号分隔的ID列表,如:

 1,17,25,44,46,67,88
Run Code Online (Sandbox Code Playgroud)

我想将它们转换为表记录(进入临时表)之类的

#tempTable

number_
--------
1
17
25
44
46
67
88
Run Code Online (Sandbox Code Playgroud)

有一个函数,一个表值的函数可以吗?

我为什么要这个?我想使用for INNER JOIN子句(到存储过程)与另一个表,如:

SELECT a,b,c FROM T1
INNER JOIN functionNameWhichReturnsTable 
ON functionNameWhichReturnsTable.number_ = T1.a
Run Code Online (Sandbox Code Playgroud)

我无法使用,IN因为我将使用接受NVARCHAR类型参数的存储过程.该参数将提供ID列表.

谢谢

Tec*_*hDo 23

可能重复单独的逗号分隔值并存储在sql server中的表中.

请尝试使用Comma-Delimited Value to Table中的精确:

CREATE FUNCTION [dbo].[ufn_CSVToTable] ( @StringInput VARCHAR(8000), @Delimiter nvarchar(1))
RETURNS @OutputTable TABLE ( [String] VARCHAR(10) )
AS
BEGIN

    DECLARE @String    VARCHAR(10)

    WHILE LEN(@StringInput) > 0
    BEGIN
        SET @String      = LEFT(@StringInput, 
                                ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput) - 1, -1),
                                LEN(@StringInput)))
        SET @StringInput = SUBSTRING(@StringInput,
                                     ISNULL(NULLIF(CHARINDEX(@Delimiter, @StringInput), 0),
                                     LEN(@StringInput)) + 1, LEN(@StringInput))

        INSERT INTO @OutputTable ( [String] )
        VALUES ( @String )
    END

    RETURN
END
GO
Run Code Online (Sandbox Code Playgroud)

使用XML以其他方式检查需求:

DECLARE @param NVARCHAR(MAX)
SET @param = '1:0,2:1,3:1,4:0'

SELECT 
     Split.a.value('.', 'VARCHAR(100)') AS CVS  
FROM  
(
    SELECT CAST ('<M>' + REPLACE(@param, ',', '</M><M>') + '</M>' AS XML) AS CVS 
) AS A CROSS APPLY CVS.nodes ('/M') AS Split(a)
Run Code Online (Sandbox Code Playgroud)


Luk*_*rms 6

这是一个不需要函数或 XML 的技巧。

基本上,字符串被转换为临时表的单个插入语句。

然后可以使用临时表进行进一步处理。

IF OBJECT_ID('tempdb..#tmpNum') IS NOT NULL
      DROP TABLE #tmpNum;

CREATE TABLE #tmpNum (num int);

DECLARE @TEXT varchar(max) = '1,17,25,44,46,67,88';

DECLARE @InsertStatement varchar(max);
SET  @InsertStatement = 'insert into #tmpNum (num) values ('+REPLACE(@TEXT,',','),(')+');';
EXEC (@InsertStatement);

-- use the temp table 
SELECT * 
FROM YourTable t
WHERE t.id IN (SELECT DISTINCT num FROM #tmpNum);
Run Code Online (Sandbox Code Playgroud)

此方法最多可用于 1000 个值。
因为 1000 是行值表达式的最大限制。

此外,正如斯图尔特·安斯沃思所指出的那样。
由于此方法使用动态Sql,因此请注意代码注入,不要将其用于基于用户输入的字符串。

边注

从 MS Sql Server 2016 开始,可以简单地使用STRING_SPLIT函数。

DECLARE @TEXT varchar(max);
SET @TEXT = '1,17,25,44,46,67,88';

SELECT t.* 
FROM YourTable t
JOIN (SELECT DISTINCT CAST(value AS INT) num FROM STRING_SPLIT(@TEXT, ',')) nums
  ON t.id = nums.num;
Run Code Online (Sandbox Code Playgroud)