将行插入表A后,我需要触发器将一些值插入到另一个表B中,但前提是表B尚未包含具有此类值组合的行。所以这就是我想出来的:
CREATE TRIGGER upd_manufactorer_in_category AFTER INSERT ON product
FOR EACH ROW
BEGIN
DECLARE id_category INT;
DECLARE id_manufacturer INT;
DECLARE id_category_test INT;
SET id_category=NEW.id_category;
SET id_manufacturer=NEW.id_manufacturer;
SET id_category_test=(SELECT 'id_category'
FROM category_has_manufacturer
WHERE 'id_category'=id_category
AND 'id_manufacturer'=id_manufacturer);
IF id_category_test IS NULL
THEN
INSERT INTO category_has_manufacturer
SET category_has_manufacturer.id_category = id_category,
category_has_manufacturer.id_manufacturer = id_manufacturer;
END IF;
END
它有效,它会在表格中插入行。但它没有检查它是否存在,所以我有很多重复。当然我可以用DISTICT来查询,但这不是我想要在这里实现的。我想要一个只有唯一(id_category,id_manufacturer)对的表。有人能帮助我吗?
答案 0 :(得分:1)
你可以做的两件事都会有所帮助。
首先在Devart建议的表格中添加一个唯一的索引/键。
第二件事是,这是一个很好的地方,你可以使用左右连接来获取不存在的数据。我将向您展示理论,然后您可以将它作为练习应用于您的答案。
第1步:
创建一个名为test的数据库。
第2步:
在新创建的测试数据库中运行以下两个create table脚本:
CREATE TABLE `test`.`category_has_manufacturer_A`
(
`id_category` INT NOT NULL ,
`id_manufacturer` INT NOT NULL ,
PRIMARY KEY (
`id_category`,
`id_manufacturer`
)
);
CREATE TABLE `test`.`category_has_manufacturer_B`
(
`id_category` INT NOT NULL ,
`id_manufacturer` INT NOT NULL ,
PRIMARY KEY (
`id_category`,
`id_manufacturer`
)
);
是的,所以我们两个表有一个共同的列,我们可以加入。
第3步:
将一些数据添加到category_has_manufacturer_a表
INSERT INTO `test`.`category_has_manufacturer_a`
(
`id_category`,
`id_manufacturer`
)
VALUES
(
1,
1
);
酷,所以表A 有一些我们想要添加到表B的数据。
第4步:
让我们在两个表上进行内连接,然后查看结果运行以下查询。
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
INNER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
很好,所以没有返回数据,因为表A 和表B 中的行之间没有直接匹配,这是因为仅内部连接返回与JOIN条件匹配的行。
第5步:
OUTER JOINS的力量透露出来。 OUTER连接将返回数据,即使它们不匹配。在这种情况下,我们将在表A 和表B 上进行LEFT OUTER JOIN。由于表A 是 LEFT 表,我们要求返回表A 中的所有数据,即使它们与表中的任何内容都不匹配乙。运行以下查询。
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
这将返回一个如下所示的记录集:
A_ID_CATEGORY|A_ID_MANAFACTURER|B_ID_CATEGORY|B_ID_MANAFACTURER|
1| 1| | |
此结果清楚地表明表A 中的行与表B 中的行不匹配。
第6步:
现在我们可以使用步骤5中的SELECT语句创建一个INSERT语句来插入不存在的这些行。运行以下查询:
INSERT INTO category_has_manufacturer_b
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
让我们检查插件执行以下查询的内容:
SELECT
`category_has_manufacturer_b`.`id_category`,
`category_has_manufacturer_b`.`id_manufacturer`
FROM `test`.`category_has_manufacturer_b`;
您将看到一个结果集,其中表A 中的行现已插入表B 。
第7步:
在这里,我们添加最后一点和多个部分,确保我们只将表A 中的新行添加到表B 。首先,我们添加更多数据。运行以下查询:
INSERT INTO `test`.`category_has_manufacturer_a`
(
`id_category`,
`id_manufacturer`
)
VALUES
(
1,
2
);
现在再次使用左连接运行查询:
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
您将看到一个结果集,其中包含两个表中匹配的行和表a中的新行。如果您现在运行插入,则会插入两行并具有主键冲突,或者在您的情况下是重复的行。
如果您将上述查询更改为以下内容并运行它:
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
WHERE B.`id_category` IS NULL AND B.`id_manufacturer` IS NULL
记录集将仅包含表A 中的新记录。
将insert语句更改为:
INSERT INTO category_has_manufacturer_b
SELECT
A.`id_category` AS A_ID_CATEGORY,
A.`id_manufacturer` AS A_ID_MANAFACTURER,
B.`id_category` AS B_ID_CATEGORY,
B.`id_manufacturer` AS B_ID_MANAFACTURER
FROM category_has_manufacturer_a A
LEFT OUTER JOIN category_has_manufacturer_b B
ON A.`id_category` =B.`id_category`
AND A.`id_manufacturer`=B.`id_manufacturer`
WHERE B.`id_category` IS NULL AND B.`id_manufacturer` IS NULL
当您运行此INSERT时,它只会将表A 中的新行插入表B 。
要点: LEFT和RIGHT JOIN语句可用于将两个表进行比较,并仅从一个表中返回新行。如果行是新的,当尝试从一个表添加到另一个表时,这是一种很好的技术。它可以同时在一行和多行上工作,因为它是基于它设置的(SQL很擅长)它非常快。
我希望您了解正在发生的事情并将其应用于您的触发器中。
提示: 在触发器中,您可以访问NEW表,您可以加入此表以确定新行。
玩得开心!