db_mergeなしでdb_insertに「INSERT IGNORE」を設定する方法


8

誰かがdb_insertで 'INSERT IGNORE'を設定する方法を知っていますか?

多くの行を挿入するため、db_mergeを使用できません。

$query = db_insert('table')->fields(array('foo', 'bar'));
foreach ($rows as $row) {
  $query->values(array(
    'foo' => $row->foo,
    'bar' => $row->bar,
  ));
}
$query->execute();

回答:


5

次の2つのオプションがあります。

  1. サブクラス化InsertQueryし、その機能を自分で追加します(現在は実装されていません)。
  2. db_query()代わりに、生のSQL文字列を実行するために使用します。

INSERT IGNOREDrupal 7コードベースでの唯一の言及はにありDatabaseConnection_mysql:nextIdます。実際には使用されていませんが、代わりに、にON DUPLICATE KEY UPDATE直接渡されるを含む生のクエリ文字列がありますdb_query()

私は間違っているかもしれませんが、それが生のSQL文字列と一緒db_query()に行く方法であるということと同じくらい良い指標だと思います。


3

「INSERT IGNORE」を使用することはできませんが、PHPでこれを回避する方法があります。このようなもの:

try {
    $insertID = db_insert('crawl_data')->fields(array(
        'url' => $url, 
    ))->execute();
} catch (Exception $ex) {

}

この例では、「urls」のデータベースがあります。ただし、アイテムがデータベースにあるかどうかを最初に確認する必要はありません。私はそれが一度に起こることを望んでいます。したがって、これは「挿入無視」と同じような動作です。

ただし、これは一般的に悪いことです。

catch (Exception $ex) {
    // open space
}

だからこれを行う方が良いかもしれません:

catch (Exception $ex) {
    $error = $ex->getMessage();
    if (strpos($error, 'SQLSTATE[23000]: Integrity constraint violation') !== false) {
        // then we know it's an error we can ignore
    }
    else {
        // just throw the error again
        throw $e;
    } 
}

これか、2つのデータベースクエリを実行しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.