2014-09-01 6 views
0

У меня есть 2 таблицы A и B. Данные в таблице A имеют строку, которую я хотел бы разбить на разные столбцы на основе "#___-" (abc, xyz, efg и т. Д.) И скопировать ее в таблицу B. Размер строка таблицы A будет изменяться для каждой строкиРазделить строку переменной длины на несколько столбцов

Таблица А:

Create table A (data varchar(100)); 

Insert table A 
    values ('101,#abc-sds)dfgd)3453)#xyz-hju)dddjfj)eieei)2323'); 
Insert into A 
    values ('102,#abc-ddeff)errr)3434)#xyz-bnhb)hehe)333)#abc-dew)weerr)2343)#efg-3434)34'); 

Create table B (id number, abc varchar2(50), xyz varchar2(50), 
    efg varchar2(50)); 

Выход Таблица B:

ID | ABC    | XYZ     | EFG 
    --------------------------------------------------------------- 
    101 | sds)dfgd)3453) | hju)dddjfj)eieei)2323 | 
    102 | ddeff)errr)3434) | bnhb)hehe)333)   | 3434)34 
    102 | dew)weerr)2343) | bnhb)hehe)333)   | 3434)34 

я попробовал регулярные выражения, но поскольку размер строки может изменяться, и из-за для дублирования я не мог пойти дальше, любая помощь будет оценена.

+0

Не понимаю, как разделить, что такое маркер, показать больше примеров и как разбить его. – zaratustra

+2

Вы хотите разбить одну строку на несколько строк * и * столбцов? Почему значения xyz/efg для 102 повторяются в обеих строках - если '# abc' является началом следующей« строки », не будет ли одна строка получать xyz, а другая - efg? И как далеко вы достигли своей регулярной экспрессии? –

ответ

0

Если вы спрашиваете, что я думаю, что вы просите, вы будете нуждаться в Dynamic SQL, регулярных выражений и поворачивающимися. Динамический SQL для генерации кода, который будет создавать таблицу с соответствующими столбцами (так как они названы в честь #___- и их произвольное количество). Поворот для поворота столбца значений в строки на идентификатор.

Я привык к SQL Server, а не к Oracle, а возможности Regex, которые я использую, - это UDF, поскольку SQL Server не имеет собственных возможностей Regex. Поэтому мой ответ только поможет, но может дать вам представление о том, как подойти к этому.

Я полагаю, вы могли бы построили регулярное выражение UDF в Oracle, наше регулярное выражение UDF возвращает результат-набор, который я могу join или в случае, если в SQL Server cross/outer apply и это дает мне Value varchar с всем матчем и SubMatches xml с захваченным submatches:

create table #A (data varchar(100)); 

Insert into #A 
    values ('101,#abc-sds)dfgd)3453)#xyz-hju)dddjfj)eieei)2323'); 
Insert into #A 
    values ('102,#abc-ddeff)errr)3434)#xyz-bnhb)hehe)333)#abc-dew)weerr)2343)#efg-3434)34'); 

declare @cols nvarchar(max), @q nvarchar(max) 


    -- Gets found columns comma-separated in @cols: 
select @cols = isnull(@cols + ', ', '') + substring(r.Value, 2, len(r.Value)-2) 
from #A 
cross apply dbo.RegexFind(data, '#(\w+)-', 1, 1, 1) r 
group by r.Value 


    -- Dynamically create #B with @cols and insert 
set @q = N'create table #B(id int, ' + replace(@cols, ', ', ' varchar(255), ') + ' varchar(255)) 
insert into #B 
select p.* 
from (
    select r.Value, 
     a.SubMatches.value(''(//submatch[@index=0]/@value)[1]'', ''varchar(255)'') col, 
     a.SubMatches.value(''(//submatch[@index=1]/@value)[1]'', ''varchar(255)'') val 
    from #A 
     -- Find the ID at the start 
    cross apply dbo.RegexFind(data, ''^\d+'', 1, 1, 1) r 
     -- Find any and all #___- occurrences and the text after it 
    outer apply dbo.RegexFind(data, ''#(\w+)-([^#]+)'', 1, 1, 1) a 
) s 
pivot (-- Pivot dynamically on the found @cols 
    min(val) for col in (' + @cols + ') 
) p 
select * from #B' 

exec sp_executesql @q 

с вашим примером содержанием таблицы #A это дает следующий SQL (содержание @q):

create table #B(id int, abc varchar(255), efg varchar(255), xyz varchar(255)) 
insert into #B 
select p.* 
from (
    select r.Value, 
     a.SubMatches.value('(//submatch[@index=0]/@value)[1]', 'varchar(255)') col, 
     a.SubMatches.value('(//submatch[@index=1]/@value)[1]', 'varchar(255)') val 
    from #A 
     -- Find the ID at the start 
    cross apply dbo.RegexFind(data, '^\d+', 1, 1, 1) r 
     -- Find any and all #___- occurrences and the text after it 
    outer apply dbo.RegexFind(data, '#(\w+)-([^#]+)', 1, 1, 1) a 
) s 
pivot (-- Pivot dynamically on the found @cols 
    min(val) for col in (abc, efg, xyz) 
) p 
select * from #B 

Примечания Тхи ugh что эта таблица #B temp существует только внутри динамического SQL, я не знаю, как Oracle справляется с этим.

Смежные вопросы