这个 My-SQL 语句有啥问题?

Posted

技术标签:

【中文标题】这个 My-SQL 语句有啥问题?【英文标题】:What is wrong with this My-SQL statement?这个 My-SQL 语句有什么问题? 【发布时间】:2015-08-31 12:35:27 【问题描述】:

声明如下:

IF NOT EXISTS (SELECT * FROM Players WHERE ID = 'Something') BEGIN
    INSERT INTO Players(ID, Msg) VALUES ('Something', 'Custom MSG')
END

错误:

您的 SQL 语法有错误;检查手册 对应于您的 mysql 服务器版本,以便使用正确的语法 靠近第 1 行的IF NOT EXISTS (SELECT * FROM Players WHERE ID = 'Something') BEGIN

预期结果:我想创建一个包含玩家 ID 和模板消息的行/列(不是 100% 确定。)。

编辑:最好的方法是什么?为什么?

【问题讨论】:

我不确定它有什么正确 :-( 您似乎正在尝试在 MySQL 中使用 TSQL 语法 【参考方案1】:

您不能在 MySQL 中的过程或例程之外使用 IF 语句。请改用INSERT IGNOREINSERT .. ON DUPLICATE KEY UPDATE 语句。

INSERT IGNORE INTO Player (ID, Msg)
VALUES 
  ('Something', 'Custom MSG');

INSERT INTO Player (ID, Msg)
VALUES 
  ('Something', 'Custom MSG')
ON DUPLICATE KEY UPDATE
  Msg = Msg; --  or Msg = VALUES(Msg) to update to the new value.

应该在ID 列上定义PRIMARY KEYUNIQUE KEY 才能起作用。

用这个SQL Fiddle检查它

【讨论】:

第二个最适合用户,因为第一个将根据 id 替换其他值.... @ZafarMalik:同意。更改了建议解决方案的顺序。 IGNORE 或 DUPLICATE 最好使用什么,两者有什么区别? 如果你想更新记录,即使它存在,使用DUPLICATE(见最后一行之后的注释)。如果您想在记录存在时忽略插入并且不想触摸现有记录,请使用 IGNORE 问题是我只需要为每个玩家一个 ID,我不想为每个玩家创建多个 ID。【参考方案2】:

一个更好的方法是简单地使用 MySQL 的REPLACE INTO 语法。只需确保您的 ID 字段是主键并将您的查询写为:

REPLACE INTO Players(ID, Msg) VALUES ('Something', 'Custom MSG'); 

如果没有找到行,这将插入,如果找到以前存在的行,则更新,基于主键。 Here你可以找到相关文档。

【讨论】:

发现行时,REPLACE INTO 不是 UPDATE,而是 DELETE 和 INSERT 的组合。请记住这一点。在这种情况下,结果是相似的,但是对于 AI 列,结果会有所不同。请谨慎使用此声明。此外,当在具有引用外键的主键上执行 REPLACE 时,它可能会失败或从另一个表中删除记录!【参考方案3】:

你需要在一个过程中使用它,它以 END IF; 结束

Create procedure proc_name
as
Begin
IF NOT EXISTS (SELECT * FROM Players WHERE ID = 'Something') BEGIN
    INSERT INTO Players(ID, Msg) VALUES ('Something', 'Custom MSG');
END IF;
end;

【讨论】:

这是一个不存在的问题的解决方案。

以上是关于这个 My-SQL 语句有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

这个return语句有啥意义吗?

有啥办法可以优化这个 SQL 语句?

let 块语句和等价的 with 语句有啥区别?

Oracle 语句后加t有啥特殊的含义吗?

SQL里if语句和case语句有啥区别吗?哪个使用更高效?就是查询更优化?

sql语句中嵌套时候用in 和=有啥区别