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