如果EXISTS MySQL

时间:2015-01-30 11:48:50

标签: php mysql

我来自mssql背景,所以很难习惯MySQL。

我有一张名为users_settings的表格。在此表中有三列; uidnamevalueUid是一个整数,指的是拥有该设置的用户,name是设置的名称,value,嗯,您猜对了,是值。

我要做的是更新这些设置(如果已存在),但如果不存在,请插入新行。

我当前的查询是这样的(注意我正在使用预准备语句):

IF EXISTS (SELECT * FROM users_settings WHERE name = ? AND uid = ?) THEN
                UPDATE users_settings SET value = ? WHERE name = ? AND uid = ?;
            ELSE
                INSERT INTO users_settings (uid, name, value) VALUES (?, ?, ?);
            END IF;

我遇到的问题是,当我尝试准备我的语句时,它返回false,因此表明语法不正确。在查看之后,看起来这是一个SQL语法错误。

是否有人能够指出我在这里可能发生的事情的相对方向,以及我的语法可能不正确的地方?

3 个答案:

答案 0 :(得分:3)

在MySQL中,if作为语句只能用于编程块 - 存储过程,函数和触发器(这不能与if混淆为函数,可以使用几乎所有SQL语句中都有。)

您可以使用单个语句insert . . . on duplicate key update在MySQL中执行您想要的操作。为此,您需要nameuid上的唯一索引:

create unique index users_settings_name_uid on users_settings(name, uid);

然后:

INSERT INTO users_settings (uid, name, value)
    VALUES (?, ?, ?)
    ON DUPLICATE KEY UPDATE value = VALUES(value);

答案 1 :(得分:2)

有两种方法可以在MySQL中完成您的请求:

  1. 如果您想要更新现有行或插入新行但不存在,那么您应该使用INSERT ... ON DUPLICATE KEY UPDATE

    INSERT INTO users_settings (uid, `name`, `value`)
    VALUES (?, ?, ?)
    ON DUPLICATE KEY UPDATE `value` = VALUES(`value`);
    

    这依赖于包含列uidname的唯一索引。如果它尚不存在,您可以创建它:

    ALTER TABLE users_settings
    ADD UNIQUE INDEX uid_name (uid, `name`);
    

    无论如何你需要它,因为你想在表格中为每个用户和设置名称添加一个条目。

  2. 如果要在表格中插入一行并替换(丢弃)已存在的另一行,则可以使用REPLACE

    REPLACE INTO users_settings (uid, `name`, `value`)
    VALUES (?, ?, ?);
    

    REPLACE的语法类似于INSERT的语法(但由于显而易见的原因,它不支持ON DUPLICATE KEY UPDATE)。在内部,它会DELETE后跟INSERT(它只是一个快捷方式)。它会丢弃现有行(如果有)并插入新行。它还依赖于上述索引的存在(无论您如何更新表中的值,都可以使用它。)

  3. 对于您的情况,两种方法都有相同的结果,因为有一个列(value)被更新或替换。在其他情况下,只有其中一个是好的。

    选择您认为更适合您的工作流程和编码风格的那个。

答案 2 :(得分:-1)

INSERT INTO persona_opcion(nPerCodigo,nOpcCodigo,nPerOpcEstado)
    SELECT '$codPer','$idOpc',1 
    FROM persona_opcion 
    WHERE NOT EXISTS(
       SELECT nPerCodigo,nOpcCodigo,nPerOpcEstado 
       FROM persona_opcion 
       WHERE nOpcCodigo='$idOpc' 
       and nPerCodigo='$codPer'
    )
    LIMIT 1;

enter link description here