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;
[ 実行結果 ]