SQL で括弧内の文字列を取り出す
SQL で括弧内の文字列を取り出す
プロダクト番号やファイル名などの文字列で、括弧があって、その中の文字列を取り出したい時ないでしょうか。
例えば、文字列が 「 プロダクト識別番号[バージョン番号] 」 から "バージョン番号" のみを取り出したい時や、「 レポート名(日付).csv 」 から "日付" を取り出したいような状況です。
いろいろなやり方があると思いますが、毎回考えるのも手間なので、ひとつの方法をここに書きとめておきます。
括弧内の文字列を取り出す
@InputString から、@StartBracket と @EndBracket の括弧に囲まれた文字列を取り出すユーザー定義ファンクションを生成するスクリプトは以下通りです。
※ 「 括弧開き 」 と 「 括弧閉じ 」 がひとつずつ入っているような値に使用する前提で作っています。
CREATE FUNCTION ufnGetStringInBrackets ( @InputString NVARCHAR(MAX), @StartBracket CHAR(1), -- '(' @EndBracket CHAR(1) -- ')' ) RETURNS NVARCHAR(MAX) AS BEGIN DECLARE @StringInBrackets NVARCHAR(MAX); IF CHARINDEX(@StartBracket, @InputString) > 0 AND CHARINDEX(@EndBracket, @InputString) > 0 AND CHARINDEX(@EndBracket, @InputString) > CHARINDEX(@StartBracket, @InputString) BEGIN SET @StringInBrackets = SUBSTRING(@InputString, CHARINDEX(@StartBracket ,@InputString) + 1, CHARINDEX(@EndBracket, @InputString) - CHARINDEX(@StartBracket, @InputString) - 1); END RETURN @StringInBrackets; END
@InputString 内に @StartBracket と @EndBracket の両方が存在していない時は NULL を返します。
@InputString 内に @StartBracket と @EndBracket が複数存在する場合は、ひとつめの @StartBracket の後から、ひとつめの @EndBracket の前までの文字列を返します。
ひとつめの @EndBracket の位置が ひとつめの @StartBracketの位置より前にある時も NULL を返します。
ufnGetStringInBrackets を使って、括弧()内の文字列を取り出してみます。
DECLARE @ReportTable TABLE ( ReportFileName VARCHAR(100) ); INSERT INTO @ReportTable (ReportFileName) VALUES ('AAA Report (20181001).csv'), ('BBB Report (20181002).csv'), ('CCC (Report) (20181003).csv'), ('DDD (Report (20181004)).csv'), ('EEE Report (20181005.csv'), (')FFF Report (20181006.csv'); DECLARE @StartBracket CHAR(1) = '(', @EndBracket CHAR(1) = ')'; SELECT ReportFileName, dbo.ufnGetStringInBrackets(ReportFileName, @StartBracket, @EndBracket) FROM @ReportTable;
[ 実行結果 ]
動きを確認するためにイレギュラーな値も試していますが、ひとつめの 「 ( 」 の後から、ひとつめの 「 ) 」 の前までの文字列されています。
もしくは、ユーザー定義関数を使わずに、StringInBrackets 用のカラムを作って、以下のように UPDATE ステートメントで取得しても同じ結果が得られます。
DECLARE @ReportTable TABLE ( ReportFileName VARCHAR(100), StringInBrackets VARCHAR(100) ); INSERT INTO @ReportTable (ReportFileName) VALUES ('AAA Report (20181001).csv'), ('BBB Report (20181002).csv'), ('CCC (Report) (20181003).csv'), ('DDD (Report (20181004)).csv'), ('EEE Report (20181005.csv'), (')FFF Report (20181006.csv'); DECLARE @StartBracket CHAR(1) = '(', @EndBracket CHAR(1) = ')'; UPDATE T SET StringInBrackets = SUBSTRING(ReportFileName, CHARINDEX(@StartBracket ,ReportFileName) + 1, CHARINDEX(@EndBracket, ReportFileName) - CHARINDEX(@StartBracket, ReportFileName) - 1) FROM @ReportTable AS T WHERE CHARINDEX(@StartBracket, ReportFileName) > 0 AND CHARINDEX(@EndBracket, ReportFileName) > 0 AND CHARINDEX(@EndBracket, ReportFileName) > CHARINDEX(@StartBracket, ReportFileName); SELECT * FROM @ReportTable;
[ 実行結果 ]