Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

外部キーの使用法

外部キーを定義して、テーブル間の参照整合性を強制できます。外部キー制約を持つテーブルを変更する際に、外部キー制約が確認されます。

外部キーの定義

Caché SQL で外部キーを定義するには、以下のような方法があります。

1 つのテーブル (クラス) のための外部キーの最大数は 400 です。

外部キーの参照整合性チェック

既定では、Caché は INSERTUPDATEDELETE の各操作に対して、外部キーの参照整合性チェックを実行します。操作が参照整合性に違反する場合、その操作は行われず、その操作によって SQLCODE -121、-122、-123、-124 のいずれかのエラーが発行されます。参照整合性チェックに失敗すると、以下のようなエラーが生成されます。

ERROR #5540: SQLCODE: -124 Message: At least 1 Row exists in table 'HealthLanguage.FKey2' 
which references key NewIndex1 - Foreign Key Constraint 'NewForeignKey1' (Field 'Pointer1') 
failed on referential action of NO ACTION [Execute+5^CacheSql16:USER] 

このチェックは、以下のいずれかを使用してシステム全体で抑制できます。

  • 管理ポータルに移動します。[システム管理] から、[構成][SQL およびオブジェクトの設定][一般SQL設定] (システム, 構成, 一般SQL設定) を選択します。この画面で、[INSERT、UPDATE、DALETE の外部キーについて参照整合性チェックを実行する] の現在の設定を表示できます。既定は “はい” です。

  • $SYSTEM.SQL.SetFilerRefIntegrity()Opens in a new tab メソッドを呼び出します。

永続クラス定義を使用してテーブルを定義する場合、NoCheck キーワードを指定して外部キーを定義すると、その外部キーの今後のチェックを抑制できます。CREATE TABLE にはこのキーワード・オプションはありません。

特定の操作のチェックを抑制するには、%NOCHECK キーワード・オプションを使用します。

既定では、Caché は次の各操作に対して、外部キーの参照整合性チェックを実行します。指定されたアクションが参照整合性に違反する場合、このコマンドは実行されません。

  • ALTER TABLE DROP COLUMN。

  • ALTER TABLE DROP CONSTRAINT。SQLCODE -317 を発行します。外部キーの整合性チェックは、SET OPTION COMPILEMODE=NOCHECK を使用して抑制できます。

  • DROP TABLE。SQLCODE -320 を発行します。外部キーの整合性チェックは、SET OPTION COMPILEMODE=NOCHECK を使用して抑制できます。

  • TRUNCATE TABLE (DELETE と同様の考慮事項が適用されます)。

  • トリガ・イベント (BEFORE イベントなど)。例えば、DELETE 操作が外部キーの参照整合性に違反するために実行されない場合、BEFORE DELETE トリガは実行されません。

親テーブルと子テーブルの識別

埋め込み SQL では、ホスト変数配列を使用して、親テーブルと子テーブルを識別できます。子テーブルの場合、ホスト変数配列の添え字 0 は parentref または parentref||childref の形式で親参照に設定されています。親テーブル場合、添え字 0 は未定義です。詳細は、以下の例を参照してください。

  &sql(SELECT *,%TABLENAME INTO :tflds(),:tname
        FROM Aviation.Event )
   IF SQLCODE=0 {
       IF $DATA(tflds(0)) {
       WRITE tname," is a child table",!,"parent ref: ",tflds(0),! }
       ELSE {WRITE tname," is a parent table",! }
   }
   ELSE {WRITE "SQLCODE error=",SQLCODE,! }
  &sql(SELECT *,%TABLENAME INTO :tflds(),:tname
        FROM Aviation.Aircraft )
   IF SQLCODE=0 {
       IF $DATA(tflds(0)) {
       WRITE tname," is a child table",!,"parent ref: ",tflds(0),! }
       ELSE {WRITE tname," is a parent table",! }
   }
   ELSE {WRITE "SQLCODE error=",SQLCODE,! }
  &sql(SELECT *,%TABLENAME INTO :tflds(),:tname
        FROM Aviation.Crew )
   IF SQLCODE=0 {
       IF $DATA(tflds(0)) {
       WRITE tname," is a child table",!,"parent ref: ",tflds(0),! }
       ELSE {WRITE tname," is a parent table",! }
   }
   ELSE {WRITE "SQLCODE error=",SQLCODE,! }
FeedbackOpens in a new tab