SQL 2005 - 将字符串拆分为多个部分并从拆分部分返回值

时间:2011-02-01 12:52:18

标签: sql sql-server sql-server-2005 tsql

我不确定我是否以最好的方式表达这一点,但我有一个大的文本字符串(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 个答案:

答案 0 :(得分:2)

如果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 使用子字符串instaed。将适用于你的“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