递归变量自赋值有效吗?

问题描述 投票:0回答:1

我找到了一些 T-SQL 代码,我正在尝试弄清楚它是否是:

  • 一个我从来不知道的优雅解决方案
  • 这是一个可怕的可憎行为,发生起作用,绝对应该被删除
  • 或介于两者之间。

标准化名称

我们有要求尝试清理名称:

  • Bob
    Robert
  • Bill
    William
  • Dick
    Richard

因此创建了一个表来保存 以及将其替换为 值。它包含上述单词(以及更深奥的、特定领域的、特定行业的、映射):

填充词

价值 替换为
迪克 理查德
比尔 威廉
鲍勃 罗伯特
特德 威廉

我看到的用于执行替换的代码要么是天才,要么是疯狂:

DECLARE @firstName varchar(200) = 'bill';
SELECT @firstName = REPLACE(@firstName, FillerWords.Value, FillerWords.ReplaceWith) FROM FillerWords;
SELECT @firstName;

这给出了:

(no column name)
----------------
William

1 row(s) affected

更令人印象深刻的是它可以一次进行多个替换:

DECLARE @firstName varchar(200) = 'teddickbobbill';
SELECT @firstName = REPLACE(@firstName, FillerWords.Value, FillerWords.ReplaceWith) FROM FillerWords;
SELECT @firstName;

这给出了:

(no column name)
----------------
WilliamRichardRobertWilliam

1 row(s) affected

它有效,但是它有效吗?

它是如何工作的?

如果在选择过程中消除变量赋值:

SELECT REPLACE(@firstName, fw.Value, fw.ReplaceWith) FROM #FillerWords fw

您会看到它正在对表中的每一行执行

REPLACE

(No column name)
teddickRobertbill
tedRichardbobbill
Williamdickbobbill
teddickbobWilliam

因此,每次计算一行时,都会更新

@firstName
变量:

@名字 价值 替换为 @firstName 的新值
泰迪克鲍比尔 迪克 理查德 ted理查德博比尔
ted理查德博比尔 比尔 威廉 ted理查德鲍勃威廉
ted理查德鲍勃威廉 鲍勃 罗伯特 ted理查德罗伯特威廉
红色理查德罗伯特威廉 特德 威廉 威廉理查德罗伯特威廉

所以它似乎依赖于变量赋值的一个怪癖,你可以不断地逐行修改相同的变量;这几乎就像一个光标操作。

是否支持这种 T-SQL 编程风格?我知道递归公用表表达式(CTE)一直在这样做;但这里允许吗?

我知道代码的成功取决于处理行的顺序,这在 SQL 中通常无法保证。这可能会导致结果不一致,尤其是当基础数据或 SQL Server 的查询执行计划发生更改时。我不关心这个,在这里,在这个问题中。

一个可能的答案

我问了一位

oratrice mechanique d'analysis cardinal,它说:

该代码利用了 T-SQL 的特定行为,其中可以在 SELECT 语句中更新变量。然而,这不是标准的 SQL 行为,并且可能不直观或不可维护。虽然这在当前版本的 SQL Server 中有效,但不能保证此类行为在未来版本中保持一致或受支持,因为它不是用于此类目的的记录功能。

递归设置变量

不是可接受的模式吗?

sql-server t-sql recursive-query
1个回答
0
投票
这与旧的

字符串聚合技术属于同一类,它有时有效,有时无效(取决于执行计划),并且从来都不是受支持的技术。

文档明确警告“

递归变量赋值的反模式使用

您的代码

SELECT @firstName = REPLACE(@firstName, ...) FROM
肯定是对结构的警告

SELECT @Var = <expression containing @Var> FROM
    
© www.soinside.com 2019 - 2024. All rights reserved.