Tips

アップグレードしたデータファイルのプライマリーキー

日付2017/12/13
ID17-007
バージョンv14以降
プラットフォームWindows, Mac

プライマリーキー(主キー)が無かったバージョンの4Dで作成されたデータベースを4D v14以降にアップグレードした時、ストラクチャとデータファイルを同時にアップグレードした場合には、新しく追加したプライマリーキーに値がセットされ、そのまま運用することができます。

しかし、以前のバージョンでデータベースを運用しながら、ストラクチャに手を入れ、その後改修したストラクチャと以前のバージョンで運用していたデータファイルとを組み合わせて運用をしたいと考えるデベロッパは多いと思います。その場合、アップグレードしたデータファイルのプライマリーキーがセットされていないので、そのままでは運用することができません。運用を開始する前に重複していないプライマリーキーがセットされているかを確認する必要があります。

少々乱暴な方法ですが、UUIDの場合であれば、運用を開始する前に全てのプライマリーキーを再設定することも可能です。再設定後にジャーナルファイルを捨て、フルバックアップを行い運用を行うことで、プライマリーキーの問題に悩まされることはありません。

下記のコードは、全てのプライマリーキーにUUIDをセットし直すメソッドです。ただし運用前にのみ使用し、実行後は必ずジャーナルファイルを新規に作成し、運用後は絶対に実行してはいけません。

  //UUIDのプライマリーキーを全て更新して新しいUUIDをセットする

  //参考記事URL
  ///blog/tech-tips-2014-07-28.html#anchor4

  // プライマリーキーをもった全テーブルのテーブル番号を配列化
ARRAY LONGINT($pk_TableIDs;0)
Begin SQL
	   SELECT TABLE_ID
	   FROM _USER_CONSTRAINTS 
	   WHERE CONSTRAINT_TYPE = 'P' 
	   INTO :$pk_TableIDs;
End SQL

  // プライマリーキーをもった全テーブルに対してループして処理する
C_LONGINT($i)  //ループ用
C_LONGINT($table_id)  //テーブル番号
C_POINTER($table_p)  //テーブルポインタ
C_LONGINT($field_id)  //フィールド番号(プライマリーキーフィールド用)
C_POINTER($field_p)  //フィールドポインタ
For ($i;1;Size of array($pk_TableIDs))
	$table_id:=$pk_TableIDs{$i}
	  //プライマリーキーフィールドの番号を得る
	Begin SQL
		SELECT COLUMN_ID
		FROM _USER_CONS_COLUMNS
		WHERE TABLE_ID = :$table_id
		INTO :$field_id;
	End SQL
	  //プライマリーキーのフィールドタイプが文字列ならUUIDとして全レコードを更新
	If (Type(Field($table_id;$field_id)->)=Is alpha field)
		PAUSE INDEXES(Table($table_id)->)  //インデックス作成を中断
		ALL RECORDS(Table($table_id)->)
		$table_p:=Table($table_id)
		$field_p:=Field($table_id;$field_id)
		APPLY TO SELECTION($table_p->;$field_p->:=Generate UUID)  //ロックされ更新できなかったレコードに注意
		RESUME INDEXES(Table($table_id)->)  //インデックス作成を再開
	End if 
End for 

関連情報