【问题标题】:PHP mysqli: Insert row or return id if unique conflictPHP mysqli:如果唯一冲突,则插入行或返回 id
【发布时间】:2015-12-19 14:38:38
【问题描述】:

我有一个重量值表:

TABLE_WEIGHT
    WEIGHT_ID bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT,
    WEIGHT float NOT NULL UNIQUE

然后我插入值:

$query = "INSERT INTO TABLE_WEIGHT (WEIGHT) VALUES(100)";

if ($stmt = $this->mysqli->prepare($query)) : 
    if (!stmt->execute()) : 
        // some error
    else :
        // alright
    endif;
endif;

我第一次这样做不会有问题。如果我第二次这样做,值 100 已经存在。现在有没有办法在不需要新的 select 语句的情况下获取冲突行的 id?

【问题讨论】:

  • 否;你应该使用SELECT 声明。
  • @TwoStraws 好的,谢谢,但我需要知道是否由于独特的冲突而发生错误。否则,即使错误有其他原因,我也会始终执行选择。
  • 你试过打电话给insert_id()吗?它返回什么? insert_id() 方法实际上返回最后插入的 id。此外,我建议您检查它是否返回重复的 id,即使在插入重复行时也是如此。祝你好运。

标签: php mysqli


【解决方案1】:

您可以通过INSERT ...ON DUPLICATE KEY UPDATE 和鲜为人知的LAST_INSERT_ID(expr) 形式来做到这一点

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly', array(
    PDO::ATTR_EMULATE_PREPARES=>false,
    PDO::MYSQL_ATTR_DIRECT_QUERY=>false,
    PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION
));
setup($pdo);

$stmt = $pdo->prepare('
    INSERT INTO
        soFoo
        (WEIGHT)
    VALUES
        (?)
    ON DUPLICATE KEY UPDATE
        WEIGHT_ID=LAST_INSERT_ID(WEIGHT_ID),
        dummy=NOT dummy
');

foreach( array(100,200,300,100,400) as $w ) {
    $stmt->execute( array($w) );
    echo $w, ' -> ', $pdo->lastInsertId(), "\r\n";
}


foreach( $pdo->query('SELECT WEIGHT_ID,WEIGHT FROM soFoo', PDO::FETCH_ASSOC) as $row) {
    echo join(', ', $row), "\r\n";
}


function setup($pdo) {
    $pdo->exec('
        CREATE TEMPORARY TABLE soFoo (
            WEIGHT_ID bigint(20) NOT NULL AUTO_INCREMENT,
            WEIGHT float NOT NULL UNIQUE,
            dummy   int  NOT NULL DEFAULT 0,
            PRIMARY KEY(WEIGHT_ID),
            UNIQUE KEY(WEIGHT)
        )
    ');
}

打印

100 -> 1
200 -> 2
300 -> 3
100 -> 1
400 -> 5
1, 100
2, 200
3, 300
5, 400

(注意缺少的 WEIGHT_ID=4)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多