2009-08-27 96 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