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?

ALTER TABLE

テーブルを変更します。

Synopsis

ALTER TABLE table alter-action

where alter-action is one of the following:
     ADD  [(] add-action {,add-action} [)] |
     DROP drop-action |
     DELETE drop-action |
     ALTER [COLUMN] identifier alter-column-action |
     MODIFY modification-spec 

add-action ::= 
     [CONSTRAINT table]
     [(] FOREIGN KEY (identifier-commalist) 
          REFERENCES table (identifier-commalist)
          [referential-action] [)]
     |
     [(] UNIQUE (identifier-commalist)  [)] 
     |
     [(] PRIMARY KEY (identifier-commalist) [)] 
     | 
     DEFAULT [(] default-spec [)] FOR identifier
     |
     [COLUMN] [(] identifier datatype  [sqlcollation] 
           [%DESCRIPTION literal]
           [DEFAULT [(] default-spec [)] ]
           [UNIQUE] [NOT NULL]
           [REFERENCES table (identifier-commalist) ]
           [)]

drop-action ::= 
     FOREIGN KEY identifier |
     PRIMARY KEY |
     CONSTRAINT identifier |
     [COLUMN] identifier [RESTRICT | CASCADE] 

alter-column-action ::= 
     SET DEFAULT [(]default-spec[)] |
     DEFAULT [(]default-spec[)] |
     DROP DEFAULT | 
     NULL | 
     NOT NULL | 
     COLLATE sqlcollation |
     datatype 

modification-spec ::=
     identifier [datatype] 
          [DEFAULT [(]default-spec[)]]
          [CONSTRAINT identifier] [NULL] [NOT NULL]

sqlcollation ::=
     { %ALPHAUP | %EXACT | %MINUS | %MVR | %PLUS | %SPACE |   
        %SQLSTRING [(maxlen)] | %SQLUPPER [(maxlen)] |
        %STRING [(maxlen)] | %TRUNCATE[(maxlen)] | %UPPER  }

引数

table 変更するテーブルの名前。
identifier 変更する列の名前。有効な識別子の詳細は、"Caché SQL の使用法" の “識別子“ の章を参照してください。
identifier-commalist 列、またはコンマ区切りの列のリストの名前。identifier-commalist は、列が 1 つしか指定されていない場合でも括弧で囲む必要があります。有効な識別子の詳細は、"Caché SQL の使用法" の “識別子“ の章を参照してください。
datatype Caché SQL の有効なデータ型。有効なデータ型の一覧は、このドキュメント末尾の SQL リファレンス資料を参照してください。
default-spec このフィールドがユーザ指定のデータ値でオーバーライドされない場合に、このフィールドに自動的に入力される既定のデータ値。使用できる値は、リテラル値、以下のキーワード・オプションのいずれか (NULL、USER、CURRENT_USER、SESSION_USER、SYSTEM_USER、CURRENT_DATE、CURRENT_TIME、および CURRENT_TIMESTAMP)、または OBJECTSCRIPT 式です。既定値として長さゼロの SQL 文字列は使用しないでください。詳細は、"CREATE TABLE" を参照してください。
COLLATE sqlcollation オプション — SQL 照合タイプ (%EXACT、%MINUS、%PLUS、%SPACE、%SQLSTRING、%SQLUPPER、%TRUNCATE、または %MVR) のいずれかを指定します。既定は、ネームスペースの既定の照合です (変更していない場合は %SQLUPPER です)。照合タイプ %ALPHAUP、%STRING、および %UPPER は非推奨であるため、使用しないでください。%SQLSTRING、%SQLUPPER、%STRING、および %TRUNCATE は、オプションの最大長のトランケーション引数である、括弧で囲んだ整数を指定できます。これらの照合パラメータ・キーワードの先頭のパーセント記号 (%) はオプションです。COLLATE キーワードはオプションです。詳細は、"Caché SQL の使用法" の “照合” の章にある "テーブルのフィールド/プロパティ定義の照合" を参照してください。

概要

ALTER TABLE 文は、要素の追加や削除または既存の要素の修正を行い、テーブルを変更します。1 つの ALTER TABLE 文で実行できる処理は 1 種類のみです。ただし、ALTER TABLE ADD 文は、複数の列および/または制約をテーブルに追加できます。ALTER TABLE DROP 文と ALTER TABLE DELETE 文は同義語です。

指定のテーブルが現在のネームスペースに存在するかどうかを確認するには、$SYSTEM.SQL.TableExists()Opens in a new tab メソッドを使用します。

特権とロック

ALTER TABLE コマンドは特権を必要とする操作です。ALTER TABLE を使用する前に、%ALTER_TABLE 管理者特権または指定されたテーブルに対する %ALTER オブジェクト特権があることを確認する必要があります。特権がない場合は、SQLCODE -99 エラー (特権違反) が返されます。%CHECKPRIV コマンドを呼び出すことにより、現在のユーザが %ALTER 特権を持っているかどうかを確認できます。$SYSTEM.SQL.CheckPriv()Opens in a new tab メソッドを呼び出すことにより、指定のユーザが %ALTER 特権を持っているかどうかを確認できます。適切な特権を持っている場合は、GRANT コマンドを使用して %ALTER_TABLE 特権または %ALTER 特権を割り当てることができます。埋め込み SQL では、以下のように $SYSTEM.Security.Login()Opens in a new tab メソッドを使用して適切な特権を持ったユーザとしてログインできます。

   DO $SYSTEM.Security.Login("_SYSTEM","SYS")
   &sql(      )

$SYSTEM.Security.Login メソッドを呼び出すには、%Service_Login:Use 特権が必要です。詳細は、"インターシステムズ・クラス・リファレンス" の "%SYSTEM.SecurityOpens in a new tab" を参照してください。

ALTER TABLE は、テーブル・クラスの定義に [DdlAllowed] が含まれている場合を除き、永続クラスを定義して作成したテーブルでは使用できません。使用すると、操作は SQLCODE -300 エラーで失敗し、%msg が”DDL がクラス schema.tablename に対して有効になっていません”に設定されます。

ALTER TABLE 文は table に対してテーブル・レベルのロックを取得します。これにより、他のプロセスはこのテーブルのデータを変更できなくなります。このロックは ALTER TABLE 操作が終了すると自動的に解除されます。ALTER TABLE は対応するクラス定義をロックする際に、現在のプロセスに対して SQL ロック・タイムアウト設定を使用します。

ADD COLUMN の制限

ALTER TABLE は、単一の列、またはコンマ区切りの列のリストを追加できます。

ALTER TABLEtablename ADD COLUMN 文を使用してテーブルにフィールドを追加することを考えます。

  • その名前の列が既に存在している場合、この文は失敗し SQLCODE -306 エラーが発生します。

  • この文で、列に NOT NULL 制約を設定し、さらに既定値を設定しない場合、そのテーブルに既にデータがあると、この文はエラーになります。これは、DDL 文が完了した後では NOT NULL 制約は既存の行すべてを満たさないためです。その結果、エラー・コード SQLCODE -304 が生成されますが、これはデータが存在するテーブルに、既定値のない NOT NULL フィールドを追加しようとするためです。

  • この文で、列に NOT NULL 制約を設定し、さらに既定値を設定した場合、テーブルにある既存の行は更新され、追加したフィールドの列には設定した既定値が割り当てられます。

  • この文で、列に NOT NULL 制約を設定せず、既定値を設定した場合は、既存のどの行の列でもデータは更新されません。これらの行に対する列の値は NULL です。

この既定の NOT NULL 制約の動作を変更するには、"SET OPTION" コマンドの "COMPILEMODE=NOCHECK" を参照してください。

“ID” という名前の通常のデータ・フィールドを指定し、RowID フィールドが既に “ID” (既定) という名前である場合、ADD COLUMN 操作は成功します。ALTER TABLE は ID データ列を追加し、RowId 列を “ID1” に名前変更して名前の重複を回避します。

整数カウンタの追加

ALTER TABLE tablename ADD COLUMN 文を使用してテーブルに整数カウンタ・フィールドを追加しようとすると、以下のようになります。

  • テーブルに IDENTITY フィールドが存在しない場合、テーブルに IDENTITY フィールドを追加できます。テーブルに IDENTITY フィールドが既に存在する場合、ALTER TABLE 操作は SQLCODE -400 エラーで失敗し、%msg は "エラー #5281: クラスに複数のidentityプロパティが定義されています: 'Sample.MyTest::MyIdent2'" になります。このフィールドの定義に ADD COLUMN を使用する場合、Caché は対応する RowID 整数値を使用して、このフィールドの既存のデータ行を入力します。

    CREATE TABLEビットマップ・エクステント・インデックスを定義して、後でテーブルに IDENTITY フィールドを追加した場合、IDENTITY フィールドが MINVAL が 1 以上の %BigInt、%Integer、%SmallInt、または %TinyInt のデータ型ではなく、テーブルにデータがないときは、システムは自動的にビットマップ・エクステント・インデックスを削除します。

  • テーブルに 1 つ以上の Serial (%Library.CounterOpens in a new tab) フィールドを追加できます。ADD COLUMN を使用してこのフィールドを定義する場合、このフィールドの既存のデータ行は NULL です。UPDATE を使用して、このフィールドの NULLである既存のデータ行に値を指定することができます。UPDATE を使用して非 NULL 値を変更することはできません。

  • テーブルに ROWVERSION フィールドが存在しない場合、ROWVERSION フィールドを追加できます。テーブルに ROWVERSION フィールドが既に存在する場合、ALTER TABLE 操作は SQLCODE -400 エラーで失敗し、%msg は "エラー #5320: クラス 'Sample.MyTest' にタイプ %Library.RowVersion のプロパティが複数あります。許されるのは 1 つだけです。プロパティ: MyVer、MyVer2" になります。ADD COLUMN を使用してこのフィールドを定義する場合、このフィールドの既存のデータ行は NULL です。NULL である ROWVERSION 値を更新することはできません。

ALTER COLUMN の制限

データが含まれている列のデータ型を変更することでストリーム・データが非ストリーム・データになる場合、または非ストリーム・データがストリーム・データになる場合、そのデータ型変更は実行できません。これを実行しようとすると、SQLCODE -374 エラーが返されます。既存のデータがない場合は、このデータ型の変更が可能です。

データを含む列の照合タイプを変更する場合は、その列のすべてのインデックスを再構築する必要があります。

DROP COLUMN の制限

列定義を削除しても、その列に格納されているデータはデータマップから削除されません。

列の定義を削除しても、対応する列レベルの特権は削除されません。例えば、その列でデータを挿入、更新、または削除するためにユーザに与えられた特権です。これは、以下のような影響があります。

  • 列が削除され、同じ名前を持つ別の列が追加されると、ユーザとロールは新しい列でも古い列で持っていたのと同じ特権を持ちます。

  • 列が削除されても、その列のオブジェクト特権を削除することはできません。

この理由により、通常は列定義を削除する前に、REVOKE コマンドを使用して、列レベルの特権を削除することをお勧めします。

列がインデックスで使用されている場合や、外部キー制約または他の独自の制約で定義されている場合、その列を削除することはできません。その列を削除しようとすると、SQLCODE -322 エラーが発生して失敗します。"DROP INDEX" を参照してください。

列が COMPUTECODE 節内または COMPUTEONCHANGE 節内で使用されている場合は、その列を削除することはできません。これを実行しようとすると、SQLCODE -400 エラーが返されます。

ADD PRIMARY KEY の制限

一意でないデータを含むフィールド、または NULL 値の入力が認められているフィールドには、主キー制約を追加できません。

既存のフィールドに主キー制約を追加する場合、フィールドが自動的に IDKey インデックスとして定義されることもあります。これはデータが存在するかどうか、および構成設定が以下のいずれかの方法で設定されているかどうかによります。

  • SQL SET OPTION PKEY_IS_IDKEY 文

  • $SYSTEM.SQL.SetDDLPKeyNotIDKey()Opens in a new tab メソッド呼び出し。現在の設定を確認するには、$SYSTEM.SQL.CurrentSettings()Opens in a new tab を呼び出します。

  • 管理ポータルに進み、システム, 構成, 一般SQL設定 を選択します。[DDL 経由で作成された主キーが ID キーではない] の現在の設定を表示します。“はい” (1) に設定すると、主キー制約が DDL で指定されたときに、自動的にクラス定義の IDKey インデックスになりません。“いいえ” (0) の場合は、IDKey インデックスになります。この値を “いいえ” に設定すると、通常パフォーマンスが向上します。しかし、主キーのフィールドを更新できなくなります。

既定値は “はい” (1) です。このオプションが “いいえ” (0) に設定されていて、このフィールドにデータがない場合、主キー・インデックスも IDKey インデックスとして定義されます。このオプションが “いいえ” に設定されていて、このフィールドにデータがある場合、IDKey インデックスは定義されません。

CREATE TABLEビットマップ・エクステント・インデックスを定義している場合に、後で ALTER TABLE を使用して IDKey でもある主キーを追加すると、システムは自動的にビットマップ・エクステント・インデックスを削除します。

主キーが既に存在する場合に主キーを作成する

主キーが既に定義されているテーブルに他の主キーを作成しようとすると、設定によって結果が異なります。既定では、主キーが既に存在する場合、Caché は主キーの定義を拒否し、SQLCODE -307 エラーを発行します。この振る舞いは、以下のように設定します。

  • $SYSTEM.SQL.SetDDLNo307()Opens in a new tab メソッド呼び出し。現在の設定を確認するには、$SYSTEM.SQL.CurrentSettings()Opens in a new tab を呼び出します。これにより、[SQLCODE=-307 エラーの抑制] の設定が表示されます。

  • 管理ポータルに進み、システム, 構成, 一般SQL設定 を選択します。[既存キーに対して DDL の Create Primary Key を許可] の現在の設定を表示します。

既定値は “いいえ” (0) です。ここでは、この設定を推奨します。

このオプションが “はい” (1) に設定されていると、ALTER TABLE ADD PRIMARY KEY により、Caché は主キー・インデックスをクラス定義から削除し、指定の主キー・フィールドを使用したインデックスを再生成します。

ただし、既存の主キーが存在する状態で主キーを作成できるようにこのオプションを設定していても、テーブルにデータがある場合は、IDKey インデックスを兼ねる主キー・インデックスは再作成できません。これを実行しようとすると、SQLCODE -307 エラーが生成されます。

ADD FOREIGN KEY の制限

既定では、同じ名前の 2 つの外部キーを持つことはできません。これを実行しようとすると、SQLCODE -311 エラーが生成されます。このオプションは、以下の手段で設定可能です。

  • $SYSTEM.SQL.SetDDLNo311()Opens in a new tab メソッド呼び出し。現在の設定を確認するには、$SYSTEM.SQL.CurrentSettings()Opens in a new tab を呼び出します。これにより、[SQLCODE=-311 エラーの抑制] の設定が表示されます。

  • 管理ポータルに進み、システム, 構成, 一般SQL設定 を選択します。[外部キーが存在する時に DDL ADD 外部キー制約を許可する] の現在の設定を表示します。

既定値は “いいえ” (0) です。この設定を推奨します。“はい” (1) の場合、同じ名前が存在しても、DDL を使用して外部キーを追加できます。“いいえ” (0) の場合は、この操作を実行すると、SQLCODE -311 エラー・コードが発行されます。

テーブル定義では、同じ identifier-commalist フィールドを参照して相反する参照アクションを実行する、名前が異なる 2 つの外部キーを指定することはできません。同一のフィールドに対して相反する参照アクションを実行する 2 つの外部キーを定義した場合 (例 : ON DELETE CASCADE と ON DELETE SET NULL)、Caché SQL は ANSI 標準に従い、エラーを生成しません。この代わりに Caché SQL では、DELETE 処理または UPDATE 処理でこのような相反する外部キー定義に遭遇したときにエラーを生成します。

存在しない外部キー・フィールドを ADD FOREIGN KEY で指定すると、SQLCODE -31 エラーが発生します。

存在しない親キー・テーブルを ADD FOREIGN KEY で参照すると、SQLCODE -310 エラーが発生します。既存の親キー・テーブルに存在しないフィールドを ADD FOREIGN KEY で参照すると、SQLCODE -316 エラーが発生します。親キー・フィールドを指定していない場合、既定の ID フィールドになります。

ADD FOREIGN KEY の発行前、ユーザは、参照されるテーブルまたは参照されるテーブルの列の REFERENCES 特権を持っている必要があります。REFERENCES 特権は、ダイナミック SQL または xDBC を介して ALTER TABLE を実行する場合に必要になります。

一意でない値を設定できるフィールド (またはフィールドの組み合わせ) を ADD FOREIGN KEY で参照すると、SQLCODE -314 エラーが発生して、%msg に追加の詳細が表示されます。

テーブルにデータがある場合は、ADD FOREIGN KEY は制約されます。この既定の制約の動作を変更するには、"SET OPTION" コマンドの "COMPILEMODE=NOCHECK オプション" を参照してください。

単一のフィールドのために ADD FOREIGN KEY 制約を定義し、外部キーが参照先テーブルの idkey を参照する場合は、Caché によって外部キー内のプロパティが参照プロパティに変換されます。この変換は、以下の制限に従います。

  • テーブルにデータを含めることはできません。

  • 外部キーに関するプロパティを永続クラスのプロパティにできません (つまり、既に参照プロパティにできません)。

  • 外部キー・フィールドおよび参照先 idkey フィールドのデータ型とデータ型パラメータは同じである必要があります。

  • 外部キー・フィールドを IDENTITY フィールドにすることはできません。

外部キーの詳細は、"CREATE TABLE" コマンド、および "Caché SQL の使用法" の “外部キーの使用法” の章を参照してください。

DROP CONSTRAINT の制限

既定では、外部キー制約によって参照されている一意キー制約または主キー制約は削除できません。これを実行しようとすると、SQLCODE -317 エラーが返されます。この既定の外部キー制約の動作を変更するには、"SET OPTION" コマンドの "COMPILEMODE=NOCHECK オプション" を参照してください。

主キー制約の削除による影響は、上記のように [主キーも ID キーである] 設定の内容によって異なります。

  • PrimaryKey インデックスが IDKey インデックスを兼ねていない場合、主キー制約を削除すると PrimaryKey インデックスの定義が削除されます。

  • PrimaryKey インデックスが IDKey インデックスを兼ねていて、テーブルにデータがない場合、主キー制約を削除するとインデックスの定義全体が削除されます。

  • PrimaryKey インデックスが IDKey インデックスを兼ねていて、テーブルにデータがある場合、主キー制約を削除すると、IDKey インデックスの定義から PRIMARYKEY 修飾子のみが削除されます。

存在しない制約の削除

制約を持たないフィールドのフィールド制約を削除しようとした場合、構成設定によって結果が異なります。

  • $SYSTEM.SQL.SetDDLNo315()Opens in a new tab メソッド呼び出し。現在の設定を確認するには、$SYSTEM.SQL.CurrentSettings()Opens in a new tab を呼び出します。これにより、[SQLCODE=-315 エラーの抑制] の設定が表示されます。

  • 管理ポータルに進み、システム, 構成, 一般SQL設定 を選択します。[存在しない制約に対して DDL の DROP を許可] の現在の設定を表示します。

既定値は “いいえ” (0) です。既定では、制約が存在しない場合、Caché は制約の削除を拒否し、SQLCODE -315 エラーを発行します。しかし、“はい” (1) に設定されていると、ALTER TABLE DROP CONSTRAINT により、Caché は処理を実行せず、エラー・メッセージを発行しません。

以下の例では 2 つの埋め込み SQL プログラムを使用して、テーブルを作成し、2 行を生成してからテーブルの定義を変更します。ALTER TABLE コマンドは ColorPreference 列を作成し、その列で既存の 2 つの行に対応するフィールドに値 'Blue' を入力します。

この動作をはっきり示すために、2 つの埋め込み SQL プログラムは示されている順序で実行してください(埋め込み SQL では参照されるテーブルが既に存在していなければ INSERT 文をコンパイルすることができないため、ここでは 2 つの埋め込み SQL プログラムを使用する必要があります)。

  DO $SYSTEM.Security.Login("_SYSTEM","SYS")
  &sql(DROP TABLE SQLUser.MyStudents)
      IF SQLCODE=0 { WRITE !,"Deleted table" }
      ELSE { WRITE "DROP TABLE error SQLCODE=",SQLCODE }
  &sql(CREATE TABLE SQLUser.MyStudents (
     Id      INT NOT NULL,
     Name    VARCHAR(35),
     DOB     DATE,
     CONSTRAINT MyStudentsPK PRIMARY KEY (Id) )
     )
     IF SQLCODE=0 { WRITE !,"Created table" }
     ELSE { WRITE "CREATE TABLE error SQLCODE=",SQLCODE }
  DO $SYSTEM.Security.Login("_SYSTEM","SYS")
  NEW SQLCODE,%msg
  &sql(INSERT INTO SQLUser.MyStudents (Id, Name, DOB) 
    VALUES (1, 'David Vanderbilt', 46639))
  IF SQLCODE=0 { WRITE !,"Inserted data in table"}
  ELSE { WRITE !,"SQLCODE=",SQLCODE,": ",%msg }
  &sql(INSERT INTO SQLUser.MyStudents (Id, Name, DOB) 
    VALUES (2, 'Mary Smith', 49759))
  IF SQLCODE=0 { WRITE !,"Inserted data in table"}
  ELSE { WRITE !,"SQLCODE=",SQLCODE,": ",%msg }
  &sql(ALTER TABLE SQLUser.MyStudents 
    ADD COLUMN ColorPreference %String NOT NULL DEFAULT 'Blue')
  IF SQLCODE=0 {
    WRITE !,"Altered table, SQLCODE=",SQLCODE }
  ELSEIF SQLCODE=-306 {
    WRITE !,"SQLCODE=",SQLCODE,": ",%msg }
  ELSE { WRITE "SQLCODE error=",SQLCODE }

データを表示するには、管理ポータルで SAMPLES ネームスペースの [グローバル] オプションを選択します。"SQLUser.MyStudentsD" までスクロールし、[データ] オプションをクリックします。

関連項目

FeedbackOpens in a new tab