How to insert into 3 tables at once? (PHP +Mysql)

Asked

Viewed 863 times

1

I always come here for research but I never had to ask. I now find myself at a crossroads.

I need to add data in 3 tables at the same time( books, author and editor), and in book, I have foreign key of editor and author.

No sql got something like this:

INSERT INTO autor(nome) VALUES ('testeAutor');
INSERT INTO livros(titulo, edicao, id_autor) values ('nomedolivro','segunda edicao',LAST_INSERT_ID());
INSERT INTO editora(nome) VALUES('testeEditora');
UPDATE livros set id_editora=LAST_INSERT_ID() where titulo='nomedolivro';

In php, I even got something like this and it worked:

$query_autor = "insert into autor (nome) values ('$autor')";
            $sql_autor = mysqli_query($con, $query_autor) or die("Não foi possível cadastrar o autor.");
            $id_autor = mysqli_insert_id($con);
            $query_editora = "insert into editora (nome) values ('$editora')";
            $sql_editora = mysqli_query($con, $query_editora) or die("Não foi possível cadastrar a editora.");
            $id_editora = mysqli_insert_id($con);
            $sql = "insert into livros (titulo, edicao, id_autor, id_editora) values ('$titulo', '$edicao', '$id_autor', '$id_editora')";
            echo $sql;
            $result = mysqli_query($con, $sql) or die("Não foi possível inserir o novo livro no sistema.");
            if(!$result) {
                echo "Não foi possivel cadastrar o novo livro";
            } else {
            echo "Livro cadastrado com sucesso";
            echo "<br />";
            echo "<a href='cadastro.php'>Voltar para cadastro</a>";
            echo "<br />";
            echo "<a href='index.php'>Listar todos</a>";

Is there any less "Gambiarra" and/or safer way to do this? After all, it can happen to insert the author, editor and fail the book... I tried Begin Tran, start transaction... Nothing works in xampp. If I put any despair (I searched in google, I looked in mysql doc), it gives that the code is incorrect in the next line after BEGIN or START.

Thanks for your attention, guys!


Update: I managed to get it to work with START TRANSACTION; + COMMIT; via SQL but I wanted to know if there is a more correct or usual way to put this in php. There is a zone like this that I posted on top. Would you have to create one more variable only for START TRANSACTION or have some command in php to do this? I don’t even know exactly how to google this.

  • examples of transaction here.

2 answers

1

As far as I know Mysql does not support any way to insert in multiple tables at the same time.

What you can do is open a transaction, run the Inserts, and then commit. Therefore, if an error occurs in one of the Inserts the others will not be effectively recorded in the bank.

  • So Fabio. I tried every way I know but the mysql of xampp is not accepting the commands to start and close transaction. I tried BEGIN TRAN, BEGIN TRANSACTION, START TRAN, START TRANSACION... anyway, I put the command alone and it works, if I try to use Begin or start, it says that the Insert that was right, got wrong...

-1

I have a very long answer. But maybe it’ll do for a north. My idea is that you separate the layers of the program.

I tried to express quite generic below:

<?php
// Contexto do modelo da livraria.
class Editora {

    public function __constructor($nome) {
        $this->nome = $nome;
    }

    /**
     * @var int numero Identificador.
     */
    public $id;

    /**
     * @var string Texto com nome.
     */
    public $nome;

}

class EditoraCRUD {

    public function cadastrar(Editora $Editora, PDOStatement $Connect) {
        // Contexto do crud do editora sempre utilizando a mesta conexão.
        $Param = [$Editora->id, $Editora->nome];
        $statement = $Connect->prepare("INSERT INTO Editora VALUES (:ID, :Nome)");
        $statement->bindParam(":ID", $Param[0]);
        $statement->bindParam(":Nome", $Param[1]);
        $statement->execute();
        $Editora->id = $Connect->lastInsertId();
    }

}

class Autor {

    public function __constructor($nome) {
        $this->nome = $nome;
    }

    /**
     * @var int numero Identificador.
     */
    public $id;

    /**
     * @var string Texto com nome.
     */
    public $nome;

}

class AutorCRUD {

    public function cadastrar(Autor $Autor, PDOStatement $Connect) {
        // Contexto do crud do Autor sempre utilizando a mesta conexão.
        $Param = [$Autor->id, $Autor->nome];
        $statement = $Connect->prepare("INSERT INTO Autor VALUES (:ID, :Nome)");
        $statement->bindParam(":ID", $Param[0]);
        $statement->bindParam(":Nome", $Param[1]);
        $statement->execute();
        $Autor->id = $Connect->lastInsertId();
    }

}

class Livro {

    public function __constructor($nome) {
        $this->nome = $nome;
    }

    /**
     * @var int numero Identificador.
     */
    public $id;

    /**
     * @var string Texto com nome.
     */
    public $nome;

    /**
     * @var Autor Instancia de Autor.
     */
    public $Autor;

    /**
     * @var Editora Instancia de Editora.
     */
    public $Editora;

}

class LivroCRUD {

    public function cadastrar(Livro $Livro, PDOStatement $Connect) {
        // Contexto do crud do Livro sempre utilizando a mesta conexão.
        $Param = [$Livro->id, $Livro->nome, $Livro->Autor->id, $Livro->Editora->id];
        $statement = $Connect->prepare("INSERT INTO Livros VALUES (:ID, :Nome, :Autor, :Editora)");
        $statement->bindParam(":ID", $Param[0]);
        $statement->bindParam(":Nome", $Param[1]);
        $statement->bindParam(":Autor", $Param[2]);
        $statement->bindParam(":Editora)", $Param[3]);
        $statement->execute();
        $Livro->id = $Connect->lastInsertId();
    }

}

// Contexto do controller da livraria.
$Connect = new PDO("mysql:127.0.0.1@livraria", "root", "");

$Editora = new Editora("StackOverflow em Português");
EditoraCRUD::cadastrar($Editora, $Connect);

$Autor = new Autor("Luis");
LivroCRUD::cadastrar($Autor, $Connect);

if (isset($Editora->id) && isset($Autor->id)) {
    $Livro = new Livro("Suas Respostas");
    $Livro->Autor = $Autor;
    $Livro->Editora = $Editora;
    LivroCRUD::cadastrar($Livro, $Connect);

    if (isset($Livro->id)) {
        print "Pronto! Tudo feito por aqui...";
    } else {
        $Connect->rollBack();
    }
} else {
    $Connect->rollBack();
    $Connect = NULL;
    print "Algo deu errado...";
}
?>

Browser other questions tagged

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