web-dev-qa-db-ja.com

重複を無視してクエリを挿入(キーなし)

質問があります:

$query_add_analogue
  ->insert($db->quoteName('#__parts_analogues'))
  ->columns($db->quoteName($columns))
  ->values($value);
$db->setQuery($query_add_analogue);
$db->execute();

テーブル「#_parts_analogues」には、「original_id」と「analogue_id」の2つの列があります。

値のペアがテーブルに既に存在する場合、挿入機能を無視する必要があります。テーブルに主キーがありません。

1
user3774771

MySQLを使用しているので、列に一意のインデックスを作成できますoriginal_idおよびanalogue_id

次に、次のような生のクエリを使用します。

$db = JFactory::getDbo();
$query = 'INSERT IGNORE INTO ' . $db->quoteName('#__parts_analogues') VALUES ("your", "values");
$db->setQuery($query)->execute();

挿入のように機能しますが、エラーを返しません。

インデックスなしで作業すると、パフォーマンスに重大な問題が発生する可能性があることに注意してください。

3
christian

私は、この種の問題の解決策を探している可能性のある新しい読者のために、これに関する解決策を示します。 Joomlaのクエリメソッドでは、この問題を実際に解決することはできません。上記で説明したように、「INSERT IGNORE INTO」のような単純なMySQLクエリは機能するはずですが、常に適切なソリューションであるとは限りません。代わりに、 "INSERT INTO ... ON DUPLICATE KEY UPDATE" MySqlクエリが機能します。どうして?レコードがすでに存在する場合、それは単に更新される(おそらく同じレコードで、または同じIDと一意のフィールドを持つ更新されたレコードで更新されるため、問題ではない)ため、レコードが存在しない場合は、作成され、テーブルに新しいレコードとして挿入されます。

最初に、元の質問のこの特定の問題を理解します(この問題では、キーのペアをテーブルに挿入または更新します)、テーブルの2つの列を「UNIQUE-"original_id"および "analogue_id"」にしないでください。キーを一意にすると、キーの1つがペアの以前に挿入されたキーと同じである新しいキーのペアを再度挿入することができないためです。たとえば、以前にoriginal_id = 1とanalog_id = 1のようなキーのペアを挿入し、今度はoriginal_id = 1とanalog_id = 2のような新しいペアを挿入しようとしています。これらのキーが両方ともテーブル内で一意である場合、 2番目のペアを新しいペアとして挿入し、同時にそれらも更新したくない場合。

だから私がやろうとしていることは、(コード内で)original_idキーとanalog_idキーから実際のUNIQUEキーを生成し、それらを生成された一意キーと一緒にテーブルに挿入することです。そして、新しいデータでテーブルを更新するとき、またはテーブルに新しいデータを挿入するとき、たとえば次のように使用します。

$my_unique_key = $original_id . $analogue_id . "something_to_make_it_more_unique";

$myTableItems = new stdClass();

// You can put all of the data items into the $myTableItems object
// if you have many of these data
// I will not do that here due to time saving

// and in foreach loop

foreach ($myTableItems as $item) {

  $fields = array($db->quoteName('myunique_key') . ' = ' . $db->quote($item->my_unique_key),
            $db->quoteName('original_id') . ' = ' . $db->quote($item->original_id),
            $db->quoteName('analogue_id') . ' = ' . $db->quote($item->analogue_id));

  $values = array($item->my_unique_key, $item->original_id, $item->analogue_id);

  $query = "INSERT INTO #__mytable (myunique_key, original_id, analogue_id) VALUES ('" . implode("', '", $values) . "')
  ON DUPLICATE KEY UPDATE" . implode(", ", $fields);

  $db->setQuery($query)->execute();
  }

また、新しいレコードを挿入するだけで、古いレコードを更新したくない場合は、次のようにINSERT IGNORE INTOクエリを使用できます。

$query = "INSERT IGNORE INTO #__mytable (myunique_key, original_id, analogue_id) VALUES ('" . implode("', '", $values) . "')";

これらのSQLクエリの簡単な参照は、たとえば here です。

1
Zollie