通过根据另一个表中的值替换子字符串来更新表字段

时间:2012-05-31 15:32:40

标签: sql sql-server sql-server-2008 tsql

我有一个表,我想根据另一个表中的值更新其中一个varchar字段。

我有下表:

ID  Constraint_Value 
----------------------------
1   (OldVal_1) (OldVal_2) 
2   (OldVal_2) (OldVal_1) 

...我想使用下表中的数据进行更新:

oldValue  newValue
----------------------------
OldVal_1    NewVal_1
OldVal_2    NewVal_2

更新后,我的目标是:

ID    Constraint_Value 
----------------------------
1     (NewVal_1) (NewVal_2) 
2     (NewVal_2) (NewVal_1) 

以下SQL说明了我的问题(您可以在没有任何设置的情况下在SQL Management Studio中运行):

IF OBJECT_ID('tempdb..#tmpConstraint') IS NOT NULL DROP TABLE #tmpConstraint
GO 
CREATE TABLE tempdb..#tmpConstraint ( constraint_id INT PRIMARY KEY, constraint_value varchar(256) )
GO

IF OBJECT_ID('tempdb..#tmpUpdates') IS NOT NULL DROP TABLE #tmpUpdates
GO 
CREATE TABLE tempdb..#tmpUpdates ( oldValue varchar(256), newValue varchar(256))
GO

insert into #tmpConstraint
values (1, '(OldVal_1) (OldVal_2)')

insert into #tmpConstraint
values (2, '(OldVal_2) (OldVal_1)')

insert into #tmpUpdates
values ('OldVal_1', 'NewVal_1')

insert into #tmpUpdates
values ('OldVal_2', 'NewVal_2')

select * from #tmpConstraint

update c
set constraint_value = REPLACE(constraint_value, u.oldValue, u.newValue)
from #tmpConstraint c
cross join #tmpUpdates u

select * from #tmpConstraint

这给出了结果:

(Before) 
1   (OldVal_1) (OldVal_2) 
2   (OldVal_2) (OldVal_1) 

(After) 
1   (NewVal_1) (OldVal_2) 
2   (OldVal_2) (NewVal_1) 

正如您所看到的,OldVal_1已更新。 OldVal_2保持不变。

如何使用查找表中的所有数据更新字段?

1 个答案:

答案 0 :(得分:1)

UPDATE只会影响每个源行一次。所以我所知道的最简单的解决方法是游标。

DECLARE @o VARCHAR(256), @n VARCHAR(256);

DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY 
FOR SELECT oldValue, newValue FROM #tmpUpdates;

OPEN c;

FETCH c INTO @o, @n;

WHILE @@FETCH_STATUS = 0
BEGIN
    UPDATE #tmpConstraint 
      -- note full match only:
      SET constraint_value = REPLACE(constraint_value, '(' + @o + ')', '(' + @n + ')')
      -- and note we only touch rows where there is a full match:
      WHERE constraint_value LIKE '%(' + @o + ')%';

    FETCH c INTO @o, @n;
END

CLOSE c;
DEALLOCATE c;

SELECT constraint_id, constraint_value FROM #tmpConstraint;

结果:

constraint_id  constraint_value
-------------  ---------------------
1              (NewVal_1) (NewVal_2)
2              (NewVal_2) (NewVal_1)