Pergunta

Eu tenho duas tabelas: ordens e ordens_items. Ambos compartilhando o campo OrderId.

Quero excluir todas as linhas de ambas as tabelas onde OrderId = 500, mas preciso fazer isso em apenas uma consulta. Isso é possível?

Foi útil?

Solução

Você pode definir a tabela com Em excluir cascata. Se você fizer isso, só precisará excluir na tabela de pedidos. As entradas em outras tabelas usando ordem_id Como a chave estrangeira com essa opção ativada será excluída automaticamente.

Este exemplo é retirado do Manual MySQL:

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;

Observe que o motor é innodb.

Outras dicas

Certamente você pode fazer isso:

DELETE FROM `table1`, `table2` WHERE `orderId` = 500

Vejo http://dev.mysql.com/doc/refman/5.0/en/delete.html

EDITAR:

Este é todo o truque:

DELETE FROM `orders`, `orders_items` 
  USING `orders` 
  INNER JOIN `orders_items` ON `orders`.`orderId` = `orders_items`.`orderId` 
  WHERE `orders`.`orderId`= 500

Se o OrderId for um Varchar, altere a declaração para = '500'.

Isso depende do seu mecanismo de banco de dados, mas basicamente o que você precisa parece que você deseja uma tabela referenciando a outra usando um FOREIGN KEY com ON DELETE CASCADE A opção e, em seguida, a remoção da tabela pai removerá automaticamente as linhas correspondentes das tabelas dependentes.

Aqui está uma solução simplesmente se você estiver usando o mysql/pgsql ...

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

Garantido para trabalhar como um encanto!

Certifique -se de substituir tabela 1 e mesa 2 com nomes de tabela apropriados no seu caso.

Eu usei bastante essa consulta no meu CMS personalizado - onde quer que eu quisesse evitar duas consultas atômicas distintas. Isso é tão bom quanto uma exclusão em cascata e a consulta pode ser expandida para abranger quantas tabelas quiser.

Aqui está outro exemplo envolvendo 3 tabelas:

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;

Saúde, M^e

Se você estiver usando o Innodb (ou um mecanismo de armazenamento que os suporta), você pode usar Restrições de chave estrangeira Para excluir as linhas correrSes. Esta é uma das abordagens mais fáceis/mais seguras, se você não se importar com o pequeno impacto de desempenho das chaves estrangeiras. Observe, no entanto, que as linhas excluídas devido a restrições não recebem gatilhos para disparar.

Como alternativa, você pode usar gatilhos. Eles trabalham com qualquer mecanismo de armazenamento e geralmente são fáceis de escrever. Eu gosto deles, mas eles não são muito executivos se você estiver excluindo um grande número de linhas de uma só vez (várias centenas ou milhares).

CREATE TRIGGER ad_orders AFTER DELETE ON orders
FOR EACH ROW DELETE FROM orders_items WHERE orderID = OLD.orderID;

Finalmente, conforme sugerido em uma resposta anterior, você pode usar exclusão de várias mesas:

DELETE o, oi
FROM orders o
LEFT JOIN orders_items oi USING (orderID)
WHERE o.orderID = 500;

Você poderia usar uma função armazenada e chamar isso?

E então, dentro da sua função armazenada, você teria ambas as consultas excluídas. Então, quando a função armazenada for chamada, será executada como uma transação e você poderá retornar o que quiser.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top