【发布时间】:2020-10-07 23:02:16
【问题描述】:
我知道我的 SQL 知识很薄弱。不幸的是,我发现我知道的比我以前想象的要少。
我编写了一个UPDATE 命令,用于使用表单的简单 HTML 设置页面。 (在数据到达 UPDATE SQL 之前,有一些浏览器端验证和更多服务器端验证表单数据)。
我的目标是更新 2 行中的 1 列。没有其他的。但是我错了。它用预期的值更新了两个目标行。 SQL 还NULLed 所有其他行中所有值的列。
我的问题 1:是什么导致我的 SQL 出现这种情况? 我的问题 2:有没有更好的方法来执行此更新?
<cfquery datasource="OurDBLocation" name="changeValues">
UPDATE sometable
SET rowvalueB = CASE
WHEN rowvalueA = 'A123' THEN #val(FORM.a123value)#
WHEN rowvalueB = 'A456' THEN #val(FORM.a456value)#
END
OUTPUT INSERTED.*
WHERE rowvalueA IN ('A123','A456')
</cfquery>
注意:这是一种内部表单,只有对我们的代码库有 VPN 访问权限的开发人员才能访问。对于不懂#val(FORM.a123value)#的人,我们在后端使用Lucee(又名ColdFusion)
【问题讨论】:
-
“SQL 还清空了所有其他行中所有值的列。” 上面只会更新
rowvalueA的值的行'A123'或'A456',没有 其他人。但是请注意,在您的CASE中,您首先检查rowvalueA,然后检查rowvalueB,因此除非rowvalueA和rowvalueB的值都为'A456',否则任何行其中rowvalueA的值为'A456'将更新为NULL,因为CASE表达式中没有ELSE。我“闻到”印刷错误。rowvalueArowvalueB. -
对于
#val(FORM.a123value)#等用户输入,您应该始终使用cfqueryparam。 -
在您的
UPDATE中,添加一个默认条件:CASE... WHEN .... THEN.... ELSE rowvalueB END。这将阻止该值更新为NULL。但我相信它也会像您的OUTPUT中的INSERTED记录一样,因为该行已更新。 -
@Larnu 谢谢。唯一的可能是我在测试中运行了一次上述语句,它不包括
END条件。排除END条件是否会导致其余数据库记录为NULLed? -
@RRK。谢谢你。如前所述
(There is some browser side validation and also more server side validation of the form data before the data reaches the UPDATE SQL).该公司不相信cfqueryparam。 IDK 为什么,他们就是不这样做。无论哪种方式,我都同意你的看法。
标签: sql tsql coldfusion lucee