DB 2のMERGE文使用上の注意!


MERGE INTO project px
USING (SELECT project.* FROM SYSIBM.DUAL LEFT JOIN project WHERE id = ?) py 
   ON px.id = py.id
 WHEN MATCHED THEN
     UPDATE SET
         (name, description, last_changed_time) = (?, ?, ?)
 WHEN NOT MATCHED THEN
     INSERT (name, description, last_changed_time)
     VALUES (?, ?, ?)
 ELSE IGNORE;
  • SELECT IDENTITY_VAL_LOCAL()FROM SYSIMM.DUAL関数IDENTITY_VAL_LOCALはMERGE文のINSERTに対して、通常のINSERT文のように最後にデータベースに挿入したデータのID値を返すことはできません.この場合、通常のINSERT文しか使用できません.
  • WHEN MATCHED THEN MATCHEDの場合はUPDATEとDELETE文のみ使用可能でINSERT文は使用できません.
  • WHEN NOTE MATCHED THEN NOTE MATCHEDの場合、UPDATEとDELETE文は使用できず、INSERT文のみ使用できます.
  • WHEN[NOT]MATCHED AND(...AND...OR...)THENはデフォルトのMATCHED/NOT MATCHEDを使用するほか、追加の判断条件を指定することもできますが、MATCHEDと並ぶ条件はANDのみで、ANDではANDとORが使用できます.
  • 空の結果セットの影響上記の例では、プロジェクトテーブルにデータが存在するかどうかにかかわらず、クエリー結果に少なくとも1つのデータがあることを保証するために、擬似テーブル左外接続projectテーブルが使用されています.DUALを使用せずに直接プロジェクトをクエリーターゲットテーブルとして使用すると、ゼロレコードの結果セット、警告番号IWAQ 0003 Wが得られる可能性があり、このときON句の比較は何の意味もない可能性があります.NULLは任意の値と比較した結果、TRUEでもFALSEでもないため、結果は常にNULLになります.警告内容:No row was found for FETCH,UPDATE or DELETE;or the result of a query is an empty table.. SQLCODE=100, SQLSTATE=02000
  • ELSE IGNORE個人的にELSE IGNOREは廃棄物だと感じていますが、書くか書かないかは区別がないようで、運行結果は同じです.
  • UPDATEについて、DELETE/INSERTは2番目と3番目のルールについて、便利な記憶方法があります.MATCHEDの場合、条件を満たすデータがある場合はUPDATEまたはDELETE操作を行い、NOT MATCHEDの場合はINSERTの新しいデータを作成します.簡単に言えば、データがあれば更新または削除し、データがなければ挿入します.
  • 例外のデータ用MERGE文INSERTのデータはMERGEの分岐文では操作できません.
  • UPDATEの賦値構文UPDATEには、「column=?[,column=?]...」と「(column,column...)=(value,value...)」の2つの賦値構文があります.
  • SIGNALは、現在の文を終了するエラー信号を発行します.使用上は便利かもしれませんが、デザイン上はちょっと問題がありますが、SQL文で実行できるようなSTATEMENTはまだ見たことがありません.ストレージプログラムの機能に似ていて、異常を投げ出すのは、本当に奇妙で、不倫のNATIVE FEATUREです.SQLSTATEの公式解釈について:【SQLSTATE classes that begin with the characters '7' through '9' or 'I' through 'Z' may be defined. Within these classes, any subclass may be defined. SQLSTATE classes that begin with the characters '0' through '6' or 'A' through 'H' are reserved for the database manager. Within these classes, subclasses that begin with the characters '0' through'H'are reserved for the database manager.Subclasses that begin with the characters'I'through'Z'may be defined.].使用する場合、一般的には数字7-9またはアルファベットI-Zの先頭を使用して、私たち自身のSQLSTATEを定義し、長さは5.
  • いくつかの例:
    MERGE INTO project px
    USING (SELECT 1 AS VAL FROM SYSIBM.DUAL WHERE 1 = 2) py 
       ON VAL = 1
     WHEN MATCHED THEN
          SIGNAL SQLSTATE 'ZZ110'
             SET MESSAGE_TEXT = 'Kidding you?'
     WHEN NOT MATCHED THEN
          SIGNAL SQLSTATE 'ZZ911'
             SET MESSAGE_TEXT = 'Kidding me?'
     ELSE IGNORE;
    --        ,  MATCHED,   NOT MATCHED
    
    MERGE INTO project px
    USING (SELECT 1 AS VAL FROM SYSIBM.DUAL WHERE 1 = 1) py 
       ON VAL = 1
     WHEN MATCHED THEN
          SIGNAL SQLSTATE 'ZZ110'
             SET MESSAGE_TEXT = 'Kidding you?'
     WHEN NOT MATCHED THEN
          SIGNAL SQLSTATE 'ZZ911'
             SET MESSAGE_TEXT = 'Kidding me?'
     ELSE IGNORE;
    --    MATCHED
    -- Application raised error or warning with diagnostic text: "Kidding you?".. SQLCODE=-438, SQLSTATE=ZZ911
    
    MERGE INTO project px
    USING (SELECT 1 AS VAL FROM SYSIBM.DUAL WHERE 1 = 1) py 
       ON VAL = 2
     WHEN MATCHED THEN
          SIGNAL SQLSTATE 'ZZ110'
             SET MESSAGE_TEXT = 'Kidding you?'
     WHEN NOT MATCHED THEN
          SIGNAL SQLSTATE 'ZZ911'
             SET MESSAGE_TEXT = 'Kidding me?'
     ELSE IGNORE;
    --    NOT MATCHED
    -- Application raised error or warning with diagnostic text: "Kidding me?".. SQLCODE=-438, SQLSTATE=ZZ110
    

    上記の3つの例のELSE IGNOREはいずれも無視でき、最終結果には影響しない.
    公式文書参照:http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.admin.doc/doc/r0010873.htm