2007年10月18日
はじめに:最新のMySQLでは、タイトルに示されている構文は使用できません。しかし、既存の機能を使用して期待されることを達成する非常に簡単な方法がいくつかあります。
3つの可能な解決策があります。INSERTIGNORE、REPLACE、またはINSERT…ON DUPLICATE KEY UPDATEを使用します。
テーブルがあると想像してください:
CREATE TABLE `transcripts` (
`ensembl_transcript_id` varchar(20) NOT NULL,
`transcript_chrom_start` int(10) unsigned NOT NULL,
`transcript_chrom_end` int(10) unsigned NOT NULL,
PRIMARY KEY (`ensembl_transcript_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ここで、Ensemblからトランスクリプトメタデータをインポートする自動パイプラインがあり、さまざまな理由によりパイプラインが実行の任意のステップで壊れている可能性があると想像してください。したがって、2つのことを確認する必要があります。
パイプラインを繰り返し実行してもデータベースは破壊されません
「主キーの重複」エラーが原因で繰り返し実行が停止することはありません。
方法1:REPLACEを使用する
とても簡単です:
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
レコードが存在する場合は上書きされます。まだ存在しない場合は作成されます。ただし、この方法を使用するのは効率的ではありません。既存のレコードを上書きする必要はありません。スキップするだけでかまいません。
方法2:INSERT IGNOREを使用することも非常に簡単です。
INSERT IGNORE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
ここで、「ensembl_transcript_id」がデータベースにすでに存在する場合、それは黙ってスキップされます(無視されます)。(より正確には、MySQLリファレンスマニュアルからの引用は次のとおりです。「IGNOREキーワードを使用すると、INSERTステートメントの実行中に発生したエラーは代わりに警告として扱われます。たとえば、IGNOREがない場合、既存のUNIQUEインデックスを複製する行またはテーブルのPRIMARY KEY値が原因で重複キーエラーが発生し、ステートメントが中止されます。」))レコードがまだ存在しない場合は、作成されます。
この2番目の方法には、他の問題が発生した場合にクエリが中断しないことなど、いくつかの潜在的な弱点があります(マニュアルを参照)。したがって、以前にIGNOREキーワードなしでテストした場合は、これを使用する必要があります。
方法3:重複キー更新でINSERT…を使用する:
3番目のオプションはINSERT … ON DUPLICATE KEY UPDATE
構文を使用することです。UPDATE部分では、0 + 0の計算など、意味のない(空の)操作を何も実行しません(Geoffrayは、MySQL最適化エンジンがこの操作を無視するようにid = id割り当てを行うことを提案しています)。この方法の利点は、重複するキーイベントのみが無視され、他のエラーが発生しても中止されることです。
最後のお知らせとして:この投稿はXaprbに触発されました。また、柔軟なSQLクエリの記述に関する彼の他の投稿を参照することをお勧めします。