多次插入后更新特定记录 - 可能使用 last_insert_id()

Posted

技术标签:

【中文标题】多次插入后更新特定记录 - 可能使用 last_insert_id()【英文标题】:Update specific record after multiple insert - possibly using last_insert_id() 【发布时间】:2013-03-04 02:19:35 【问题描述】:

我有一个使用 for 循环的多个插入(4 条记录)。然后,我想对在 path_allowed = 'y' 中插入的记录运行更新查询(4 个中只有一个具有此值)。我猜 last_insert_id() 在这里会很有用,但不确定如何使用它来更新插入以下内容的记录:

$pathway_allowed = intval($_POST['allowed']);
$action = mysql_real_escape_string($_POST['actions']);

if(isset($_POST['submit'])) 

$pathway_comment = array();
foreach($_POST['comment'] as $comment) 
    $pathway_comment[]= mysql_real_escape_string($comment);

for($i=0, $count = count($pathway_comment);$i<$count;$i++) 
    $comment = $pathway_comment[$i];
    $query = sprintf(
        "INSERT INTO pathway (             
           pathway_pk,
           case_fk,
           level,
           pathway_action_fk,
           pathway_allowed,
           comment
        ) VALUES (
           '',
           '$case_pk',
           '1',
           '$action',
           '%s',
           '$comment')", $pathway_allowed === $i ? 'y' : 'n');

       $result = mysql_query($query, $connection) or die(mysql_error());

if($result)
- SELECT the 4 records here...


【问题讨论】:

彼得,你应该知道mysql_query将来会消失你知道吗?在我的回答中,我包含了PDO,因为如果 php 5.5 出现,您将替换您的代码。现在它在PHP 5.5.0 Alpha5 released 中。然后,如果您的主机有这个 PHP 版本,您的代码将不会被执行。只是为了让你认识我的朋友:) 【参考方案1】:

在每次循环迭代中,将mysql_insert_id() 存储到一个数组中,以后可以使用该数组来选择新记录。请注意,我在这里用更简洁的foreach 替换您的增量for 循环:

// Initialize arrays for later
// one for the new ids
$inserted_ids = array();
// one to keep comments from failed queries
$failed_comments = array();
// and one for the MySQL errors of failed queries
$errors = array();

foreach ($pathway_comment as $comment) 
    $query = sprintf(
        "INSERT INTO pathway (             
           pathway_pk,
           case_fk,
           level,
           pathway_action_fk,
           pathway_allowed,
           comment
        ) VALUES (
           '',
           '$case_pk',
           '1',
           '$action',
           '%s',
           '$comment')", $pathway_allowed === $i ? 'y' : 'n');

       $result = mysql_query($query, $connection);

       // If the iteration was successful, save the insert id onto an array
       // but only if $pathway_allowed == 'y'
       if ($result) 
           if ($pathway_allowed == 'y') 
               $inserted_ids[] = mysql_insert_id();        
           
       
       // Otherwise, keep an array of comments that failed
       // Maybe useful later if you want to print those that failed
       else 
           $failed_comments[] = $comment;
           // And keep the mysql_error() as well.
           $errors[] = mysql_error();
       

// Loop is done, now you can implode() the inserted ids array:
// These are all ints from an auto_increment PK, so no additional escaping needed
// Execute the query than do whatever you need with the newly inserted rows.
$query = "SELECT * FROM pathway WHERE pathway_pk IN (" . implode(",", $inserted_ids) . ")";

您之前可能听说过,但从长远来看,请考虑切换到支持预准备语句的 API,例如 MySQLi 或 PDO。您已经在此处完成了所有必要的转义和整数转换,但如果在循环中编译和执行准备好的语句会更快,而且不需要转义。

【讨论】:

酷,谢谢,我会试一试。顺便说一句,我在***.com/questions/15153196/… 提出了这个问题作为解决我的问题的一种可能方法 @PeterBrowne 我只是稍微修改了一下 - 没有注意到您只想保存 $pathway_allowed == 'y' 的那些 不完全是,在插入之后,我想更新在 path_allowed = 'y' 处插入的四个记录之一... @PeterBrowne 你在使用更新的代码吗?它这样做。只有 $pathway_allowed = y 的那个被添加到 $inserted_ids 数组中...【参考方案2】:

mysql_connect 扩展自 PHP 5.5.0 起已弃用,并将在 未来。相反,应该使用 MySQLi 或 PDO_MySQL 扩展。 另请参阅 MySQL:选择 API 指南和相关常见问题解答以了解更多信息 信息。此函数的替代方法包括:PDO 和 mysqli_connect()

如果您使用的是 PDO,则可以使用它。

$dbh = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');

在 for 循环中你可以这样做:

$stmt = $dbh->prepare("INSERT INTO test (name, email) VALUES(?,?)");
$tmt->execute( array('user', 'user@example.com'));
$inserted_ids[] = $dbh->lastInsertId(); 

在循环之后,您将拥有一个包含 4 个插入 id 的数组

编辑:你不需要重新选择你输入的值,你可以使用这个

IN FOR LOOP

    $stmt = $dbh->prepare($query = sprintf("INSERT INTO pathway (pathway_pk,case_fk,level,pathway_action_fk,pathway_allowed, comment)
    VALUES (
       '',
       '$case_pk',
       '1',
       '$action',
       '%s',
       '$comment')", $pathway_allowed === $i ? 'y' : 'n'););

        // change the values to bindParam 

    $stmt->execute( array('user', 'user@example.com'));
    $data[$i]['pathway_pk'] = $dbh->lastInsertId(); 
    $data[$i]['case_fk'] = $case_pk;
    $data[$i]['level'] = 1;
    $data[$i]['pathway_action_fk'] = $action;
    $data[$i]['pathway_allowed'] = %s;
    $data[$i]['comment'] = $comment;


然后

foreach($data as $d)

    echo $d['pathway_pk'];
    echo $d['case_fk'];



【讨论】:

以上是关于多次插入后更新特定记录 - 可能使用 last_insert_id()的主要内容,如果未能解决你的问题,请参考以下文章

插入后触发多次插入后无法正常工作

Pdo多次插入记录,等于数据库值

多次插入和更新导致死锁 c#

pdo多次插入记录,等于数据库值

如何在mysql 5中记录特定表的插入/更新查询

如何分离在 Oracle 中为特定表插入、更新和删除记录的过程