我找到了一些 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 中有效,但不能保证此类行为在未来版本中保持一致或受支持,因为它不是用于此类目的的记录功能。递归设置变量
不是可接受的模式吗?
字符串聚合技术属于同一类,它有时有效,有时无效(取决于执行计划),并且从来都不是受支持的技术。
文档明确警告“递归变量赋值的反模式使用”
您的代码
SELECT @firstName = REPLACE(@firstName, ...)
FROM
肯定是对结构的警告
SELECT @Var = <expression containing @Var>
FROM