SQL如何在一个命令中为int列增加或减少一个


119

我有一个包含数量列的订单表。在签入或签出期间,我们需要将该数量列更新一个。有一种方法可以一次执行此操作,还是我们必须获取现有值,然后在其顶部加上或减去一个值?

另一个问题是,当我们插入新行时,是否需要检查是否存在相同的数据,然后是否插入,这是两个步骤,还是有更好的方法呢?

谢谢,

Answers:


250

首先回答:

UPDATE Orders SET Quantity = Quantity + 1 WHERE ...

回答第二个问题:

有几种方法可以做到这一点。由于您未指定数据库,因此假设使用MySQL。

  1. INSERT INTO table SET x=1, y=2 ON DUPLICATE KEY UPDATE x=x+1, y=y+2
  2. REPLACE INTO table SET x=1, y=2

他们俩都可以解决您的问题。但是,第一种语法允许更灵活地更新记录,而不仅仅是替换它(如第二种一样)。

请记住,要使两者同时存在,必须定义一个唯一键。


32
由于未指定数据库,因此您应该真正采用标准SQL。
paxdiablo

12

第一个问题的单步答案是使用类似以下内容的方法:

update TBL set CLM = CLM + 1 where key = 'KEY'

那完全是一种单一指令的方式。

至于第二个问题,您不必求助于DBMS特定的SQL体操(例如UPSERT)来获得所需的结果。有一种执行更新或插入操作的标准方法,不需要特定的DBMS。

try:
    insert into TBL (key,val) values ('xyz',0)
catch:
    do nothing
update TBL set val = val + 1 where key = 'xyz'

也就是说,您尝试首先进行创建。如果已经存在,请忽略该错误。否则,将其创建为0值。

然后执行无论是否可以正常运行的更新:

  • 该行最初存在。
  • 有人在您插入和更新之间更新了它。

这不是一条指令,但令人惊讶的是,这是我们长期以来一直成功完成的方式。


4

如果我的理解是正确的,则更新应该非常简单。我只会做以下事情。

UPDATE TABLE SET QUANTITY = QUANTITY + 1 and
UPDATE TABLE SET QUANTITY = QUANTITY - 1 where QUANTITY > 0

您可能需要其他过滤器来仅更新一行而不是所有行。

对于插入,您可以在本地缓存一些与记录相关的唯一ID,并对照此缓存进行检查并决定是否插入。另一种方法是始终插入并检查PK违反错误,然后忽略,因为这是多余的插入。


4
UPDATE Orders Order
SET Order.Quantity =  Order.Quantity - 1
WHERE SomeCondition(Order)

据我所知,SQL没有对INSERT-OR-UPDATE的内置支持。我建议创建一个存储过程或使用条件查询来实现此目的。在这里,您可以找到针对不同数据库的解决方案集合。


您可能会收到这样的语法错误:像这样抛出保留字ORDER
gahooa

0

回答第二个问题:

使该列唯一,并在设置为相同值时捕获异常。


0

@dotjoe更新和检查@@ rowcount便宜,然后在事实之后进行插入。

异常代价高昂&&更新更加频繁

建议:如果要在DAL中表现出色,请在前端插入要更新的行的唯一ID(如果为null)。

DAL应该是CRUD,而不必担心无状态。

如果将其设置为无状态,则在具有良好索引的情况下,使用以下SQL vs 1语句不会看到差异。IF(选择顶部1 *表格x,其中PK = @ ID)插入else更新

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.