[英]Preventing duplicates in an SQL query?
如果其中一个字段与其他字段之一重复,则插入新记录以使其失败时,是否有一种简便的方法?
我不希望该字段成为主键或类似的主键...
正如hgulyan所说,如果您希望table.col1是唯一的,请在该列上添加唯一约束。
如果您的意思是希望在列table1.col1 = table1.col2时插入操作失败,则可以在触发器中实现此操作。 请参见MYSQL创建触发器 。
要在触发器中引发异常,以使插入失败,请参阅导致INSERT失败的TRIGGER? 可能?
就像是:
CREATE TRIGGER Employee_beforeinsert before insert
ON Employee FOR EACH ROW
BEGIN
IF new.age = new.age2 THEN
DECLARE dummy INT;
SELECT 'Your meaningful error message goes here' INTO dummy
FROM Employee
WHERE Employee.id=new.id
END IF;
END;
以下是标准SQL,而不是mySQL方言,但是mySQL与Standard的合规性很高,我相信您应该能够理解我的观点。
您没有发布架构或示例数据,因此我不得不猜测您的表可能是什么样的:
CREATE TABLE Mothers
(
mother_ID INTEGER NOT NULL UNIQUE
);
CREATE TABLE Children
(
child_ID INTEGER NOT NULL UNIQUE
);
CREATE TABLE MothersOfTwins
(
mother_ID INTEGER NOT NULL
UNIQUE REFERENCES Mothers (mother_ID),
twin_1_child_ID INTEGER
REFERENCES Children (child_ID),
twin_2_child_ID INTEGER
REFERENCES Children (child_ID),
CHECK (twin_1_child_ID <> twin_2_child_ID)
);
INSERT INTO Mothers (mother_ID) VALUES (101), (102), (103);
INSERT INTO Children (child_ID) VALUES (551), (552), (553), (554);
INSERT INTO MothersOfTwins (mother_ID, twin_1_child_ID, twin_2_child_ID)
VALUES
(101, 551, 552),
(102, 552, 551); -- duplicate
最后一个INSERT
成功,即使它失败了,即在行之间转换child_ID值也将使您想放在列上的所有UNIQUE
约束都蒙混了。 我想这与您面临的问题类似。
解决此问题的一种方法是创建一个基表,该基表需要使用多行来对同级进行建模,使用带有约束条件的“出现”列来确保不超过两个同级(即双胞胎):
DROP TABLE MothersOfTwins;
CREATE TABLE MothersOfTwinsBase
(
mother_ID INTEGER NOT NULL
REFERENCES Mothers (mother_ID),
twin_occurrence INTEGER NOT NULL
CHECK (twin_occurrence BETWEEN 1 AND 2),
twin_child_ID INTEGER NOT NULL UNIQUE
REFERENCES Children (child_ID),
UNIQUE (mother_ID, twin_occurrence)
);
INSERT INTO MothersOfTwinsBase (mother_ID, twin_occurrence, twin_child_ID)
VALUES
(101, 1, 551),
(101, 2, 552),
(102, 1, 553),
(103, 2, 554);
然后,您可以使用VIEW
重新创建以前的基表的数据结构
CREATE VIEW MothersOfTwins
(
mother_ID,
twin_1_child_ID, twin_2_child_ID
)
AS
SELECT M1.mother_ID,
M1.twin_child_ID AS twin_1_child_ID,
M2.twin_child_ID AS twin_2_child_ID
FROM MothersOfTwinsBase AS M1
INNER JOIN MothersOfTwinsBase AS M2
ON M1.mother_ID = M2.mother_ID
AND M1.twin_occurrence = 1
AND M2.twin_occurrence = 2
UNION ALL
SELECT M1.mother_ID,
M1.twin_child_ID AS twin_1_child_ID,
NULL AS twin_2_child_ID
FROM MothersOfTwinsBase AS M1
WHERE NOT EXISTS (
SELECT *
FROM MothersOfTwinsBase AS M2
WHERE M1.mother_ID = M2.mother_ID
AND M2.twin_occurrence = 2
)
UNION ALL
SELECT M2.mother_ID,
NULL AS twin_1_child_ID,
M2.twin_child_ID AS twin_2_child_ID
FROM MothersOfTwinsBase AS M2
WHERE NOT EXISTS (
SELECT *
FROM MothersOfTwinsBase AS M1
WHERE M1.mother_ID = M2.mother_ID
AND M1.twin_occurrence = 1
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.