2009-08-27 66 views
7

我有两个表:orders和orders_items。共享字段orderID。从一个查询中的两个表中删除行

我想从两个表中删除orderID = 500的所有行,但我只需要在一个查询中执行此操作。这可能吗?

+0

为什么你需要在一个查询中做到这一点?根据您访问数据库的方式,您可以使用以分号分隔的两个语句并将其视为一个。我知道的唯一的另一种方式是使用存储过程。 – 2009-08-27 09:17:40

+0

是的,我知道。但我必须用数千行手动完成。 这个想法是只在一个查询中做到这一点,以尽量避免小费错误。 – 2009-08-27 09:20:45

回答

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。

+0

声音没问题,我会试一下,然后回来 – 2009-08-27 09:27:54

+1

它像一个魅力一样工作,谢谢 ALTER TABLE orders_items ADD FOREIGN KEY(orderID)REFERENCES orders(orderID)ON DELETE CASCADE – 2009-08-27 09:43:40

1

你可以使用存储的函数并调用它吗?

然后在你存储的函数中,你将有两个DELETE查询。然后,当调用存储的函数时,它将作为事务运行,并且可以让它返回任何你喜欢的东西。

+0

存储过程对我来说是难以捉摸的。不喜欢我:-( – 2009-08-27 09:22:44

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 

如果订单ID是一个varchar,然后将该语句更改为= '500'

+0

#1064 - 您的SQL语法错误;检查与您的MySQL服务器版本相对应的手册,以获得在第1行'where orderID = 500'附近使用的正确语法 – 2009-08-27 09:23:34

3

这取决于你的数据库引擎,但基本上你需要听起来像你想要一个表引用另一个表使用FOREIGN KEYON DELETE CASCADE选项,然后从父表中删除将自动从相关表中删除相应的行。

+0

我只是想写同样的东西:)级联是最容易做的事情。 – Thinker 2009-08-27 09:24:40

+0

看着它,谢谢 – 2009-08-27 09:28:36

2

这里有一个简单的解决方案,如果你使用MySQL/PGSQL ...

DELETE t1, t2 FROM table1 AS t1 
LEFT JOIN table2 AS t2 USING(orderID) 
WHERE t1.orderID = 500; 

保证像一个魅力的工作!

确保在您的情况下使用适当的表名替换表1表2

我在我的自定义设计的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; 

干杯, 平方公尺Ë

+0

哦,很好。我会记住它。 – 2009-08-27 09:45:31

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 o, oi 
FROM orders o 
LEFT JOIN orders_items oi USING (orderID) 
WHERE o.orderID = 500; 
+0

非常感谢 – 2009-08-27 09:47:29