Sql server 是否可以构造此sql更新查询而不将其包装在游标中?
我有两张桌子。包含键/值对的一种。另一个包含varchar列,这些列需要用相应的值替换文本中所有键的实例 我已经在一个使用游标的存储过程中实现了这一点。但我确实需要存储过程尽可能高效地执行。我的第一个想法是删除光标。可能吗?也许使用递归cte?示例如下 设置Sql server 是否可以构造此sql更新查询而不将其包装在游标中?,sql-server,tsql,Sql Server,Tsql,我有两张桌子。包含键/值对的一种。另一个包含varchar列,这些列需要用相应的值替换文本中所有键的实例 我已经在一个使用游标的存储过程中实现了这一点。但我确实需要存储过程尽可能高效地执行。我的第一个想法是删除光标。可能吗?也许使用递归cte?示例如下 设置 DECLARE @Dictionary TABLE ( WordKey NVARCHAR(255), WordValue NVARCHAR(4000) ) INSERT INTO @Dictionary VALUES
DECLARE @Dictionary TABLE
(
WordKey NVARCHAR(255),
WordValue NVARCHAR(4000)
)
INSERT INTO @Dictionary
VALUES
('[key1]', 'Value1'),
('[key2]', 'Value2'),
('[key3]', 'Value3')
DECLARE @Phrasings TABLE
(
Phrasing1 NVARCHAR(4000),
Phrasing2 NVARCHAR(4000),
Phrasing3 NVARCHAR(4000)
)
INSERT INTO @Phrasings
VALUES
('[key1]','random text','random text'),
('random text','random [key2] text','random text'),
('random text [key1]','random [key2] text','random [key1] [key3] text')
主查询
DECLARE @WordKey NVARCHAR(255)
DECLARE @WordValue NVARCHAR(max)
DECLARE parsing_cursor CURSOR FOR
SELECT WordKey,WordValue FROM @Dictionary
OPEN parsing_cursor
FETCH NEXT FROM parsing_cursor
INTO @WordKey, @WordValue
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE @Phrasings SET
Phrasing1 = REPLACE(Phrasing1, @WordKey, @WordValue),
Phrasing2 = REPLACE(Phrasing2, @WordKey, @WordValue),
Phrasing3 = REPLACE(Phrasing3, @WordKey, @WordValue)
FETCH NEXT FROM parsing_cursor
INTO @WordKey, @WordValue
END
CLOSE parsing_cursor
DEALLOCATE parsing_cursor
预期结果
Phrasing1 Phrasing2 Phrasing3
^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^
"Value1" "random text" "random text"
"random text" "random Value2 text" "random text"
"random text Value1" "random Value2 text" "random Value1 Value3 text"
试试这个-
查询:
DECLARE @Dictionary TABLE (WordKey VARCHAR(255), WordValue VARCHAR(400))
INSERT INTO @Dictionary (WordKey, WordValue)
VALUES
('[key1]', 'Value1'),
('[key2]', 'Value2'),
('[key3]', 'Value3')
DECLARE @Phrasings TABLE (Phrasing1 VARCHAR(400), Phrasing2 VARCHAR(400), Phrasing3 VARCHAR(400))
INSERT INTO @Phrasings (Phrasing1, Phrasing2, Phrasing3)
VALUES
('[key1]', 'random text', 'random text'),
('random text', 'random [key2] text', 'random text'),
('random text [key1]', 'random [key2] text', 'random [key1] [key3] text')
;WITH cte AS
(
SELECT x = (
SELECT
Phrasing1
, Phrasing2
, Phrasing3
FROM @Phrasings t
FOR XML PATH('ID')
), lvl = 1
UNION ALL
SELECT REPLACE(x, t.WordKey, t.WordValue), lvl + 1
FROM cte
JOIN (
SELECT WordKey, WordValue, rn = ROW_NUMBER() OVER (ORDER BY (SELECT 1))
FROM @Dictionary
) t ON rn = lvl
)
SELECT
Phrasing1 = t.c.value('Phrasing1[1]', 'VARCHAR(400)')
, Phrasing2 = t.c.value('Phrasing2[1]', 'VARCHAR(400)')
, Phrasing3 = t.c.value('Phrasing3[1]', 'VARCHAR(400)')
FROM (
SELECT TOP 1 x = CAST(x AS XML)
FROM cte
ORDER BY lvl DESC
) r
CROSS APPLY x.nodes('/ID') t(c)
Phrasing1 Phrasing2 Phrasing3
-------------------- -------------------- ---------------------------
Value1 random text random text
random text random Value2 text random text
random text Value1 random Value2 text random Value1 Value3 text
结果:
DECLARE @Dictionary TABLE (WordKey VARCHAR(255), WordValue VARCHAR(400))
INSERT INTO @Dictionary (WordKey, WordValue)
VALUES
('[key1]', 'Value1'),
('[key2]', 'Value2'),
('[key3]', 'Value3')
DECLARE @Phrasings TABLE (Phrasing1 VARCHAR(400), Phrasing2 VARCHAR(400), Phrasing3 VARCHAR(400))
INSERT INTO @Phrasings (Phrasing1, Phrasing2, Phrasing3)
VALUES
('[key1]', 'random text', 'random text'),
('random text', 'random [key2] text', 'random text'),
('random text [key1]', 'random [key2] text', 'random [key1] [key3] text')
;WITH cte AS
(
SELECT x = (
SELECT
Phrasing1
, Phrasing2
, Phrasing3
FROM @Phrasings t
FOR XML PATH('ID')
), lvl = 1
UNION ALL
SELECT REPLACE(x, t.WordKey, t.WordValue), lvl + 1
FROM cte
JOIN (
SELECT WordKey, WordValue, rn = ROW_NUMBER() OVER (ORDER BY (SELECT 1))
FROM @Dictionary
) t ON rn = lvl
)
SELECT
Phrasing1 = t.c.value('Phrasing1[1]', 'VARCHAR(400)')
, Phrasing2 = t.c.value('Phrasing2[1]', 'VARCHAR(400)')
, Phrasing3 = t.c.value('Phrasing3[1]', 'VARCHAR(400)')
FROM (
SELECT TOP 1 x = CAST(x AS XML)
FROM cte
ORDER BY lvl DESC
) r
CROSS APPLY x.nodes('/ID') t(c)
Phrasing1 Phrasing2 Phrasing3
-------------------- -------------------- ---------------------------
Value1 random text random text
random text random Value2 text random text
random text Value1 random Value2 text random Value1 Value3 text
使用持久表
字典
可以使用如下用户函数
Create Function F_Replace(@Phrasing NVARCHAR(4000)) RETURNS NVARCHAR(4000)
begin
Declare @Result NVARCHAR(4000)
Select @Result=@Phrasing
Select @Result= REPLACE(@Result,WordKey,WordValue)
from Dictionary
Return @Result
end
你可以有这样一个查询
Select dbo.F_Replace(Phrasing1) ,dbo.F_Replace(Phrasing2) ,dbo.F_Replace(Phrasing3)
from @Phrasings
@Dictionary表中的行数是否已固定???如果是,则在更新查询中使用嵌套替换函数。不,不幸的是,两个表中的总行数和行内容不是固定的或静态的。字典在xml传递到存储过程时开始使用。因此,我只是改变了功能,以接收以及它的工作待遇。非常感谢