這一次是一個很好的謎題。這裏有一個遞歸CTE的方法:
--using recursive CTE
with
subq (original, corrected, PassNum) as
(
select expression.expression as corrected, expression.expression as original, 1 as PassNum from expression
union all
select subq.original, cast(replace(subq.corrected, '#' + variable.name + '#', variable.value) as varchar(100)),
PassNum+1 as PassNum from subq, variable where subq.corrected like '%#' + variable.name + '#%'
)
update expression set expression.expression=subq.corrected from expression inner join subq on
expression.expression=subq.original where subq.passnum=(select max(passnum) from subq)
它有一些煩惱,喜歡的事實,你有那麼它列大小(請參閱下面的詳細瞭解此),以及PassNum
變量,匹配投修正值是我能找到的唯一方法來指出哪個更新是最後一個。
世俗光標的方法可能是更容易調試,因爲它更簡單:
--using cursor
DECLARE @name VARCHAR(50)
DECLARE @value VARCHAR(50)
DECLARE loopCursor CURSOR FOR
SELECT name, value from variable
OPEN loopCursor
FETCH NEXT FROM loopCursor INTO @name, @value
WHILE @@FETCH_STATUS = 0
BEGIN
update expression set expression.expression=replace(expression, '#' + @name + '#', @value)
FETCH NEXT FROM loopCursor INTO @name, @value
END
CLOSE loopCursor
DEALLOCATE loopCursor
這是我發現對鑄件使用遞歸CTE時報價:
您所看到的行爲是由設計。雖然我們可以輸入 爲列和/或脅迫類型進行派生,但對於遞歸 CTE,我們選擇嚴格保持派生。也有一些角落 案例,其中類型派生將無法達到正確的精度/比例/長度的 。這可能會導致錯誤。 因此,我們的建議與您觀察到的一樣是使用CAST明確鍵入任何 表達式。 -Umachandar,SQL可編程性團隊[1]
[1] http://connect.microsoft.com/SQLServer/feedback/details/668872/types-dont-match-between-the-anchor-and-the-recursive-part-in-column-columnname-of-recursive-query-cte-name
爲什麼你想遞歸地做到這一點? – RBarryYoung
因爲如果你不遞歸地做它,我不認爲有一種方法可以在同一行中替換多個變量。 – psadac
是否有原因不希望將表達式拆分爲具有序列號的部分?然後,您可以像這樣重新組裝零件:http://sqlfiddle.com/#!3/e0f21/6 – JAQFrost