我有两个表:orders和orders_items。两者都共享字段orderID。
我想删除orderID = 500的两个表中的所有行,但我只需要在一个查询中执行此操作。这可能吗?
答案 0 :(得分:10)
当然你可以这样做:
DELETE FROM `table1`, `table2` WHERE `orderId` = 500
请参阅http://dev.mysql.com/doc/refman/5.0/en/delete.html
[编辑:
这是一个完整的伎俩:
DELETE FROM `orders`, `orders_items`
USING `orders`
INNER JOIN `orders_items` ON `orders`.`orderId` = `orders_items`.`orderId`
WHERE `orders`.`orderId`= 500
如果orderId是varchar,则将语句更改为= '500'
。
答案 1 :(得分:8)
您可以使用 ON DELETE CASCADE 定义表格。如果这样做,您只需要在订单表上删除。使用 order_id 作为启用该选项的外键的其他表中的条目将自动删除。
此示例取自MySQL manual:
CREATE TABLE parent(
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child(
id INT, parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
) ENGINE=INNODB;
请注意,引擎是InnoDB。
答案 2 :(得分:3)
这取决于您的数据库引擎,但基本上您需要的声音就像您希望一个表使用带有FOREIGN KEY
选项的ON DELETE CASCADE
引用另一个表,然后从父表中删除将自动删除相应的行来自附属表。
答案 3 :(得分:2)
如果您正在使用MySQL / PgSQL,那么这是一个简单的解决方案......
DELETE t1, t2 FROM table1 AS t1
LEFT JOIN table2 AS t2 USING( orderID )
WHERE t1.orderID = 500;
保证像魅力一样工作!
请确保将 table1 和 table2 替换为您的相应表格名称。
我在自定义设计的CMS中使用了大量此查询 - 无论何时我想避免两个不同的原子查询。这与级联删除一样好,并且可以将查询扩展为跨越任意数量的表。
这是另一个涉及3个表的例子:
DELETE t1, t2, t3 FROM table1 AS t1
LEFT JOIN table2 AS t2 USING( orderID )
LEFT JOIN table3 AS t3 USING( orderID )
WHERE t1.orderID = 500;
干杯, 米^ E
答案 4 :(得分:2)
如果您正在使用InnoDB(或支持它们的存储引擎),您可以使用FOREIGN KEY constraints删除对应的行。如果您不介意外键对性能的轻微影响,这是最简单/最安全的方法之一。但请注意,由于约束而删除的行不会触发触发器。
或者,您可以使用触发器。它们适用于任何存储引擎,它们通常很容易编写。我喜欢它们,但如果你一次删除大量行(几百或几千行),它们就不是很有效。
CREATE TRIGGER ad_orders AFTER DELETE ON orders
FOR EACH ROW DELETE FROM orders_items WHERE orderID = OLD.orderID;
最后,正如上一个答案中所建议的那样,您可以使用多表DELETE:
DELETE o, oi
FROM orders o
LEFT JOIN orders_items oi USING (orderID)
WHERE o.orderID = 500;
答案 5 :(得分:1)
您可以使用存储的函数并调用它吗?
然后在您的存储函数中,您将同时拥有两个DELETE查询。然后,当调用存储的函数时,它将作为事务运行,您可以返回任何您喜欢的函数。