How to delete data from multiple tables at the same time?

Asked

Viewed 275 times

-1

People for security I decided to use Transaction, I hope it works like this:

Concludes only if all the querys rotate.

You suggest something better?

<?php
if (isset($_GET['deletar']) && $_GET['deletar'] == 'sim'):
    $lojista = (int)$_GET['lojista'];
    BD::conn()->beginTransaction();
    $deletar_lojista = BD::conn()->prepare("DELETE FROM `loja_lojistas` WHERE `id` = :id");
    $deletar_lojista->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_lojista->execute();
    if(!$deletar_lojista){
        BD::conn()->rollBack();
    }

    $deletar_loja = BD::conn()->prepare("DELETE FROM `admin_lojas` WHERE `id_loja` = :id");
    $deletar_loja->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_loja->execute();
    if(!$deletar_loja){
        BD::conn()->rollBack();
    }

    // Apaga todas as fotos de produtos que o Lojista cadastrou
    $deletar_fotos_produtos = BD::conn()->prepare("SELECT `imagem` FROM `loja_produtos` WHERE `id_loja` = :id");
    $deletar_fotos_produtos->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_fotos_produtos->execute();
    $foto = $deletar_fotos_produtos->fetchObject();
    unlink('../../../www/produtos/'.$foto->imagem);

    $deletar_produtos = BD::conn()->prepare("DELETE FROM `loja_produtos` WHERE `id_loja` = :id");
    $deletar_produtos->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_produtos->execute();
    if(!$deletar_produtos){
        BD::conn()->rollBack();
    }

    $deletar_produtos_pedidos = BD::conn()->prepare("DELETE FROM `loja_produtos_pedidos` WHERE `id_loja` = :id");
    $deletar_produtos_pedidos->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_produtos_pedidos->execute();
    if(!$deletar_produtos_pedidos){
        BD::conn()->rollBack();
    }

    $deletar_pedidos = BD::conn()->prepare("DELETE FROM `loja_pedidos` WHERE `id_loja` = :id");
    $deletar_pedidos->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_pedidos->execute();
    if(!$deletar_pedidos){
        BD::conn()->rollBack();
    }

    $deletar_categorias = BD::conn()->prepare("DELETE FROM `loja_categorias` WHERE `id_loja` = :id");
    $deletar_categorias->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_categorias->execute();
    if(!$deletar_categorias){
        BD::conn()->rollBack();
    }

    $deletar_subcategorias = BD::conn()->prepare("DELETE FROM `loja_subcategorias` WHERE `id_loja` = :id");
    $deletar_subcategorias->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_subcategorias->execute();
    if(!$deletar_subcategorias){
        BD::conn()->rollBack();
    }

    $deletar_pagamentos = BD::conn()->prepare("DELETE FROM `admin_pagamentos` WHERE `id_lojista` = :id");
    $deletar_pagamentos->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_pagamentos->execute();
    if(!$deletar_pagamentos){
        BD::conn()->rollBack();
    }

    $deletar_vencimentos = BD::conn()->prepare("DELETE FROM `admin_vencimentos` WHERE `id_lojista` = :id");
    $deletar_vencimentos->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_vencimentos->execute();
    if(!$deletar_vencimentos){
        BD::conn()->rollBack();
    }

    BD::conn()->commit();
    echo "<script type='text/javascript'>
            $.alert({
                theme: 'black',
                title: 'Deletado com sucesso!',
                content: '',
                icon: '',
                confirmButton: 'OK',
                confirmButtonClass: 'btn-primary',
                animation: 'scale',
                animationClose: 'top',
                opacity: 0.5,
            });
        </script>";
endif;
?>
  • 1

    Yes, a framework and/or ORM rsrsrs.

  • 2

    Then the transaction fails, it’s all in DB, but the photos were deleted from the hard drive anyway. It would be better if at the end, confirmed the success of the transaction, you deleted the photos. What you can do there, if you change the database, is create a Deletardodb( $connected, $table, $id ) function to make life easier. Or do in a foreach, passing the list of tables as array.

1 answer

1


Utilize exceptions together. It is easy to verify that you are using PDO. Once using exceptions, you do not need to validate method returns PDOStatement::execute(), just keep going.

You must first activate the exception release:

//Ativa o lançamento de exceptions para erros
BD::conn()->->setAttribute(PDO::ATTR_ERRMODE , PDO::ERRMODE_EXCEPTION);

After, the deletion script.

try {        
    BD::conn()->beginTransaction();

    $deletar_lojista = BD::conn()->prepare("DELETE FROM `loja_lojistas` WHERE `id` = :id");
    $deletar_lojista->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_lojista->execute();

    $deletar_loja = BD::conn()->prepare("DELETE FROM `admin_lojas` WHERE `id_loja` = :id");
    $deletar_loja->bindValue(':id', $lojista, PDO::PARAM_INT);
    $deletar_loja->execute();

    /** 
        todas as suas demais transações 
    **/

    BD::conn()->commit();

    /** 
        passe a exclusão física dos arquivos para o final do script, 
        após o commit das transações
    **/    

    // Apaga todas as fotos de produtos que o Lojista cadastrou
    //A foto deve ter sido consultada antes do commit, após, o registro não existe mais no SGBD
    unlink('../../../www/produtos/'.$foto->imagem);
} catch (PDOException $exception) {
    BD::conn()->rollback();

    printf('Não foi possível realizar a operação: %s' , $exception);
}

If the command is successful, the script will continue running, if there is a failure, a PDOException. Understand how to fail when you cannot delete an existing record (a dependency, connection failure, privileges).

Using returns, you may get a different result as an exclusion with a clause WHERE of a record that does not exist, can return false. However, it was not the execution of DELETE or the record that was not deleted but the record that does not exist according to the clause.

The same can happen with a UPDATE. In prepared statements, if you perform a UPDATE for a record, and update with the same existing values, this UPDATE will not be carried out as there will be no change in the record and no affected lines. However, this can change from DBMS to DBMS, so it’s important to be aware of feedback, errors and exceptions. Always recommended the use of exceptions.

  • What if by chance deleting the shopkeeper, there is no payment yet made by him? will give Exception la in admin_payments and not complete any of those other processes?

  • @Jonathansilva No. The fact of instruction DELETE Not finding results to delete is not an error. The instruction will be executed normally, with 0 (zero) lines affected and will pass to the next instruction. An exception will be issued only if an error occurs, such as a dependent record, lack of privileges, etc.

  • in the case when deleting the shopkeeper, as it had no products and much less the product photo, gave error but deleted the rest. No problem? http://imgur.com/a/mxHJM

  • at first, if you have not launched Exception, the error has no relation. What was the error?

  • sent the print link above, the error line is where you have unlink('.. /.. /.. /www/products/'. $photo->image);

  • The variable you are using to delete the file is not an object. It is not a transaction error.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.