SQL 2005 - разбить строку на разделы и вернуть значения из разделенных разделов - PullRequest
0 голосов
/ 01 февраля 2011

Я не уверен, что формулирую это наилучшим образом, но у меня есть большая текстовая строка (формат ntext), которая в настоящее время не индексируется (я пытаюсь получить полный текстовый индекс, но не собираюсьпо крайней мере, на некоторое время), который находится в таблице аудита с подробным описанием изменений данных в других таблицах.

Что я пытаюсь сделать, это вытащить старое и новое значение для конкретной таблицы иимя поля, например, для этой строки:

CREATE TABLE #example
(
id UNIQUEIDENTIFIER --unique audit id
,date_created DATETIME --date data was modified
,changes NTEXT --what parts of the data have been changed
)

INSERT INTO #example VALUES ('74158983-7123-4AC8-A16A-CF88D3115B86','2006-04-05 13:30:42.993','<ChangedAttributes><Attribute><Name>Table1</Name><Field>field1</Field><Value>15980ffc-209f-46bb-8d15-31100640b5a8</value><OldValue>15980ffc-209f-46bb-8d15-31100640b5a8</OldValue></Attribute><Attribute><Name>Table2</Name><Field>field1 </Field><Value>05/04/2006</Value><OldValue </Attribute><Attribute><Name>Table2</Name><Field>Field2</Field><Value>Apple</Value><OldValue>Orange</OldValue</Attribute></ChangedAttributes>')

(именно так мои данные отображаются в справочной таблице). Я хотел бы получить только старые и новые значения для таблицы 1 и поля 1, даваяследующий вывод:

CREATE TABLE #output
(
id UNIQUEIDENTIFIER --unique audit id
,date_created DATETIME --date data modified
,old_value VARCHAR(255) --what the data value was
,new_value VARCHAR(255) --what the data value was changed to
)
INSERT INTO #output VALUES('74158983-7123-4AC8-A16A-CF88D3115B86','2006-04-05 13:30:42.993','15980ffc-209f-46bb-8d15-31100640b5a8','193B3612-551D-4EB0-B840-900F916A1BF7')

Как я уже сказал, это может звучать как бред, так что если я могу что-то сделать, чтобы уточнить, я сделаю все возможное!

Спасибо:)

1 Ответ

2 голосов
/ 01 февраля 2011

Вот версия, которая работает, если xml верен.

declare @T table (id uniqueidentifier, date_created datetime, [changes] ntext)

insert into @T values (
  '74158983-7123-4AC8-A16A-CF88D3115B86',
  '2006-04-05 13:30:42.993',
  '<ChangedAttributes>
    <Attribute>
        <Name>Table1</Name>
        <Field>field1</Field>
        <Value>15980ffc-209f-46bb-8d15-31100640b5a7</Value>
        <OldValue>15980ffc-209f-46bb-8d15-31100640b5a8</OldValue>
    </Attribute>
    <Attribute>
        <Name>Table2</Name>
        <Field>field1 </Field>
        <Value>05/04/2006</Value>
        <OldValue/>
    </Attribute>
    <Attribute>
        <Name>Table2</Name>
        <Field>Field2</Field>
        <Value>Apple</Value>
        <OldValue>Orange</OldValue>
    </Attribute>
</ChangedAttributes>')


select
  id,
  date_created,
  c.a.value('OldValue[1]', 'varchar(50)') as old_value,
  c.a.value('Value[1]', 'varchar(50)') as new_value
from
    (select id, date_created, cast([changes] as xml) as [changes]
     from @T) as T
cross apply
   [changes].nodes('ChangedAttributes/Attribute') c(a)

Результат

id                                   date_created            old_value                            new_value
74158983-7123-4AC8-A16A-CF88D3115B86 2006-04-05 13:30:42.993 15980ffc-209f-46bb-8d15-31100640b5a8 15980ffc-209f-46bb-8d15-31100640b5a7
74158983-7123-4AC8-A16A-CF88D3115B86 2006-04-05 13:30:42.993                                      05/04/2006
74158983-7123-4AC8-A16A-CF88D3115B86 2006-04-05 13:30:42.993 Orange                               Apple 

Редактировать 1 Это даст вам первый атрибут в xml

select
  id,
  date_created,
  c.a.value('OldValue[1]', 'varchar(50)') as old_value,
  c.a.value('Value[1]', 'varchar(50)') as new_value
from
    (select id, date_created, cast([changes] as xml) as [changes]
     from @T) as T
cross apply
   [changes].nodes('ChangedAttributes/Attribute[1]') c(a)

Редактировать 2 С фильтром по имени вместо

select
  id,
  date_created,
  c.a.value('OldValue[1]', 'varchar(50)') as old_value,
  c.a.value('Value[1]', 'varchar(50)') as new_value
from
    (select id, date_created, cast([changes] as xml) as [changes]
     from @T) as T
cross apply
   [changes].nodes('ChangedAttributes/Attribute') c(a)
where c.a.value('Name[1]', 'varchar(50)') = 'Table1'

Редактировать 3 Использование подстроки. Будет работать на вашем "XML"

select 
  id,
  date_created,
  substring([changes], charindex('<OldValue>', [changes], 0)+10, charindex('</OldValue>', [changes], 0)-charindex('<OldValue>', [changes], 0)-10) as old_value,
  substring([changes], charindex('<Value>', [changes], 0)+7, charindex('</value>', [changes], 0)-charindex('<Value>', [changes], 0)-7) as new_value
from @T
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...