【问题标题】:Syntax error with IF EXISTS UPDATE ELSE INSERT (NODE JS)IF EXISTS UPDATE ELSE INSERT (NODE JS) 的语法错误
【发布时间】:2022-01-31 13:42:46
【问题描述】:

我正在尝试编写一个 SQL 查询,如果它存在则更新一个条目,如果它不存在则插入一个新条目。 UPDATE ON DUPLICATE KEY 选项不起作用,因为我没有按主键查询。我所指的 SQL 语句在下面的 sql.query() 函数中。我还添加了错误消息。

  Asset.create = (newAsset, result) => {
      sql.query(
        `if exists(SELECT * from asset WHERE 
         AssetId="${newAsset.AssetId}" AND 
         AccountID="${newAsset.AccountId}") BEGIN UPDATE asset set 
         Amount="${newAsset.Amount}" where AssetId="${newAsset.AssetId}" 
         AND AccountID="${newAsset.AccountId}" End else begin INSERT 
         INTO asset SET ? end`,
        newAsset,
        (err, res) => {
          if (err) {
            console.log("error", err);
            result(err, null);
            return;
          }
    
          result(null, { id: res.insertId, ...newAsset });
        }
      );
    };

错误信息:

sqlMessage:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'if exists(SELECT * from asset WHERE AssetId="bitcoin" AND AccountID="2c341fed-cf' at line 1

【问题讨论】:

  • 这样的构造只允许在函数和过程中,并且是不是有效的sql代码

标签: mysql sql database


【解决方案1】:

在 MySQL 中,诸如 BEGIN ... ENDIF ... THEN ... END IF 之类的复合语句语法仅在存储例程中受支持。直接从客户端执行时不能使用此类语句。

https://dev.mysql.com/doc/refman/8.0/en/sql-compound-statements.html 说:

本节介绍 BEGIN ... END 复合语句的语法以及可用于存储程序主体的其他语句:存储过程和函数、触发器和事件。

在您展示的示例中,您似乎正在尝试更新一行,如果该行不存在,则插入它。

如果表上有主键或唯一键,一个解决方案是使用 INSERT ON DUPLICATE KEY UPDATE:

INSERT INTO asset (AssetId, AccountId, Amount) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE Amount = VALUES(Amount);

我假设上面的示例 AssetId 和 AccountId 是主键。

另一种方法是先尝试 UPDATE,然后在回调中检查 result.affectedRows。如果该值为零,请尝试 INSERT。

【讨论】:

  • AssetId 和 AccountId 不是主键,这就是 ON DUPLICATE KEY UPDATE 方法不起作用的原因。但是,您的替代方法效果很好。谢谢你。几天来我一直在努力解决这个问题:)
【解决方案2】:

这不是有效的 sql 代码

在 SQL 中你会写类似的东西

SELECT
if (exists(SELECT * from asset WHERE AssetId="${newAsset.AssetId}" AND AccountID="${newAsset.AccountId}") 
, @sql := 'UPDATE asset set Amount="${newAsset.Amount}" where AssetId="${newAsset.AssetId}" AND AccountID="${newAsset.AccountId}" ',
@sql := 'INSERT INTO asset SET ? ');
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

但这是多查询,必须是eanabled

它还需要一些工作,因为你有很多报价

【讨论】:

    猜你喜欢
    • 2012-09-08
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 2013-11-26
    • 2017-09-09
    相关资源
    最近更新 更多