2010年5月21日金曜日

SQL-Serverにおいて、CSV(カンマ区切り)テキストをテーブル形式に変換するSplit関数を作ってみました

今回の記事では、SQL-Serverにおいて、CSV(カンマ区切り)形式のテキストをテーブル形式に変換する関数を作ってみました。

いわゆるSplit関数のSQL-Server版です。

友達から「Split関数を、SQLCLRじゃなくて、純粋なSQL関数で作って欲しい」というリクエストがあったので、お応えいたします。

というわけで、今回はSQLCLRではなくて、純粋なSQL関数・・・つまりTransact SQLなので、SQL-Server 2008 (Express)ばかりでなくて、SQL-Server 2000でも応用できると思います。

文字列だけでなく、連番も付けています。入力順の管理などに便利かと思います。

ただ、SQL-Server 2000ではnvarchar(max)が使えないので、varchar(8000)とかvarchar(255)とかを代わりに使うとよろしいかと思います。

ただ、実行速度はやはりC#言語で怒涛のように動くSQLCLRと比べてしまうと遅いはず。

■実行例■

SELECT * FROM dbo.Split('Aspire1410,新型,気になる,Core i5かなぁ,新セレロンSUシリーズかなぁ');

SELECT * FROM dbo.Split('カンマ区切りが無い場合はそのまま');

SELECT * FROM dbo.Split('カンマだけの場合,,,');


■コード■

(インデントが消えています。)
(Transact SQLなのでこのまま即登録して使えます。)

-- -----------------------------------------------
-- Split関数
-- -----------------------------------------------
CREATE FUNCTION Split(@P_STREAM nvarchar(max))
RETURNS @TBL_RESULT TABLE(
CSV_SEQ int,
CSV_ELEMENT nvarchar(max)
)
BEGIN

-- -----------------------------
-- 変数定義エリア
-- -----------------------------
DECLARE
@end_flg tinyint, --終了フラグ
@sel_value nvarchar(max), --作業中文字列
@i int, --インデックス
@j int --インデックス
;

-- -----------------------------
-- 処理
-- -----------------------------
SET @end_flg = 0;
SET @i = 0;
SET @j = 0;
SET @sel_value = @P_STREAM;
-- @@@@@@@@@@[LOOP-START]@@@@@@@@@@
WHILE @end_flg = 0
BEGIN
SET @sel_value = SUBSTRING(@sel_value,@i+1,LEN(@sel_value)-@i);
SET @i = CHARINDEX(',',@sel_value);
IF @i = 0
BEGIN
SET @end_flg = 1;
END
ELSE BEGIN
INSERT INTO @TBL_RESULT
(CSV_SEQ,CSV_ELEMENT)
SELECT
@j AS CSV_SEQ,
SUBSTRING(@sel_value,1,@i-1) AS CSV_ELEMENT;
SET @j = @j + 1;
END;
END
-- @@@@@@@@@@[LOOP-END ]@@@@@@@@@@

INSERT INTO @TBL_RESULT
(CSV_SEQ,CSV_ELEMENT)
SELECT
@j AS CSV_SEQ,
@sel_value AS CSV_ELEMENT;

RETURN;

END


それにつけても、本当にAspire 1410は良いなぁ。
布団に入りながら、超省スペースでSQL-Server 2008をじっくり勉強できる・・・。