作为我想要运行的MERGE
查询的一部分,我想在运行时断言某个条件成立。当MERGE
找到 -match 时,我想更新某个列并执行以下逻辑:
- 如果目标列是
NULL
,则写入源值 - 如果目标是
NOT NULL
,则断言目标和源是相同的
我希望在案例 2 中这两个值总是相同的,但我可能犯了一个错误(有一个错误)。发生这种情况时,我想使语句崩溃并让我的应用程序报告错误。这是一种非常罕见的错误情况,不会作为常规处理的一部分发生。
所以我在想我可以滥用除零异常来触发崩溃:
MERGE
...
WHEN MATCHED BY TARGET THEN UPDATE SET
TargetCol = CASE
WHEN TargetCol IS NULL THEN SourceCol
WHEN TargetCol = SourceCol THEN SourceCol
ELSE 0/0 END --crash!
这会可靠地工作吗?有理由不这样做吗?
答案取决于您需要的保证强度。过去有围绕
CASE
评估顺序的错误,例如常量折叠产生错误的表达式。我知道 SQL Server 2014 中当前没有错误会影响您的查询,但这并不意味着它们将来可能不会发生。这当然是任何代码的风险,但我的评估是,将此技术与
MERGE
. Merge 的实现很复杂,如您所知,过去有很多相关的错误。就个人而言,我希望避免将除以零作为解决方案的一部分。更好的选择可能是尝试写入一个违反
CHECK
目标表上的显式(或其他)约束的值。这将导致执行计划中的显式 Assert 运算符位于 Merge 运算符之后。添加这样的约束可能是不可取的(如果允许该列保存其类型域中的所有值,甚至是可能的),但这是需要考虑的一件事。另一项一般性建议:避免在值匹配时更新目标列。这在逻辑上是无操作的,但这并不总是在物理上转化。