在SQL-Server中批量替换

时间:2014-02-19 10:20:50

标签: sql-server

是否可以在没有while循环的情况下进行批量替换或者什么是最佳方式

表格-1

+-------+--------+
| name  |  value |
+-------+--------+
| @1@   |   one  |
| @2@   |   two  |
| @3@   |  three |
+-------+--------+

表-2 (更新:表2中有多个不同的令牌)

+-----------------------+
|    col1               |
+-----------------------+
| string @1@ string @2@ |
| string @2@ string @1@ |
| string @3@ string @2@ |
+-----------------------+

我喜欢将Table-2中的所有令牌分别替换为Table-1的value列。

预期结果

+-------------------------+
|    col1                 |
+-------------------------+
| string one string two   |
| string two string one   |
| string three string two |
+-------------------------+

使用While循环的当前解决方案

declare @table1 table(name nvarchar(50),value nvarchar(50)) 
insert into @table1 values('@1@','one'),('@2@','two'),('@1@','three')

declare @table2 table(col1 nvarchar(50)) 
insert into @table2 values('string @1@ string @2@'),('string @2@ string @1@'),('string @3@ string @2@')

WHILE EXISTS (SELECT 1 FROM @table2 t2 INNER JOIN @table1 t1 ON CHARINDEX(t1.name,[col1])>0)
BEGIN
    UPDATE @table2
    SET col1=REPLACE(col1,name,value)
    FROM @table1
    WHERE CHARINDEX(name,[col1])>0  
END

select * from @table2

由于

2 个答案:

答案 0 :(得分:0)

我想你使用的是Sql Server(用tsql标记):

我在2012版本的Sql上运行此查询,但在我的PC上我尝试过使用2008r2版本。

你可以这样做:

UPDATE table2
SET col1 = REPLACE(col1, 
(SELECT name FROM table1 WHERE col1 LIKE '%' + table1.NAME + '%'),
(SELECT value FROM table1 WHERE col1 LIKE '%' + table1.NAME + '%'))

Sql Fiddle

如果您只想显示没有UPDATE的值,您可以这样继续:

SELECT REPLACE(T2.col1, T1.name, T1.value)
FROM table1 T1
JOIN table2 T2
ON T2.col LIKE '%' T1.name + '%'

修改

编辑问题/评论后我的答案不完整,因为在同一行可以存在更多的一个标记。我在想......:)

我想:D

恕我直言:你必须在你的桌子上创建一个循环,因为有几个标记的存在不能用带有子查询的单个UPDATE语句解析,因为在你编写时,子查询会返回多个值。

在Sql Server中,REPLACE函数只更改令牌,所以如果你想要改变一步两个令牌,你必须嵌套你的REPLACE函数,但是我们有一个未定义的令牌,所以我们不能阻止应用确切的REPLACE数量。您可以使用游标和动态SQL查询构建运行时的帮助,因此您可以每行执行一次UPDATE。如果你想要一个使用CURSOR和DYNAMIC SQL的指南,请写信给我。晚安;)

答案 1 :(得分:0)

update @table2
set col1= left(a.col1,6)+' ' + b.value from @table2 a
join @table1 b on b.name=substring(a.col1,8,3)

select * from @table2