2016-10-31 5 views
0

Я в середине преобразования столбца NTEXT в несколько записей. Я хочу разбить исходный столбец на новую строку или объект json. Это, безусловно, уникальный сценарий, но за пределами среды sql это регулярное выражение правильно соответствует всему, что мне нужно, из исходного столбца:Разделить столбцы 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.

ответ

1

С помощью функции Split/синтаксического анализа

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 

Возвращает

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

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

ОДС, если это необходимо

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) 
+0

Действительно большой ответ! Цените помощь. Я только что понял, что данные, которыми я манипулирую, также имеют некоторые вложенные данные json (pooh). Как вы можете манипулировать UDF, чтобы игнорировать '{', который не сразу следует за новой строкой? (Перед всеми вложенными json-данными есть как минимум два пробела.) –

+0

@SamThornton Я беспокоился об этом. Позвольте мне немного лапнуть. –

+0

@SamThornton FYI, UDF - это просто парсер. 1,001 использует. Можете ли вы поставить более надежную строку JSON? –