来自Special Kind of ntext列的SQL SubString

时间:2014-03-27 14:23:13

标签: sql sql-server

我有一个DB表,类型为ntext的列填充了

之类的值
  

A&。1, 'attrdisplay'= A<?1,..., '1361147_2'= '2', '1361147_3'= '3', '1361147_4'= '4', '1361147_5'= '5' , '1361147_6'= '6', '1361147_7'= '1' >, 'ClassificationInheritance'= A< 1,..., 'DisabledIds'= A< 1,>>, '保密'= 0,” CreationNotification'= A< 1,?,'mail'='Ärendeharskapats','recipients'= A< 1,?,1414822 = -1,1414823 = -1,1414824 = -1,1414825 = -1,1414826 = -1,1414827 -1,1415811 = = -1>>, 'IsSubBinder'= 1, '名称'= A&。1, '全名'= 'Ärendemall5', 'mlNames'= A< 1,? , 'SV'= 'Ärendemall5' >, '名称'= 'Ärendemall5', 'nameFormat'= ':名称:', 'OK'=真, 'refnr'= 'SJCM-2013-00014' >中” showDocumentsFirst '=真,' 工作项目 '= A&。1,?' ID '= - 1,' 名称 '=''>>

我必须为表中的每一行提取此值SJCM-2013-00014

知道我该怎么做吗?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

我猜你真正想要的是搜索和提取refnr?如果你有可能将CLR函数添加到服务器,为了能够使用正则表达式,这是迄今为止最简单的方法:

CREATE TABLE #test (data ntext)
INSERT INTO #test VALUES('A<1,?,''attrdisplay''=A<1,?,''1361147_2''=''2'',''1361147_3''=''3'',''1361147_4''=''4'',''1361147_5''=''5'',''1361147_6''=''6'',''1361147_7''=''1''>,''ClassificationInheritance''=A<1,?,''DisabledIds''=A<1,?>>,''Confidential''=0,''CreationNotification''=A<1,?,''mail''=''Ärende har skapats'',''recipients''=A<1,?,1414822=-1,1414823=-1,1414824=-1,1414825=-1,1414826=-1,1414827=-1,1415811=-1>>,''IsSubBinder''=1,''name''=A<1,?,''fullname''=''Ärendemall5'',''mlNames''=A<1,?,''sv''=''Ärendemall5''>,''name''=''Ärendemall5'',''nameFormat''='':name:'',''ok''=true,''refnr''=''SJCM-2013-00014''>,''showDocumentsFirst''=true,''WorkItem''=A<1,?,''id''=-1,''Name''=''''>>')

SELECT
    *,
    [dbo].[RegexMatchGroupClr](
        CAST(data as nvarchar(max)), 
        'refnr''=''(?<refnr>[^'']+)''', 
        'refnr'
    )
FROM
    #test 

这是在CLR函数中使用正则表达式完成的,在C#中看起来像这样:

[SqlFunction]
public static SqlChars RegexMatchGroupClr(SqlChars input, string pattern, string groupName)
{
    if (input.IsNull) return input;

    string inputString = new string(input.Value);
    rx.Match match = rx.Regex.Match(inputString, pattern);

    if (match.Success && match.Groups[groupName].Success)
    {
        string resultString = match.Groups[groupName].Value;
        SqlChars result = new SqlChars(resultString.ToCharArray());
        return result;
    }

    return null;
}

如果你没有可能添加CLR功能,它仍然可行,但更麻烦:

CREATE TABLE #test (data ntext)
INSERT INTO #test VALUES('A<1,?,''attrdisplay''=A<1,?,''1361147_2''=''2'',''1361147_3''=''3'',''1361147_4''=''4'',''1361147_5''=''5'',''1361147_6''=''6'',''1361147_7''=''1''>,''ClassificationInheritance''=A<1,?,''DisabledIds''=A<1,?>>,''Confidential''=0,''CreationNotification''=A<1,?,''mail''=''Ärende har skapats'',''recipients''=A<1,?,1414822=-1,1414823=-1,1414824=-1,1414825=-1,1414826=-1,1414827=-1,1415811=-1>>,''IsSubBinder''=1,''name''=A<1,?,''fullname''=''Ärendemall5'',''mlNames''=A<1,?,''sv''=''Ärendemall5''>,''name''=''Ärendemall5'',''nameFormat''='':name:'',''ok''=true,''refnr''=''SJCM-2013-00014''>,''showDocumentsFirst''=true,''WorkItem''=A<1,?,''id''=-1,''Name''=''''>>')
DECLARE @SearchFor varchar(10) = 'refnr''=''';
DECLARE @EndsWith varchar(10) = '''';

WITH converted AS (
    SELECT
        CAST(data as nvarchar(max)) as data
    FROM
        #test
), startPos AS (
    SELECT
        *
        ,CHARINDEX(@SearchFor, data) + LEN(@SearchFor) as startPos
    FROM
        converted
), endPos AS (
    SELECT
        *
        ,CHARINDEX(@EndsWith, data, startPos) as endPos
    FROM
        startPos
)
SELECT
    *
    ,SUBSTRING(data, startPos, endPos - startPos) as refnr
FROM
    endPos

如果你不能使用Common Table Expressions,那就更难以理解了:

CREATE TABLE #test (data ntext)
INSERT INTO #test VALUES('A<1,?,''attrdisplay''=A<1,?,''1361147_2''=''2'',''1361147_3''=''3'',''1361147_4''=''4'',''1361147_5''=''5'',''1361147_6''=''6'',''1361147_7''=''1''>,''ClassificationInheritance''=A<1,?,''DisabledIds''=A<1,?>>,''Confidential''=0,''CreationNotification''=A<1,?,''mail''=''Ärende har skapats'',''recipients''=A<1,?,1414822=-1,1414823=-1,1414824=-1,1414825=-1,1414826=-1,1414827=-1,1415811=-1>>,''IsSubBinder''=1,''name''=A<1,?,''fullname''=''Ärendemall5'',''mlNames''=A<1,?,''sv''=''Ärendemall5''>,''name''=''Ärendemall5'',''nameFormat''='':name:'',''ok''=true,''refnr''=''SJCM-2013-00014''>,''showDocumentsFirst''=true,''WorkItem''=A<1,?,''id''=-1,''Name''=''''>>')
DECLARE @SearchFor varchar(10) = 'refnr''=''';
DECLARE @EndsWith varchar(10) = '''';

SELECT
    *
    ,SUBSTRING(data, (CHARINDEX(@SearchFor, data) + LEN(@SearchFor)), (CHARINDEX(@EndsWith, data, (CHARINDEX(@SearchFor, data) + LEN(@SearchFor)))) - (CHARINDEX(@SearchFor, data) + LEN(@SearchFor))) as refnr
FROM
    #test