微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQL UPDATE案例

如何解决SQL UPDATE案例

我知道我的sql知识很薄弱。不幸的是,我发现自己所知道的比我以前所想的要少。

我写了一个UPDATE命令,可以在使用表单的简单HTML设置页面中使用。 (在表单数据到达UPDATE sql之前,对表单数据进行了一些浏览器端验证和服务器端验证。)

我的目标是更新2行中的1列。没有其他的。但是我错了。它使用期望的值更新了两个目标行。 sqlNULL列了所有其他行中所有值的列。

我的问题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)。

解决方法

编辑:2020-10-07

对于最新注释,如果要减少UPDATE的数量,尤其是当它不更改值但仍导致写入时,可以使用CTE仅过滤需要更新的行然后与那些人一起工作。

<cfquery datasource="OurDBLocation" name="changeValues">
; WITH cte AS (
    SELECT rowvalueB
    FROM sometable
    WHERE rowvalueA = 'A123'
        OR ( rowvalueA = 'A456' AND rowvalueB = 'A456' )
)
UPDATE cte
SET rowvalueB =
        CASE
            WHEN rowvalueA = 'A123' THEN <cfqueryparam value="#val(FORM.a123value)#" cfsqltype="cf_sql_integer">
            ELSE <cfqueryparam value="#val(FORM.a456value)#" cfsqltype="cf_sql_integer">
        END
    OUTPUT INSERTED.*
;
</cfquery>

CTE UPDATE非常棒,如果可以按照您的SQL风格使用它们(并且通过标记tsql,我猜您是SQL Server)。测试它以确保它适合您的情况。我不知道为什么cfquery无法正确运行CTE UPDATE,但是我现在无法对其进行测试。

解释正在发生的事情: ;WITH cte AS..创建命名的CTE数据集。另请参见https://www.sqlshack.com/sql-server-common-table-expressions-cte/ SELECT...定义构成CTE的数据。由于您要过滤rowvalueA IN (A123,A456),然后更新不同的值,因此我简化了WHERE语句。当FORM.a456rowvalueB都等于'A456'时,您只会更新rowvalueA值。因此,CTE会过滤掉rowvalueA=A456rowvalueBA456以外的所有行。这些将是最初重置为NULL的记录。 然后,使用普通的UPDATE语句更新CTE,这将通过管道传输到表中的实际行。由于您仍在更新中使用条件值,因此我们必须使用CASE...WHEN...,但行已被过滤和简化。我们只需要检查rowvalueA=A123

还要注意,当我提到客户端验证时,我并不是说不这样做。我只是指出,绕过客户端验证很简单,因此不应依赖于任何形式的验证,这些验证除了用于客户端显示或易于使用之外,还用于其他任何用途。

==========原始答案=====================

如果我正确理解您的意图,则您的查询似乎大部分是正确的。您只更新表中的rowdataB。但是,如果不满足您的WHEN条件,则不会提供默认值,因此将NULL分配给它。

<cfquery datasource="OurDBLocation" name="changeValues">
    UPDATE sometable
    SET rowvalueB = 
        CASE
            WHEN rowvalueA = 'A123' THEN <cfqueryparam value="#val(FORM.a123value)#" cfsqltype="cf_sql_integer">
            WHEN rowvalueB = 'A456' THEN <cfqueryparam value="#val(FORM.a456value)#" cfsqltype="cf_sql_integer">
            ELSE rowvalueB
        END
    OUTPUT INSERTED.*
    WHERE rowvalueA IN ('A123','A456')
</cfquery>

如果您的rowvalueB中的WHEN条件都不满足,这只会将CASE的值重新分配给它自己。由于存在WHERE子句,它将忽略任何其他行。

认为如果OUTPUT INSERTED.*rowvalueA,这可能会将行添加到您的'A456',因为它将在您的WHERE子句中匹配,但是不在您的WHEN子句中。如果您不打算这样做,则可能要更改WHERE

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。