【问题标题】:How to insert a value into an auto_increment of a different table in the same string如何将值插入到同一字符串中不同表的 auto_increment
【发布时间】:2018-09-19 13:36:41
【问题描述】:

我使用mysqli_multi_query 插入用户信息和默认的空个人资料照片,有两个表格,"esc_usuarios" 用于个人数据,"esc_usuarios_fotos" 用于照片。

我想要的是,在插入个人数据后,将此空图像插入"esc_usuarios_fotos" 表绑定"img_usu_codigo" 与此插入的人,此人的ID 在表中的"usu_codigo" 列中自动递增"esc_usuarios".

查询:

<?php
$inserir_usuario = "INSERT INTO `esc_usuarios` 
    (
        usu_nome, 
        usu_senha, 
        usu_sobrenome, 
        usu_cpf, 
        usu_rg, 
        usu_nasc, 
        usu_endereco, 
        usu_numero, 
        usu_bairro, 
        usu_cep, 
        usu_cidade, 
        usu_uf, 
        usu_tel, 
        usu_cel, 
        usu_genero, 
        usu_email, 
        usu_indicador_codigo, 
        usu_datacadastro
    ) VALUES (
        '$nome', 
        '".md5('$password')."', 
        '$sobrenome', 
        '$cpf', 
        '$rg', 
        '$nascimento', 
        '$endereco', 
        '$numero', 
        '$bairro', 
        '$cep', 
        '$cidade', 
        '$uf', 
        '$tel', 
        '$cel',
        '$genero', 
        '$email', 
        '" . $_SESSION['codigo'] . "', 
        '$trn_date'
    );
    INSERT INTO esc_usuarios_fotos(img_local,img_usu_codigo) VALUES ('null', //i want to insert here the inserted person's id  "usu_codigo" of the first insert statement)";

$re = mysqli_multi_query($conexao, $inserir_usuario);

【问题讨论】:

  • 将它们分成 2 个单独的查询。您可以使用 mysqli_insert_id 获取刚刚创建的 ID,然后在第二个插入语句中使用它 - php.net/manual/en/…
  • 除了@waterloomatt 所说的:我建议在整个过程中使用事务,因此您要么拥有所有数据,要么一无所有,而不是可能会中断的半现有用户当您尝试在代码中使用他时。
  • 警告: 不要使用md5() 进行密码散列。它很旧,超快(在密码散列方面很糟糕)并且损坏(发生了散列冲突)。请改用 PHP 的 password_hash()password_verify()
  • 您还应该考虑使用准备好的语句,而不是像那样手动构建查询。我不知道您是否先转义数据,但是在使用多查询时考虑安全性尤为重要。
  • 您有两个选择:1.) 根据手册使用 PHP 函数 mysqli_insert_id()。 2.) 通过使用 SQL 函数 LAST_INSERT_ID(): INSERT INTO esc_usuarios_fotos (...) VALUES ('null', LAST_INSERT_ID()); 使用本机 (My)SQL 方法

标签: php sql mysqli-multi-query


【解决方案1】:

在这里解决一些问题。出于安全原因,您确实应该使用参数化插入。拆分您的插入,然后使用insert_id 从您的person insert 中获取新创建的 ID。正如 cmets 中的其他人所指出的那样,将所有内容包装在事务中 - 这将确保您获得所有内容或一无所有。

最后,使用mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); 将 MySQL 错误转换为 PHP 异常。然后,您可以将所有内容包装在 try/catch 块中。祝你好运!

伪代码:

// Turn MySQL errors into PHP exceptions.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

try {
    // Open connection
    $connection = new mysqli(...);

    // check connection 
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }

    // Start transaction here 
    ...

    /***********************************/
    /********** PERSON INSERT **********/
    /***********************************/
    if ($stmt = $connection->prepare("INSERT INTO `esc_usuarios` ... (?, ?, ...)")) {

        /* bind parameters for markers */
        $stmt->bind_param("s", $...);
        ...

        /* execute first query */
        $stmt->execute();

        /* This is the newly created ID */
        $id = $connection->insert_id

        /***********************************/
        /********** PHOTOS INSERT **********/
        /***********************************/
        if ($stmt = $connection->prepare("INSERT INTO `esc_usuarios_fotos` ... (?, ?)")) {

            /* Use that newly created ID here along with other params for your query */
            $stmt->bind_param("s", $id);

            /* execute query */
            $stmt->execute();
        }
    }

    // Commit transaction here
    ...
}
catch ( Exception $e ) {
    // Rollback transaction if the exception is DB related
    ...
}

【讨论】:

  • 不错的一个。我建议将“伪代码”更改为“模板代码”,因为这几乎是完全有效的 PHP。
猜你喜欢
  • 2018-10-11
  • 1970-01-01
  • 2016-06-03
  • 2010-11-26
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多