14

次のようなコンマで区切られたIDのリストがあります。

 1,17,25,44,46,67,88

それらをテーブルレコードに(一時テーブルに)変換したい

#tempTable

number_
--------
1
17
25
44
46
67
88

関数、テーブル値の関数で可能ですか?

なぜ私はこれが欲しいのですか?INNER JOIN次のような別のテーブルで for 句を(ストアドプロシージャに)使用したい:

SELECT a,b,c FROM T1
INNER JOIN functionNameWhichReturnsTable 
ON functionNameWhichReturnsTable.number_ = T1.a

INNVARCHAR 型のパラメータを受け取るストアド プロシージャを使用するため、使用できません。そのパラメーターは、ID のリストを提供します。

ありがとうございました

4

7 に答える 7

25

別々のカンマ区切りの値が重複している可能性があり、SQL Server のテーブルに格納されています。

Comma-Delimited Value から 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

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)
于 2013-03-23T10:26:56.190 に答える
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);

このメソッドは、最大 1000 個の値に使用できます。
行値式の上限は 1000 であるためです。

また、スチュアート・エインズワースが指摘したように。
このメソッドは Dynamic 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;
于 2016-03-24T10:59:22.673 に答える