通过正则表达式匹配将 SQL 列拆分为多行
Split SQL Column into Multiple Rows by Regex Match
我正在将 NTEXT 列转换为多条记录。我希望通过新行或 json 对象拆分原始列。可以肯定的是,这是一个独特的场景,但在 sql 环境之外,此正则表达式正确匹配我从原始列中需要的所有内容:
({(.*)(.*\r\n)*?})|(.+\r\n)
.
如果我的记录中有一列的值为:
Foo bar baz
hello world
{
foo: 'bar',
bar: 'foo'
}
{
foo: 'foo',
bar: 'bar'
}
我想把它分成多条记录:
| ID | Text |
---------------------
| 1 | Foo bar baz |
| 2 | hello world |
| 3 | { |
| | foo: 'bar' |
| | bar: 'foo' |
| | } |
| 4 | { |
| | foo: 'foo' |
| | bar: 'bar' |
| | } |
有什么简单的方法可以做到这一点?这是一个 SQL Express 服务器。
借助 split/parse 函数
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'
}
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)
我正在将 NTEXT 列转换为多条记录。我希望通过新行或 json 对象拆分原始列。可以肯定的是,这是一个独特的场景,但在 sql 环境之外,此正则表达式正确匹配我从原始列中需要的所有内容:
({(.*)(.*\r\n)*?})|(.+\r\n)
.
如果我的记录中有一列的值为:
Foo bar baz
hello world
{
foo: 'bar',
bar: 'foo'
}
{
foo: 'foo',
bar: 'bar'
}
我想把它分成多条记录:
| ID | Text |
---------------------
| 1 | Foo bar baz |
| 2 | hello world |
| 3 | { |
| | foo: 'bar' |
| | bar: 'foo' |
| | } |
| 4 | { |
| | foo: 'foo' |
| | bar: 'bar' |
| | } |
有什么简单的方法可以做到这一点?这是一个 SQL Express 服务器。
借助 split/parse 函数
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'
}
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)