【问题标题】:sql server query to replace variables with values recursivelysql server查询以递归方式用值替换变量
【发布时间】:2013-05-28 14:16:50
【问题描述】:

我有一个表 variable 包含变量名称及其值,例如:

  • var1 = value1
  • var2 = value2
  • var3 = value3

另一个表expression 包含表达式:

  • “使用#var1#和#var2#的字符串”
  • “另一个有#var3#和#var4#甚至#var1#”

我想用它们的值替换表variable中存在的变量,所以结果应该是:

  • “使用 value1 和 value2 的字符串”
  • “另一个有 value3 和 #var4# 甚至 value1”

有没有办法用 CTE 做到这一点?

http://sqlfiddle.com/#!3/c1e1e/2/0

【问题讨论】:

  • 为什么要递归执行此操作?
  • 因为如果你不递归地做,我认为没有办法在同一行替换多个变量。
  • 您是否有不想将表达式拆分为具有序列号的部分的原因?然后您可以像这样重新组装零件:sqlfiddle.com/#!3/e0f21/6
  • 感谢您的回复,但我无法更改架构

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


【解决方案1】:

这是一个很好的脑筋急转弯。这是递归 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-19
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 2011-02-21
    • 1970-01-01
    相关资源
    最近更新 更多