【问题标题】:MySQL Procedure check if record exists before insert not workingMySQL程序在插入不起作用之前检查记录是否存在
【发布时间】:2012-08-24 18:34:05
【问题描述】:

我已经查看了有关此问题的其他问题。它不工作。

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `environment_admin`(
IN environment_id   TEXT,
IN user_id          TEXT,
IN username         VARCHAR(75),
IN password         VARCHAR(512)
)
BEGIN
DECLARE env_id INT;
DECLARE admin_id INT;

SET env_id = CAST(environment_id AS SIGNED INT);
SET admin_id = CAST(user_id AS SIGNED INT);

IF NOT EXISTS(SELECT 1 FROM `environment`.`environment_accounts` WHERE environment_id = env_id AND user_id = admin_id) THEN
    BEGIN
    INSERT INTO 
        `environment`.`environment_accounts` 
        (
            `environment_id`, 
            `user_id`, 
            `username`, 
            `password`, 
            `is_active`, 
            `is_admin`, 
            `is_mod`
        ) 
        VALUES 
        (
            env_id, 
            admin_id,
            username,
            password,
            1,
            1,
            1
        );
    END;
END IF;
END

所以如果我运行:

CALL `environment`.`environment_admin`('22','1','kacieh','512c9ad228332bbd30d09ce7ffb8896e00a1610e914a5fa180bf15ce702b90423e6a9540579f672315ae3c6cb1b8d06ee2b784b4761e806675aa88c2a915553e');

我得到 0 行影响 果然,什么也没发生。 -_- 我一直在这个时间工作 我测试了条件查询,它有效。 我只测试了存储过程中的插入语句,它也可以工作。

【问题讨论】:

    标签: mysql stored-procedures insert exists not-exists


    【解决方案1】:

    别再那样做了,效率低下,如果两个插入同时运行,情况可能会更糟! :)

    使用 INSERT.... 在重复密钥更新时 ... see here

    一个技巧是执行 ON DUPLICATE KEY UPDATE environment_id = env_id (不更改列,因此不会更新任何内容,确保 INSERT 不会在没有任何错误条件的情况下工作,之后您可以检查修改/插入的行数)

    【讨论】:

    • 但可以有许多相同的 environment_id 和许多 user_id,这是多对多的关系。但是不会有相同的 environment_id user_id 组合。我没有把这对做成 pk,因为我有其他要求,需要这些记录有一个唯一的 ID
    • 如果我对这两个字段的组合有唯一索引,这应该可以工作。我得看看我有没有那个或者把那个放进去。给我几个
    • 在环境中创建唯一索引 IX_environment_id_user (environment_id, user_id);
    • 是的,我已经创建了索引,这好多了,好多了,非常感谢
    【解决方案2】:

    我知道你已经解决了你的问题(并为 Parallelis 的回答 +1,特别是在突出并发问题时),但以防万一它对其他人有帮助......

    MySQL 可能在您的参数 environment_iduser_id 以及 environment_accountsenvironment_iduser_id 之间感到困惑。我怀疑WHERE 子句中的参数优先,这意味着只要environment_accounts 中至少有一行,NOT EXISTS 子句将始终返回 false,并且您的插入永远不会运行。

    例如,如果您的 environment_iduser_id 参数的值分别为 1 和 2,则 NOT EXISTS 子句的计算结果为

    IF NOT EXISTS(SELECT 1 FROM `environment`.`environment_accounts` WHERE 1 = 1 AND 2 = 2) THEN
    

    可能值得为参数(和其他变量)制定命名约定,例如为参数添加 p_ 之类的前缀。

    【讨论】:

      猜你喜欢
      • 2012-03-06
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-18
      • 1970-01-01
      相关资源
      最近更新 更多