SQL Server で文字列を分割する方法は多数あります。この記事では、ほぼすべての方法の長所と短所について説明します。
Erland Sommarskog による「SQL Server 2005 以降の配列とリスト、テーブル値パラメーターがそれをカットしない場合」
分割関数を作成する必要があります。これは、分割機能を使用する方法です。
SELECT
*
FROM YourTable y
INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value
私は、TSQL で文字列を分割する数値テーブル アプローチを好みますが、SQL Server で文字列を分割する方法は多数あります。それぞれの長所と短所を説明している前のリンクを参照してください。
Numbers
Numbers Table メソッドを機能させるには、1 から 10,000 までの行を含むテーブルを作成する、この 1 回限りのテーブル設定を行う必要があります。
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
Numbers テーブルを設定したら、次の分割関数を作成します。
CREATE FUNCTION [dbo].[FN_ListToTable]
(
@SplitOn char(1) --REQUIRED, the character to split the @List string on
,@List varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN
(
----------------
--SINGLE QUERY-- --this will not return empty rows
----------------
SELECT
ListValue
FROM (SELECT
LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
FROM (
SELECT @SplitOn + @List + @SplitOn AS List2
) AS dt
INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
WHERE SUBSTRING(List2, number, 1) = @SplitOn
) dt2
WHERE ListValue IS NOT NULL AND ListValue!=''
);
GO
CSV 文字列を簡単にテーブルに分割して結合したり、動的 SQL 内からでも必要に応じて使用したりできるようになりました。質問の動的パラメーター化クエリで使用する方法は次のとおりです。
DECLARE @Cmd as nvarchar(1000),@ParamDefinition nvarchar(1000);
Set @Cmd = N'SELECT * FROM table WHERE RegionCode in (SELECT ListValue FROM dbo.FN_ListToTable('','',@P1))'
SET @ParamDefinition = N'@P1 varchar(100)';
DECLARE @Code as nvarchar(1000);
SET @Code = 'X101,B202'
EXECUTE sp_executesql @Cmd, @ParamDefinition, @P1 = @Code
試してみる作業サンプルを次に示します (最初に数値テーブルと分割関数をセットアップする必要があります)。
CREATE TABLE YourTable (PK int primary key, RowValue varchar(5))
INSERT YourTable VALUES (1,'A')
INSERT YourTable VALUES (2,'BB')
INSERT YourTable VALUES (3,'CCC')
INSERT YourTable VALUES (4,'DDDD')
INSERT YourTable VALUES (5,'EEE')
INSERT YourTable VALUES (6,'FF')
INSERT YourTable VALUES (7,'G')
DECLARE @SQL nvarchar(1000)
,@ParamDefinition nvarchar(1000)
,@ParamValue varchar(100)
SELECT @SQL = N'SELECT * FROM YourTable WHERE PK IN (SELECT ListValue FROM dbo.FN_ListToTable('','',@P1))'
,@ParamDefinition = N'@P1 varchar(100)'
,@ParamValue = '2,4,,,6,,8,,2,,4'
EXECUTE sp_executesql @SQL, @ParamDefinition, @P1 = @ParamValue
出力:
PK RowValue
----------- --------
2 BB
4 DDDD
6 FF
(3 row(s) affected)