如果满足条件,则插入INTO

时间:2014-09-13 19:52:03

标签: mysql

用户只能在任何时间在其帐户中注册最多3个密钥。要添加新密钥,用户必须先删除另一个密钥才能“腾出空间”#34;换一个新的。

我希望在服务器端检查这个,但我无法让查询生效。这是我试过的:

IF (SELECT COUNT(serial_key_nbr)
FROM keys_table WHERE user_id = 9) <= 2
THEN INSERT INTO keys_table (user_id, serial_key_nbr)
VALUES (9, 'abc123')

怎么做?

3 个答案:

答案 0 :(得分:3)

您可以使用下面提到的脚本:

INSERT INTO keys_table (user_id, serial_key_nbr)
SELECT 9, 'abc123'        FROM DUAL
WHERE 
(SELECT COUNT(serial_key_nbr)
FROM keys_table WHERE user_id = 9)<=2

答案 1 :(得分:2)

如果你想使用if进行条件选择,那么我会把它放在一个像这样的变量中。

BEGIN

    DECLARE var1 INT;

    SELECT COUNT(serial_key_nbr) INTO var1
    FROM keys_table 
    WHERE user_id = 9;

    IF var1 <= 2 
    THEN
      INSERT INTO keys_table (user_id, serial_key_nbr)
      VALUES (9, 'abc123')

    END IF;

答案 2 :(得分:2)

触发器可能是要走的路。如果满足条件,则在插入表之前触发可执行无效操作并导致插入操作失败:

delimiter $$
create trigger keep_three before insert on keys_table for each row
begin
    if (select count(serial_key_nbr) from keys_table where user_id = new.user_id) >= 3 then
        insert into non_existent_table (non_existent_field) values (new.user_id);
    end if;
end$$
delimiter ;

丑陋,但它可能有用。

参考:


另一个解决方案(我认为更好)是在注册插入之前强制删除条目。当少于3个条目时,插入正常进行:

delimiter $$
create trigger keep_three before insert on keys_table for each row
begin
    while (select count(serial_key_nbr) from keys_table where user_id = new.user_id) >= 3 do
        delete from keys_table where user_id = new.user_id 
        -- OPTIONAL: Add an ordering criteria to define which entry is deleted first
        limit 1;
    end while;
end$$
delimiter ;

我认为这更清洁。


第三种方式(我发现它here)。它将返回与定义的条件相关联的错误消息(通过信令sqlstate 45000:未处理的用户定义的异常):

delimiter $$
create trigger keep_three before insert on keys table for each row
begin
    declare msg varchar(255);
    declare n int default 0;
    set n = (select count(serial_key_nbr) from keys_table where user_id = new.user_id);
    if n >= 3 then
        set msg = "INSERT failed: There must be only three entries for each user. Delete an entry first";
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
    end if;
end$$
delimiter ;

我的第一个选项的清洁版。