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

标签 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 保持不变。

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

最佳答案

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)

关于sql - 通过根据另一个表中的值替换子字符串来更新表字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10836681/

相关文章:

sql-server - HTTP 状态 500 - 此驱动程序不支持 Java 运行时环境 (JRE) 版本 1.7

sql-server - 阻止 SQL Server Management Studio 添加 ANSI_NULLS 和 QUOTED_IDENTIFIER

sql-server - 计算sql server中值中的空格数

sql-server-2008 - Tablix 标题不会在新页面上重复,当子报表导致分页时

sql-server - 在 SQL Server 数据库中使用脚本删除主键

sql - 索引 SQL 表以查找最佳匹配字符串的最佳方法

SQL Server - 按情况排序

sql - 在sql中的某些单词之间选择数字

sql - 由于触发器而被锁定在 SQL Server 之外

c# - 我可以使用流在 SQL Server (C#) 中插入或更新行吗?