整个mysql表上的唯一键?

atl*_*lau 6 mysql unique-key mysql-error-1054

假设我有一个包含两列的mysql表:A和B.是否可以使用唯一键,这样我只能在A或B中插入一次值(整个表中只有一次)?

因此,如果列A包含'qwe'而B包含'asd',那么这两个值就不能再插入任何列中.

这不起作用:

UNIQUE KEY `A` (`A`,`B`),
UNIQUE KEY `A_2` (`A`),
UNIQUE KEY `B` (`B`),
UNIQUE KEY `B_2` (`B`,`A`)
Run Code Online (Sandbox Code Playgroud)

谢谢.

编辑:我能够使用以下触发器完成此操作:

delimiter |
create trigger unique_check before insert on mytable
       for each row begin
              declare alreadyexists integer;
          select count(*) > 0 into alreadyexists from mytable
                 where A=NEW.B or B=NEW.A;
          IF alreadyexists = 1 THEN begin
             DECLARE dummy INT;
         SELECT 'A OR B already exists' INTO dummy FROM mytable
            WHERE nonexistent = 'value';
 end;
 END IF;
 END;|
Run Code Online (Sandbox Code Playgroud)

但是,我没有看到"A OR B已存在"错误消息,但是:

ERROR 1054(42S22):'where子句'中的未知列'不存在'

再次感谢!

Pen*_*m10 2

是的,这是可能的。

\n\n

1 种方式是

\n\n

您需要创建一个BEFORE INSERT触发器,如果​​该值已在其他列/表中找到,则返回错误。

\n\n

来自这篇博文

\n\n
\n

MySQL 触发器:如何使用\n 触发器中止 INSERT、UPDATE 或 DELETE?在 EfNet\xe2\x80\x99s #mysql 上有人问:

\n\n

如果我的业务规则失败,如何使触发器中止操作?

\n\n

在 MySQL 5.0 和 5.1 中,您需要采取一些技巧来使触发器失败并传递有意义的错误消息。MySQL 存储过程常见问题解答提到了有关错误处理的内容:

\n\n

SP 11. SP 是否有 \xe2\x80\x9craise\xe2\x80\x9d 语句来\xe2\x80\x9craise 应用程序错误\xe2\x80\x9d?抱歉,目前没有。SQL 标准 SIGNAL 和 RESIGNAL 语句位于 TODO 上。

\n\n

也许 MySQL 5.2 将包含 SIGNAL\n 语句,这将使直接从 MySQL 存储过程编程中窃取的这个 hack 过时。黑客攻击是什么?您\xe2\x80\x99 将强制\n MySQL 尝试使用\n 不存在的列。丑陋的?是的。它有效吗?当然。

\n\n
CREATE TRIGGER mytabletriggerexample\nBEFORE INSERT\nFOR EACH ROW BEGIN\nIF(NEW.important_value) < (fancy * dancy * calculation) THEN\n    DECLARE dummy INT;\n\n    SELECT Your meaningful error message goes here INTO dummy \n        FROM mytable\n      WHERE mytable.id=new.id\nEND IF; END;\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

其他方式

\n\n

你也可以这样做Transactions

\n\n

使用带有事务的过程将数据插入事务表(InnoDB),

\n\n

在触发器中写入错误条件:

\n\n
set @error=1; \n
Run Code Online (Sandbox Code Playgroud)\n\n

在程序中是这样的:

\n\n
set @error=0; \nstart transaction \ndo insert \nif @error>0 then rollback; \nelse commit; \n
Run Code Online (Sandbox Code Playgroud)\n