0

我有这个表,col1 col2 col3,col1是主键,现在我想为col2和col3添加唯一约束,我使用alter table add constraint,但是表中似乎已经有重复的记录,所以我必须删除它们以使其工作,但是,如果我需要保留所有现有记录,我如何确保新添加的记录在 col2 和 col3 中是唯一约束?

4

2 回答 2

1

如果我理解正确,您想保留当前的重复项,但要确保不添加任何新的重复项,对吗?就我个人而言,我会遵循上面的评论,但我理解这是否不能满足您的业务需求。

不幸的是,约束不能满足您描述的需求。您可能希望控制插入数据的软件中的重复逻辑,而不是在表级别。例如,如果表中尚不存在 val3,则以下内容只会添加该行。说得通?

INSERT INTO MyTable (col1, col2, col3, col4)
VALUES (val1, val2, val3, val4) WHERE NOT col3 = val3;

或者您可以触发 INSTEAD OF 触发器。SQL 有一个特殊的临时“插入”表,您可以在输入值之前与它进行比较。所以您说,“插入这些值,但等等!仅当临时“插入”表中的行与 MyTable 中的现有行不匹配时才插入它们。”

CREATE TRIGGER no_duplicates_in_MyTable ON MyTable
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON
IF (NOT EXISTS (SELECT M.val3
      FROM MyTable M, inserted I
      WHERE M.val3 = I.val3))
   INSERT INTO MyTable
      SELECT val1, val2, val3, val4
      FROM inserted
END

或者,您可以使用 AFTER INSERT 触发器在表级别处理逻辑,但这有点不稳定。在某些情况下,您可以删除现有的重复项。像这样的东西;

CREATE TRIGGER delete_duplicates_MyTable
AFTER INSERT ON MyTable
BEGIN
   DELETE FROM MyTable 
   WHERE val3 NOT IN (SELECT MIN(val3) 
                             FROM MyTable 
                             WHERE val1 = new. val1)
   AND val1 = new. val1;
END;

如果您有任何问题或这不符合您的业务需求,请告诉我。

编辑:@Rik 是正确的,这些是 INSERT 触发器,因此它们不适用于更新,允许任何人的代码将值更改为重复项。尝试更新触发器。您可以随意使用这些将 INSERT 更改为 UPDATE。

于 2013-07-17T22:26:33.873 回答
0

就我个人而言,我会同意其他人的评论。您应该真正修复数据,然后添加约束。

然而,仅仅为了它,一个可能的解决方案可能是使用 MERGE 引擎。基本上,您会将您现在拥有的数据保存在一个表中,并创建一个几乎相同的第二个表。唯一不同的是,这次索引是唯一的。

看这个例子:

CREATE TABLE t1 (
   a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   message CHAR(20),
   key whatever (message)
   ) ENGINE=MyISAM;

CREATE TABLE t2 (
   a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   message CHAR(20),
   unique key whatever (message)
   ) ENGINE=MyISAM;

INSERT INTO t1 (message) VALUES ('Testing'),('Testing'),('t1');
INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');

CREATE TABLE total (
   a INT NOT NULL AUTO_INCREMENT,
   message CHAR(20), INDEX(a))
   ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;

select * from total; 
/*Here you can see, that there are duplicate values*/

insert into total (message) values ('Testing');
/*but this results in a duplicate key error*/

insert into total (message) values ('it work\'s');
/*whereas this doesn't*/

在此处阅读有关 MERGE 引擎的更多信息。

于 2013-07-17T22:28:42.293 回答