日期:2014-05-18 浏览次数:20865 次
--> 测试数据:[tb]
IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
GO
CREATE TABLE [tb]([id] INT,[name] VARCHAR(100))
INSERT [tb]
SELECT 1,'C:5,E:1;C:6,E:20' UNION ALL
SELECT 2,'C:5,E:1,A:21;C:55,E:7,A:21' UNION ALL
SELECT 3,'C:5,E:1;C:10,E:20'
GO
-->
-- 假设你要更新的条件是分号前面的。
-- 如更新条件为 update [tb] set [name]='C:5,D:6,E:1'+right([name],len([name])-7) where left([name],7)='C:5,E:1'
--如果不是这样就没必要往下面看了
-- 次方法适用于2005 2008
-- 可以把条件 name 改成 id
-- 支持插入人一个值。
IF OBJECT_ID('p') IS NOT NULL DROP proc p
GO
create proc p
@old_name varchar(100),
@new_name varchar(100)
as
set nocount on
begin
IF OBJECT_ID('tempdb..#t1') IS NOT NULL DROP TABLE #t1
create table #t1(iden int identity ,id int,name varchar(10),value varchar(10))
IF OBJECT_ID('tempdb..#t2') IS NOT NULL DROP TABLE #t2
create table #t2(id int,name varchar(10),value varchar(10))
IF OBJECT_ID('f_str',N'FN') IS NOT NULL DROP function f_str
--存跟新前后的name值变化
IF OBJECT_ID('tempdb..#t3') IS NOT NULL DROP TABLE #t3
create table #t3(id int,new_name varchar(100))
--第一次更新,取出更新后的值
update tb set [name]=@new_name+right([name],len([name])-len(@old_name))
output deleted.id,inserted.name into #t3
where left([name],len(@old_name))=@old_name
--select * from #t3
--拆分分号前面的值
insert into #t1
select a.id,
name=left(b.name,charindex(':',b.name)-1),
value=right(b.name,len(b.name)-charindex(':',b.name))
from(
select id,
[name] = CONVERT(XML,'<ROOT><V>' + REPLACE(left(new_name,charindex(';',new_name)-1), ',', '</V><V>') + '</V></ROOT>')
from #t3
)a
outer apply (
select [name] = N.v.[value]('.', 'varchar(10)')
from a.[name].nodes('/ROOT/V') N(v)
)b
--拆分分号后面的值
insert into #t2
select a.id,
name=left(b.name,charindex(':',b.name)-1),
value=right(b.name,len(b.name)-charindex(':',b.name))
from(
select id,
[name] = CONVERT(XML,'<ROOT><V>' + REPLACE(right(new_name,len(new_name)-charindex(';',new_name)), ',', '</V><V>') + '</V></ROOT>')
from #t3
)a
outer apply (
select [name] = N.v.[value]('.', 'varchar(10)')
from a.[name].nodes('/ROOT/V') N(v)
)b
--进行查询合并重组
;with cte as
(
select a.iden,a.id,a.name as a_name,a.value as a_value,isnull(b.name,a.name) as b_name,
b.value as b_value
from #t1 a left join #t2 b
on a.name=b.name and a.id=b.id
)
,cte2 as
(
select id,a_name,a_value,b_name,b_value=isnull(b_value,(select top 1 b_value from cte where iden<t.iden and b_value is not null order by iden desc))
from cte t
)
--select * from cte2
,cte3 as
(
select id,stuff((select ','+b_name+':'+b_value from cte2 where id=b.id for xml path('')),1,1,'') as name
from cte2 b group by id
)
--select * from cte3
update a set a.name=left(a.name,charindex(';',a.name))+b.name
from tb a,cte3 b where a.id=b.id
drop table #t1,#t2,#t3
end
--测试
select * from tb
exec p 'C:5,E:1','C:5,D:7,E:1'
select * from tb
exec p 'C:5,D:7,E:1','C:5,D:7,F:12,G:15,E:1'
select * from tb
/*
id name
----------- ----------------------------------------------------------------
1 C:5,