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

-1

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

Conclude only if all querys are running.

Do 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;
?>
    
asked by anonymous 04.01.2017 / 01:54

1 answer

1

Use exceptions together. It is easy to verify that you are using PDO. Once using exceptions, you do not need to validate returns from the PDOStatement::execute() method, just go ahead.

First you must enable throw exceptions:

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

After, the delete 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 succeeds, the script will continue to run, if a fault occurs, a PDOException will be thrown. Understand how to fail, when you can not delete an existing record (a dependency, connection failure, privileges).

Using returns, you can have a different result because an exception with a WHERE clause 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 occur with a UPDATE . In prepared statements , if you make a UPDATE for a record, and update with the same existing values, this UPDATE will not be performed as there will be no change in the record and no affected rows. However, this may change from DBMS to DBMS, so it is important to be aware of returns, errors, and exceptions. Always being careful to use exceptions.

    
04.01.2017 / 14:52