简体   繁体   English

通过正则表达式匹配将SQL列拆分为多行

[英]Split SQL Column into Multiple Rows by Regex Match

I'm in the middle of converting an NTEXT column into multiple records. 我正在将NTEXT列转换为多个记录。 I'm looking to split the original column by new line or json object. 我正在寻找通过换行或json对象拆分原始列。 It's a unique scenario, to be sure, but outside of a sql environment this regex correctly matches everything I need from the original column: 可以肯定,这是一个独特的场景,但是在sql环境之外,此正则表达式正确地匹配了我从原始列中获取的所有内容:

({(.*)(.*\\r\\n)*?})|(.+\\r\\n) . ({(.*)(.*\\r\\n)*?})|(.+\\r\\n)

If I have a record with a column that has the value: 如果我有一条记录,该列的值是:

Foo bar baz
hello world
{
  foo: 'bar',
  bar: 'foo'
}
{
  foo: 'foo',
  bar: 'bar'
}

I want to break it into multiple records: 我想将其分为多个记录:

| ID | Text         |
---------------------
|  1 | Foo bar baz  |

|  2 | hello world  |

|  3 | {            |
|    |   foo: 'bar' |
|    |   bar: 'foo' |
|    | }            |

|  4 | {            |
|    |   foo: 'foo' |
|    |   bar: 'bar' |
|    | }            |

Any easy way to accomplish this? 有什么简单的方法可以做到这一点? It's a SQL Express server. 这是一个SQL Express服务器。

With the help of a split/parse function 借助拆分/解析功能

Declare @String varchar(max)='Foo bar baz
hello world
{
  foo: ''bar'',
  bar: ''foo''
}
{
  foo: ''foo'',
  bar: ''bar''
}'

Select ID=Row_Number() over (Order By (Select NULL))
      ,Text = B.RetVal
 From (Select RetSeq,RetVal = IIF(CharIndex('}',RetVal)>0,'{'+RetVal,RetVal) from [dbo].[udf-Str-Parse](@String,'{')) A
 Cross Apply (
               Select * from [dbo].[udf-Str-Parse](A.RetVal,IIF(CharIndex('{',A.RetVal)>0,char(1),char(10)))
             ) B
 Where B.RetVal is Not Null

Returns 退货

ID  Text
1   Foo bar baz
2   hello world
3   {
     foo: 'bar',
     bar: 'foo'
    }

4   {
     foo: 'foo',
     bar: 'bar'
    }

The UDF if needed UDF(如果需要)

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = Row_Number() over (Order By (Select null))
          ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From (Select x = Cast('<x>'+ Replace(@String,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i)
);
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
--Performance On a 5,000 random sample -8K 77.8ms, -1M 79ms (+1.16), -- 91.66ms (+13.8)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM