Skip to main content

ALTER TABLE (SQL)

テーブルを変更します。

構文

ADD
ALTER TABLE table ADD [CONSTRAINT identifier] 
  ( FOREIGN KEY (field-commalist) 
    REFERENCES table (field-commalist) 
    [ON DELETE ref-action] 
    [ON UPDATE ref-action] 
    [NOCHECK]
  )
ALTER TABLE table ADD ( UNIQUE (field-commalist) )
ALTER TABLE table ADD ( PRIMARY KEY (field-commalist) )
ALTER TABLE table ADD DEFAULT ( default-spec ) FOR field
ALTER TABLE table ADD COLUMN ( field datatype  [sqlcollation]  
  [%DESCRIPTION string] [DEFAULT [(] default-spec [)] ]   
  [ON UPDATE update-spec ] [UNIQUE] [NOT NULL] 
  [REFERENCES table (field-commalist)
  [ON DELETE ref-action] [ON UPDATE ref-action]  
  [NOCHECK] )
ALTER COLUMN
ALTER TABLE table ALTER COLUMN field alter-column-action
ALTER TABLE table ALTER COLUMN field RENAME newfieldname
ALTER TABLE table ALTER COLUMN field datatype
ALTER TABLE table ALTER COLUMN field SET DEFAULT ( default-spec ) 
ALTER TABLE table ALTER COLUMN field DROP DEFAULT
ALTER TABLE table ALTER COLUMN field NULL
ALTER TABLE table ALTER COLUMN field NOT NULL
ALTER TABLE table ALTER COLUMN field COLLATE sqlcollation
CLEANUP
ALTER TABLE table CLEANUP
CONVERT
ALTER TABLE table CONVERT TO SHARDED KEY (identifier, ...) defer
ALTER TABLE table CONVERT TO SHARDED KEY (identifier, ...) 
  COSHARD WITH ( coshardtable ) defer
ALTER TABLE table CONVERT TO NONSHARDED defer

ALTER TABLE table CONVERT TO STORAGETYPE = ROW delData
ALTER TABLE table CONVERT COLUMNS field-commalist 
  TO STORAGETYPE = ROW delData

ALTER TABLE table CONVERT TO STORAGETYPE = COLUMNAR delData
ALTER TABLE table CONVERT COLUMNS field-commalist 
  TO STORAGETYPE = COLUMNAR delData
DROP または DELETE
ALTER TABLE table DROP COLUMN field 
  [RESTRICT | CASCADE] delData
ALTER TABLE table DROP FOREIGN KEY identifier
ALTER TABLE table DROP PRIMARY KEY    
ALTER TABLE table DROP CONSTRAINT identifier

ALTER TABLE table DELETE COLUMN field 
  [RESTRICT | CASCADE] delData
ALTER TABLE table DELETE FOREIGN KEY identifier
ALTER TABLE table DELETE PRIMARY KEY    
ALTER TABLE table DELETE CONSTRAINT identifier
MODIFY
ALTER TABLE table MODIFY oldfieldname RENAME newfieldname
ALTER TABLE table MODIFY field [datatype] 
  [DEFAULT ( default-spec )] 
  [CONSTRAINT identifier] [ NULL | NOT NULL ]
PARTITION
ALTER TABLE table MOVE PARTITION BETWEEN partID AND partID TO database
ALTER TABLE table MOVE PARTITION ID partID TO database
ALTER TABLE table MOVE PARITION ID BETWEEN partVal AND partVal TO database

ALTER TABLE table CONVERT PARTITION ON
ALTER TABLE table CONVERT PARTITION OFF
ALTER TABLE table CONVERT PARTITION BY RANGE (field) INTERVAL partInterval
ALTER TABLE table CONVERT PARTITION BY HASH (field) IN numPart PARTITIONS
ALTER TABLE table CONVERT PARTITION BY LIST (field)

ALTER TABLE table DROP PARTITION ID partID
ALTER TABLE table DROP PARTITION BETWEEN partVal AND partVal
ALTER TABLE table DROP ALL PARTITIONS

ALTER TABLE table TRUNCATE PARTITION ID partID
ALTER TABLE table TRUNCATE PARTITION BETWEEN partVal AND partVal
RENAME
ALTER TABLE table RENAME table
STATS
ALTER TABLE table DROP FIXED STATISTICS
ALTER SCHEMA schema DROP FIXED STATISTICS

ALTER TABLE table FIX STATISTICS
ALTER SCHEMA schema FIX STATISTICS

ALTER TABLE table SET RUNTIME IGNOREFIXEDSTATS = boolean
ALTER TABLE table SET RUNTIME SKIPAUTOMATICSTATSCOLLECTION = boolean
ALTER SCHEMA schema SET RUNTIME IGNOREFIXEDSTATS = boolean
ALTER SCHEMA table SET RUNTIME SKIPAUTOMATICSTATSCOLLECTION = boolean

引数

引数 説明
table 変更するテーブルの名前。 テーブル名は修飾 (schema.table)、未修飾 (table) のどちらでもかまいません。テーブル名が未修飾の場合は、既定のスキーマ名が使用されます。スキーマ検索パスの値は使用されません。
identifier 制約に割り当てられた一意の名前。有効な識別子である必要があります。
field 変更 (追加、修正、削除) する列の名前。有効な識別子である必要があります。
field-commalist 列、またはコンマ区切りの列のリストの名前。field-commalist は、列が 1 つしか指定されていない場合でも括弧で囲む必要があります。"識別子" を参照してください。
datatype InterSystems SQL の有効なデータ型。"Data Types (SQL)" を参照してください。
default-spec このフィールドがユーザ指定のデータ値でオーバーライドされない場合に、このフィールドに自動的に入力される既定のデータ値。使用できる値は、リテラル値、以下のキーワード・オプションのいずれか (NULL、USER、CURRENT_USER、SESSION_USER、SYSTEM_USER、CURRENT_DATE、CURRENT_TIME、および CURRENT_TIMESTAMP)、または OBJECTSCRIPT 式です。既定値として長さゼロの SQL 文字列は使用しないでください。詳細は、"CREATE TABLE" を参照してください。
modification-spec "CREATE TABLE" の "ON UPDATE" を参照してください。
COLLATE sqlcollation オプション — SQL 照合タイプとして、%EXACT、%MINUS、%MVR、%PLUS、%SPACE、%SQLSTRING、%SQLUPPER、%TRUNCATE のいずれかを指定します。既定は、ネームスペースの既定の照合です (変更していない場合は %SQLUPPER です)。%SQLSTRING、%SQLUPPER、および %TRUNCATE は、オプションの最大長のトランケーション引数である、括弧で囲んだ整数を指定できます。これらの照合パラメータ・キーワードの先頭のパーセント記号 (%) はオプションです。COLLATE キーワードはオプションです。詳細は、"テーブルのフィールド/プロパティ定義の照合" を参照してください。
convert-option シャード・テーブルをシャード化されていないテーブルに変換するか、その逆の変換を行うかを指定します。
defer 必ずオプション。DEFER または IMMEDIATE
del-data 必ずオプション。%DELDATA または %NODELDATA
partID 変更するパーティションの ID。INFORMATION_SCHEMA.TABLE_PARTITIONS をクエリすることで確認できます。
partVal 範囲の上限または下限として機能する、パーティション分割列での値です。
partCol パーティションで変更する列。
partInterval 期間 n MINUTE/HOUR/DAY/MONTH/YEAR (n は整数)、またはパーティション間隔の長さを指定する整数。
numPart 作成されたパーティションの数。

説明

ALTER TABLE 文は、要素の追加や削除または既存の要素の修正を行い、テーブル定義を変更します。1 つの ALTER TABLE 文で実行できる処理は 1 種類のみです。

ALTER TABLE DROP キーワードと ALTER TABLE DELETE キーワードは同義語です。

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

特権とロック

ALTER TABLE コマンドは特権を必要とする操作です。ALTER TABLE を実行するには、ユーザは %ALTER_TABLE 管理特権を持っている必要があります。持っていない場合、SQLCODE –99 エラーが発生し、%msg が "ユーザ 'name' は %ALTER_TABLE 特権を持っていません" に設定されます。

ユーザは、指定されたテーブルに対する %ALTER 特権を持っている必要があります。ユーザがテーブルの所有者 (作成者) である場合、ユーザにはそのテーブルに対する %ALTER 特権が自動的に付与されます。そうでない場合は、ユーザにテーブルに対する %ALTER 特権を付与する必要があります。持っていない場合、SQLCODE –99 エラーが発生し、%msg が "ユーザ 'name' は 'Schema.TableName' のテーブル定義を変更するために必要な %ALTER 特権を持っていません。" に設定されます。

現在のユーザが %ALTER 特権を持っているかどうかを確認するには、%CHECKPRIV コマンドを呼び出します。指定のユーザが %ALTER 特権を持っているかどうかを確認するには、$SYSTEM.SQL.Security.CheckPrivilege()Opens in a new tab メソッドを呼び出します。

必要な管理特権を割り当てるには、%ALTER_TABLE 特権で GRANT コマンドを使用します。これには適切な付与特権が必要です。%ALTER オブジェクト特権を割り当てるには、以下を使用できます。

  • GRANT コマンドと %ALTER 特権。これには適切な付与特権が必要です。

  • ロールまたはユーザを編集するためページの管理ポータルの [SQL Tables] タブにある、目的のテーブルの [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 は、導入済みの永続クラスから投影されたテーブルでは使用できません。この操作は SQLCODE -400 エラーで失敗し、%msg が “導入済みのクラス classname を変更する DDL を実行できません” に設定されます。

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

テーブルを変更する場合、そのテーブルを別のプロセスによって EXCLUSIVE MODE または SHARE MODE でロックしないでください。ロックされているテーブルを変更しようとすると、SQLCODE -110 エラーになり、%msg は "テーブル 'Sample.MyTest' の排他テーブルロックを取得できません" になります。

ADD

ADD COLUMN の制限

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

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

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

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

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

  • この文で、列に 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 を使用してこのフィールドを定義する場合、対応する RowID 整数値を使用して InterSystems IRIS はこのフィールドで既存データ行を入力します。

    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 値を更新することはできません。

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

主キーは 1 つしか定義できません。既定では、InterSystems IRIS は、主キーが既に存在する場合に主キーを定義しようとしたり、同じ主キーを 2 回定義しようとしたりすると、それを拒否して SQLCODE -307 エラーを発行します。主キーの第 2 定義が最初の定義と同じ場合も SQLCODE -307 エラーを発行します。現在の構成を確認するには、$SYSTEM.SQL.CurrentSettings()Opens in a new tab を呼び出します。これにより、[既存キーに対して DDL の Create Primary Key を許可] 設定が表示されます。既定値は 0 (いいえ) で、これが推奨される構成設定です。このオプションが 1 (はい) に設定されていると、ALTER TABLE ADD PRIMARY KEY により、InterSystems IRIS は主キー・インデックスをクラス定義から削除し、指定の主キー・フィールドを使用したインデックスを再生成します。

管理ポータル、[システム管理][構成][SQL とオブジェクトの設定][SQL] から [冗長な DDL ステートメントを無視] チェック・ボックスにチェックを付けることにより、このオプション (および他の同様の作成、変更、および削除のオプション) をシステム全体で設定できます。

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

ADD FOREIGN KEY の制限

外部キーの詳細は、CREATE TABLE コマンドの "外部キーの定義" と外部キーの "参照アクション節"、および "外部キーの使用法" を参照してください。

既定では、同じ名前の 2 つの外部キーを持つことはできません。これを実行しようとすると、SQLCODE -311 エラーが生成されます。現在の設定を確認するには、$SYSTEM.SQL.CurrentSettings()Opens in a new tab を呼び出します。これにより、[外部キーが存在する時に DDL ADD 外部キー制約を許可する] 設定が表示されます。既定値は 0 (いいえ) で、これが推奨設定です。1 (はい) の場合、同じ名前が存在しても、DDL を使用して外部キーを追加できます。

管理ポータル、[システム管理][構成][SQL とオブジェクトの設定][SQL] から [冗長な DDL ステートメントを無視] チェック・ボックスにチェックを付けることにより、このオプション (および他の同様の作成、変更、および削除のオプション) をシステム全体で設定できます。

テーブル定義では、同じ field-commalist フィールドを参照して相反する参照アクションを実行する、名前が異なる 2 つの外部キーを指定することはできません。同一のフィールドに対して相反する参照アクションを実行する 2 つの外部キーを定義した場合 (例: ON DELETE CASCADE と ON DELETE SET NULL)、InterSystems SQL は ANSI 標準に従い、エラーを生成しません。この代わりに InterSystems 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 を介して、または SQL ドライバ接続により ALTER TABLE を実行する場合に必要になります。

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

NO ACTION は、シャード・テーブルでサポートされている唯一の参照アクションです。

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

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

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

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

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

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

ADD CONSTRAINT の制限

制約をフィールドのコンマ区切りリストに追加できます。例えば、UNIQUE (FName,SurName) 制約を追加できます。この制約は、2 つのフィールド FName と Surname の値を組み合わせて UNIQUE 制約を設定します。同様に、フィールドのコンマ区切りリストに対して主キー制約外部キー制約を追加することもできます。

制約は名前付き制約にも名前のない制約にもできます。名前のない制約の場合、制約名はテーブル名を使用して生成されます。例えば、MYTABLE_Unique1MYTABLE_PKEY1 のようになります。

以下の例では、名前のない制約を 2 つ作成して、一意制約と主キー制約の両方をフィールドのコンマ区切りリストに追加します。

 ALTER TABLE SQLUser.MyStudents 
    ADD UNIQUE (FName,SurName),PRIMARY KEY (Fname,Surname)  
  • 制約で使用するフィールドが存在している必要があります。存在しないフィールドを指定すると、SQLCODE -31 エラーが生成されます。

  • 制約で RowId フィールドを使用することはできません。RowId (ID) フィールドを指定すると、SQLCODE -31 エラーが生成されます。

  • 制約でストリーム・フィールドを使用することはできません。ストリーム・フィールドを指定すると、SQLCODE -400 “エラーインデックス属性に誤り” が生成されます。

  • 制約は 1 つのフィールドに一度だけ適用できます。1 つのフィールドに同じ制約を 2 回指定すると、SQLCODE -400 エラー “インデックス名が重複しています” が生成されます。

オプションの CONSTRAINT identifier キーワード節を使用して、名前付き制約を作成できます。名前付き制約は、有効な識別子である必要があります。制約名では、大文字と小文字は区別されません。これにより、将来的に使用できるように、制約の名前が指定されます。以下に例を示します。

 ALTER TABLE SQLUser.MyStudents 
    ADD CONSTRAINT UnqFullName UNIQUE (FName,SurName)  

複数の制約をコンマ区切りリストとして指定できます。制約名は最初の制約に適用され、その他の制約には既定の名前が適用されます。

制約名は、テーブルで一意である必要があります。1 つのフィールドに同じ制約名を 2 回指定すると、SQLCODE -400 エラー “インデックス名が重複しています” が生成されます。

ALTER COLUMN

ALTER COLUMN では、単一の列の定義を変更できます。

  • 構文 ALTER TABLE tablename ALTER COLUMN oldname RENAME newname を使用して列の名前を変更します。列の名前を変更すると、SQL フィールド名が変更されます。対応する永続クラスのプロパティ名は変更されません。ALTER COLUMN oldname RENAME newname は、トリガー・コードと ComputeCode の oldfield 名の参照を置き換えます。

  • 列の特性 (データ型、既定値、NULL/NOT NULL、および照合タイプ) を変更します。

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

ALTER COLUMN を使用して、フィールドの既定値を追加、変更、または削除できます。

テーブルにデータが含まれていて、列に NULL 値が含まれている場合は、その列に NOT NULL を指定することはできません。これは SQLCODE -305 エラーになります。

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

CLEANUP

列指向ストレージと行単位ストレージの間でテーブルを変換する際に %NODELDATA を指定した場合、潜在的な古いデータを CLEANUP でクリーンアップできます。テーブル変換が完了したらすぐに、古いデータをクリーンアップすることを強くお勧めします。

テーブルに関連付けられた古いデータがない場合に ALTER TABLE ... CLEANUP コマンドを発行すると、SQLCODE -165 が発生します。クリーンアップ・プロセス自体が失敗した場合は、SQLCODE -166 が発生します。

あるストレージ・タイプの変換で、古いデータをクリーンアップするまでは、別の変換を行うことはできません。別の変換を開始しようとすると、SQLCODE -160 が発生します。

CONVERT

シャード形式またはシャード化されていない形式へのテーブルの変換

CONVERT オプションを使用して、シャード化されていないテーブルのシャード・テーブルへの変換、またはその逆の変換が可能です。前提条件として、インスタンスでシャーディングを有効にして、シャード・クラスタを導入する必要があります。詳細は、"シャード・テーブルの定義" を参照してください。

IMMEDIATE オプションを指定すると、変換は非同期のバックグラウンド・プロセスとしてすぐに開始されます。DEFER オプションを指定すると、$SYSTEM.Sharding.Rebalance の明示的な呼び出しまたは管理ポータルによって、次回シャードを明示的に再分散するときに変換が開始されます。

テーブルは、シャード形式またはシャード化されていない形式に変換されている間、シャード・テーブルのように扱われ、そのようにクエリされます。

シャード化されていないテーブルからシャード・テーブルへの変換

シャード化されていないテーブルをシャード・テーブルに変換する際には、シャード・キーとして使用する列または列のコンマ区切りリストを指定する必要があります。シャード・キーの選択の詳細は、"シャード・キーの選択" を参照してください。COSHARD オプションを使用する場合は、代わりに coshardtable で定義されたテーブルとのコシャード結合に使用されるシャード・キー列の名前を指定する必要があります。

シャード・テーブルからシャード化されていないテーブルへの変換

シャード・テーブルをシャード化されていないテーブルに変換する場合、シャード全体に保存されているデータがシャード・クラスタのマスタ・ネームスペースに収集されます。

列指向ストレージまたは行単位ストレージへのテーブルの変換

CONVERT オプションを使用して、テーブル、列、または列のセットのストレージ・タイプを変更できます。テーブル変換が実行されると、テーブルに現在保存されているデータはすべて新しいストレージ・タイプに変換されます。テーブル変換中は、さまざまな DML 操作 (INSERT など) でデータを挿入できますが、変換が完了するまで、変換中のクラスを他のプロセスでコンパイルすることはできません。

ROW から COLUMNAR に変換された列が以下の要件を満たさない場合、そのコマンドで SQLCODE -159 が発生します。

  • MAXLEN パラメータを取るタイプの列の場合、MAXLEN 属性は 300 を超えないこと。

  • 列がストリームでないこと。

  • 列がシリアルでないこと。

  • 列がコレクションでないこと。

  • 列が多次元でないこと。

  • 列が %Library.Vector または %Library.List でないこと。

既定では %DELDATA フラグが含まれるため、テーブルは古い形式で保存されたデータで占有されていたメモリを解放します。COLUMNAR から ROW への変換の場合、変換の終了時に列指向データが同期的にクリーンアップされます。ROW から COLUMNAR への変換の場合、クリーンアップを処理するバックグラウンド・ジョブが開始され、変換はただちに成功として返されます。この動作に従うことをお勧めします。

ストレージの変換が正常に完了したものの、古いテーブル・データの自動クリーンアップに失敗した場合、コマンドは SQLCODE -164 を発生させ、失敗したクリーンアップも messages.log に記録されます。バックグラウンド・プロセスが 1 時間ごとにクリーンアップの失敗がないかをチェックし、自動的にクリーンアップを再試行します。各クリーンアップは 1 日 1 回のみ試行されます。毎日のクリーンアップが 1 週間にわたって失敗すると、システムは自動クリーンアップ・プロセスを中止し、手動での検査用に SEVERE メッセージが messages.log に記録されます。

%NODELDATA フラグを手動で指定する場合、古いデータ・スロットは手動でクリーンアップされません (つまり、未割り当てとしてマークされません)。古いデータをクリーンアップするには、ALTER TABLE table-name CLEANUP を使用する必要があります。

DROP または DELETE

DROP COLUMN の制限

DROP COLUMN は、コンマ区切りリストとして指定された複数の列定義を削除します。リストされる各列名の後には、その RESTRICT または CASCADE (指定しない場合、既定は RESTRICT)、および %DELDATA または %NODELDATE (指定しない場合、既定は %NODELDATA) オプションが続く必要があります。

既定では、列定義を削除しても、その列に格納されているデータはデータマップから削除されません。列定義とそのデータの両方を削除するには、%DELDATA オプションを指定します。

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

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

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

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

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

CASCADE キーワード : 列がインデックスで使用されている場合は、インデックスが削除されます。複数のインデックスが存在する場合があります。列が外部キーで使用されている場合は、外部キーが削除されます。複数の外部キーが存在する場合があります。

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

DROP CONSTRAINT の制限

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

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

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

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

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

存在しない制約の削除

既定では、制約を持たないフィールドのフィールド制約を削除しようとした場合、InterSystems IRIS は削除を拒否し、SQLCODE -315 エラーを発行します。現在の設定を確認するには、$SYSTEM.SQL.CurrentSettings()Opens in a new tab を呼び出します。これにより、[存在しない制約に対して DDL の DROP を許可] 設定が表示されます。既定値は 0 (いいえ) で、これが推奨設定です。このオプションが 1 (はい) に設定されていると、ALTER TABLE DROP CONSTRAINT により、InterSystems IRIS は処理を実行せず、エラー・メッセージを発行しません。

管理ポータル、[システム管理][構成][SQL とオブジェクトの設定][SQL] から [冗長な DDL ステートメントを無視] チェック・ボックスにチェックを付けることにより、このオプション (および他の同様の作成、変更、および削除のオプション) をシステム全体で設定できます。

MODIFY

MODIFY では、単一の列またはコンマ区切りの列のリストの定義を変更できます。

  • 構文 ALTER TABLE tablename MODIFY oldname RENAME newname を使用して列の名前を変更します。列の名前を変更すると、SQL フィールド名が変更されます。対応する永続クラスのプロパティ名は変更されません。MODIFY oldname RENAME newname は、トリガー・コードと ComputeCode の oldfield 名の参照を置き換えます。

  • 列の特性 (データ型、既定値、および他の特性) を変更します。

テーブルにデータが含まれている場合、以下のように、データが含まれている列のデータ型を互換性のないデータ型に変更することはできません。

  • 既存のデータ値と競合する場合、より低い (より包括的ではない) データ型の優先順位を持つデータ型。これを実行しようとすると、SQLCODE -104 エラーになり、どのフィールドとどのデータ値がエラーの原因となっているかを示す %msg が表示されます。

  • 既存のデータ値と競合する場合、より小さい MAXLEN、または MAXVAL/MINVAL を持つデータ型。これを実行しようとすると、SQLCODE -104 エラーになり、どのフィールドとどのデータ値がエラーの原因となっているかを示す %msg が表示されます。

  • ストリーム・データ型から非ストリーム・データ型、または非ストリーム・データ型からストリーム・データ型へのデータ型の変更。これを実行しようとすると、SQLCODE -374 エラーが返されます。既存のデータがない場合は、このデータ型の変更が可能です。

MODIFY を使用して、フィールドの既定値を追加または変更できます。MODIFY を使用して、フィールドの既定値を削除することはできません。

テーブルにデータが含まれていて、列に NULL 値が含まれている場合は、その列に NOT NULL を指定することはできません。これは SQLCODE -305 エラーになります。構文形式 ALTER TABLE mytable MODIFY field1 NOT NULL および ALTER TABLE mytable MODIFY field1 CONSTRAINT nevernull NOT NULL は同じ操作を実行します。オプションの CONSTRAINT identifier 節は、互換性を保つための空命令です。InterSystems IRIS ではこのフィールド制約名を保持または使用しません。このフィールド制約名を指定してこのフィールド制約を削除しようとすると、SQLCODE -315 エラーになります。

PARTITION

MOVE PARTITION

MOVE PARTITION オプションでは、指定のパーティションを別個のデータベースへ移動するマッピングを作成します。目的のパーティションに既に行が保存されている場合、その行は DataMove ユーティリティによって新しい場所へ移動します。データベース間でのパーティション移動の詳細は、"パーティション分割されたテーブル" を参照してください。

データベース間でパーティションを移動するには、そのパーティションのスキーマでどのデータベースが使用されるかを把握しておく必要があります。そのためには、管理ポータルから CREATE DATABASE FILE コマンドを使用するか、^DATABASE ユーティリティを使用して、追加のデータベースを作成することが必要な場合もあります。このような新しいデータベースに対する適切なアクセス権を必ず構成します。また、管理ポータルでジャーナルに対して [エラー発生時に凍結する] を有効にしておく必要もあります。そのためには、[システム管理]→[構成]→[システム構成]→[ジャーナル設定] の順に移動し、[エラー発生時に凍結する] チェックボックスにチェックが付いていることを確認します。

パーティション・キー・フィールド値の範囲、パーティション ID、またはパーティション ID の範囲を指定してパーティションを移動できます。

例 : パーティション・キー・フィールド値の範囲を指定してパーティションを移動する

Note:

HASH タイプのパーティション・キーを使用しているキー・パーティション分割テーブルでは、パーティション・キー・フィールド値の範囲を指定してデータを移動することはできません。

以下の例では、1 年の間隔でデータをパーティション分割するパーティション・キーを TransactionDate フィールドに設定したテーブルを作成します。つづいて、2023 年分のデータを保持しているパーティションを、事前定義した data-2023 データベースへ移動します。パーティション全体がそのまま移動するので、ここで指定した範囲 ('2023-01-01' AND '2023-02-01') が 2023 年分のパーティションの一部に該当していることから、そのパーティション全体が移動します。

CREATE TABLE Store.Transactions ( TransactionDate DATE ) PARTITION BY RANGE INTERVAL 1 YEAR

ALTER TABLE Store.Transactions MOVE PARTITION BETWEEN '2023-01-01' AND '2023-02-01' TO data-23

以下の例では、1 年の間隔でデータをパーティション分割するパーティション・キーを TransactionDate フィールドに設定したテーブルを作成します。つづいて、それぞれ 2023 年分、2024 年分、2025 年分のデータを保持している 3 つのパーティションを、事前定義した 2020s-data データベースへ移動します。ここで指定した範囲 ('2023-12-31' AND '2025-01-01') 自体に年間の境界が含まれているので、3 年間のデータが年別に取得されます。1 つのパーティションにある任意の個数の値が指定の範囲に該当していれば、そのパーティション全体が指定のデータベースへ移動します。

CREATE TABLE Store.Transactions ( TransactionDate DATE ) PARTITION BY RANGE INTERVAL 1 YEAR

ALTER TABLE Store.Transactions MOVE PARTITION BETWEEN '2023-12-31' AND '2025-01-01' TO last-three-years
例 : パーティション ID を指定してパーティションを移動する

以下の例では、6 か月を間隔とするパーティション・キーを TransactionDate フィールドに設定したテーブルを作成します。INFORMATION_SCHEMA.TABLE_PARTITIONS をクエリするか、カタログの詳細を確認することで、新しいデータベースへ移動するパーティションの ID を特定してから、ALTER TABLE コマンドを実行します。

CREATE TABLE Store.Transactions ( TransactionDate DATE ) PARTITION BY RANGE (TransactionDate) INTERVAL 6 MONTHS

ALTER TABLE Store.Transactions MOVE PARTITION ID 202411010000 TO data-2024

以下の例では、個別の値でデータをパーティション分割するパーティション・キーを StoreLocation フィールドに設定したテーブルを作成します。このパーティション・キー・フィールドの個別の値は、LIST タイプ・パーティション・キーのパーティション ID なので、パーティション ID が 'New York' であるパーティションが us-north データベースへ移動します。

CREATE TABLE Store.Transactions ( StoreLocation VARCHAR(50) COLLATE %EXACT ) PARTITION BY LIST (StoreLocation)

ALTER TABLE Store.Transactions MOVE PARTITION ID 'New York' TO us-north
例 : パーティション ID の範囲を指定してパーティションを移動する

以下の例では、パーティション・キーを CustomerName フィールドに設定したテーブルを作成し、8 つのパーティションにわたってデータを格納します。つづいて、パーティション ID 14 のパーティションに格納したデータを overflow データベースへ移動します。パーティション・キーの値を指定してパーティションを移動する場合と同様に、両方の境界が移動対象となります。

CREATE TABLE Store.Transactions ( CustomerName VARCHAR(50) ) PARTITION BY RANGE (StoreLocation) IN 8 PARTITIONS

ALTER TABLE Store.Transactions MOVE PARTITION ID BETWEEN 1 AND 4 TO overflow
例 : 複数フィールドのパーティション・キーがあるテーブルのパーティションを移動する

以降のすべての例では、複数フィールドでパーティション分割した同じテーブルを使用しています。このテーブルは、以下の CREATE TABLE コマンドで作成され、その後に示しているデータを保持しています。

CREATE TABLE Store.Transactions ( 
   CustomerName VARCHAR(50), 
   TransactionDate DATE, 
   StoreLocation VARCHAR(25) COLLATE %EXACT ) 
PARTITION BY LIST (StoreLocation), RANGE (TransactionDate) INTERVAL 3 MONTHS
| CustomerName | TransactionDate | StoreLocation |
|      --      |        --       |       --      |
|     Jack     |    09/01/2025   |     Maine     |
|    Margie    |    11/05/2025   |     Maine     |
|   Katherine  |    02/05/2025   | Massachusetts |
|      Max     |    01/01/2025   | Massachusetts |
|     Lucas    |    04/15/2025   | NewHampshire  |
|    Lauren    |    06/11/2025   |  RhodeIsland  |
|    Stephen   |    07/04/2025   |  RhodeIsland  |
|     Stacy    |    08/01/2025   |  RhodeIsland  |
|      Ben     |    03/07/2025   |    Vermont    |
|     Holly    |    05/04/2025   |    Vermont    |

複数フィールドのパーティション・キーを設定したパーティション分割テーブル上で、パーティション・キー・フィールドの範囲を指定してパーティションを移動する場合の動作は、単一フィールドのパーティション・キーの場合と同様です。ただし、上位レベルのパーティションを移動せずに下位レベルのパーティションを移動できる点が異なります。例えば、Store.Transactions テーブルでは、特定の格納場所のパーティション上位レベルでどのデータも移動することなく、その場所のパーティション下位レベルで特定の日付範囲のデータを新しいデータベースに移動できます。以下の例では、場所 RhodeIsland にある、日付範囲 2025-07-012025-12-31 に該当するすべてのデータを、q3-2025 データベースへ移動します。

ALTER TABLE Store.Transactions MOVE PARTITION ID BETWEEN 
  'RhodeIsland||202507010000' AND 'RhodeIsland||202509300000' TO q3-2025

パーティション ID を指定してパーティションを移動する場合は、最も外側のパーティション ID (ここの例では StoreLocation の値) を移動対象として選択すると、そのバーティションとその内側のすべてのパーティション (ここの例では、3 か月分のデータ・グループごとのパーティション) を指定のデータベースへ移動できます。以下の例では、場所 Massachusetts の最も外側のパーティションを new-england データベースへ移動します。

ALTER TABLE Store.Transactions MOVE PARTITION ID 'Massachusetts' TO 'new-england'

CONVERT PARTITION

CONVERT PARTITION オプションを使用すると、パーティション分割していないテーブルを、既定のパーティション分割テーブルまたはキー・パーティション分割テーブルに変換できます。また、パーティション分割テーブルを、パーティション分割していないテーブルに変換することもできます。変換の実行中でも、変換元テーブルに対するクエリと、そのデータを変更する INSERTUPDATEDELETE の各コマンドを実行できます。

例 : パーティション分割していないテーブルを既定のパーティション分割テーブルに変換する

パーティション分割していないテーブルを既定のパーティション分割テーブルに変換すると、意識せずにバケット化の利点が得られます。

ALTER TABLE Store.Transactions CONVERT PARTITION ON
例 : パーティション分割していないテーブルまたは既定のパーティション分割テーブルを、キー・パーティション分割テーブルに変換する

パーティション・キーを定義することで、パーティション分割していないテーブルまたは既定のパーティション分割テーブルを、キー・パーティション分割テーブルに変換できます。パーティション・キーを定義した後は、そのキーを変更できず、そのテーブルを既定のパーティション分割テーブルに変換することもできません。

ALTER TABLE Store.Transactions CONVERT 
    PARTITION BY RANGE (TransactionDate) INTERVAL 3 MONTHS
例 : パーティション分割テーブルを、パーティション分割していないテーブルに変換する

パーティション分割テーブルを、パーティション分割していないテーブルに変換できます。この変換では、ネームスペースの既定のグローバル・データベースにすべてのデータが戻され、すべてのストレージ・マッピングが削除されたうえで、パーティション・キーが削除されます。

ALTER TABLE Store.Transactions CONVERT PARTITION OFF

DROP PARTITION

DROP PARTITION オプションを使用すると、テーブルからパーティションのすべてまたは一部を削除できます。そのテーブルで保持されているデータもすべて削除されます。このコマンドでは、ジャーナル化、ロック、トリガの処理が省略され、参照アクションが実行されません。

以下のコマンドは、指定されたパーティション ID のパーティションをテーブルから削除します。

ALTER TABLE Demo.Log DROP PARTITION ID 201402010000

以下のコマンドは、パーティション ID の範囲を指定することでパーティションを削除します。

ALTER TABLE Demo.Inventory DROP PARTITION ID BETWEEN 4 AND 8

以下のコマンドは、パーティション・キー・フィールド値の範囲を指定することでパーティションを削除します。指定された範囲の値 (範囲の下限値以上で上限値以下の値) を保持しているすべてのパーティションがテーブルから削除されます。

ALTER TABLE Demo.Inventory DROP PARTITION BETWEEN '2024-04-01' AND '2024-06-30'

TRUNCATE PARTITION

TRUNCATE PARTITION オプションは DROP PARTITION に似ていますが、パーティションとそのマッピングはデータと共に削除されません。その結果、このオプションの実行直後はパーティションとマッピングが存続していますが、そこにデータは保持されていません。

以下のコマンドは、指定されたパーティション ID のパーティションにあるデータをテーブルから削除します。

ALTER TABLE Demo.Log TRUNCATE PARTITION ID 201402010000

以下のコマンドは、パーティション ID の範囲を指定することで、該当するパーティションのデータを削除します。

ALTER TABLE Demo.Inventory TRUNCAT PARTITION ID BETWEEN 4 AND 8

以下のコマンドは、パーティション・キー・フィールド値の範囲を指定することで、パーティションのデータを削除します。すべてのパーティションで、指定された範囲の値 (範囲の下限値以上で上限値以下の値) を保持しているデータがテーブルから削除されます。

ALTER TABLE Demo.Inventory DROP PARTITION BETWEEN '2024-04-01' AND '2024-06-30'

RENAME

以下の構文を使用して、既存のテーブルの名前を変更できます。

ALTER TABLE schema.TableName RENAME NewTableName

この操作では、既存のスキーマ内にある既存のテーブルの名前を変更します。変更できるのはテーブル名だけです。テーブル・スキーマは変更できません。NewTableName でスキーマ名を指定すると、SQLCODE -1 エラーになります。古いテーブルと新しいテーブルの両方に同じテーブル名を指定すると、SQLCODE -201 エラーが生成されます。

テーブルの名前を変更すると、SQL テーブル名が変更されます。対応する永続クラス名は変更されません。

テーブルの名前を変更しても、トリガ内にある古いテーブル名への参照は変更されません。

ビューで既存のテーブル名を参照している場合、そのテーブルの名前を変更しようとすると失敗します。その理由は、テーブルの名前の変更を試行するのはビューのリコンパイルを引き起こすアトミックな操作であるためで、これによって SQLCODE -30 エラー “テーブル 'schema.oldname' が見つかりません” が生成されます。

STATS

DROP FIXED

DROP FIXED 操作は、クラス定義から一連の固定統計を削除して、収集統計を使用できるようにします。このオプションは、スキーマ・レベルまたはテーブル・レベルで適用できます。

ALTER TABLE Sample.People DROP FIXED STATISTICS

STATISTICS の同義語として STATS を使用できます。例えば、以下のクエリは上記のクエリと同等です。

ALTER TABLE Sample.People DROP FIXED STATS

FIX

FIX 操作で一覧の収集統計をクラス定義に固定できます。これにより、これらの統計がクエリ・プランの作成に使用する統計となり、これらの統計によって既存の固定統計が置き換えられます。このオプションは、スキーマ・レベルまたはテーブル・レベルで適用できます。

ALTER TABLE Sample.People FIX STATISTICS

STATISTICS の同義語として STATS を使用できます。例えば、以下のクエリは上記のクエリと同等です。

ALTER TABLE Sample.People FIX STATS

SET RUNTIME

SET RUNTIME 操作では、スキーマ・レベルまたはテーブル・レベルで 2 つのパラメータを設定できます。その 1 つである IGNOREFIXEDSTATS では、固定統計よりも収集統計を優先するかどうかを構成します。既定では、このオプションは FALSE に設定されています。もう 1 つのパラメータ SKIPAUTOMATICSTATSCOLLECTION では、自動収集統計ユーティリティによる処理対象からスキーマまたはテーブルのどちらを除外するかを構成します。

以下の例では、固定統計が無視され、収集統計の自動収集が停止します。

ALTER SCHEMA Sample SET RUNTIME IGNOREFIXEDSTATS = TRUE
ALTER SCHEMA Sample SET RUNTIME SKIPAUTOMATICSTATSCOLLECTION = FALSE

以下の例では埋め込み SQL プログラムを使用して、テーブルを作成し、2 行を生成してからテーブルの定義を変更します。

この動作をはっきり示すために、最初の 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 (
     FirstName VARCHAR(35) NOT NULL,
     LastName VARCHAR(35) NOT NULL)
     )
     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 (FirstName, LastName) 
    VALUES ('David','Vanderbilt'))
  IF SQLCODE=0 { WRITE !,"Inserted data in table"}
      ELSE { WRITE !,"SQLCODE=",SQLCODE,": ",%msg }
  &sql(INSERT INTO SQLUser.MyStudents (FirstName, LastName)
    VALUES ('Mary','Smith'))
  IF SQLCODE=0 { WRITE !,"Inserted data in table"}
     ELSE { WRITE !,"SQLCODE=",SQLCODE,": ",%msg }

以下の例は、ALTER TABLE を使用して ColorPreference 列を追加します。列定義で既定値を指定するため、システムではテーブルの既存の 2 つの行に対して ColorPreference に値 'Blue' を入力します。

   NEW SQLCODE,%msg
  &sql(ALTER TABLE SQLUser.MyStudents 
    ADD COLUMN ColorPreference VARCHAR(16) NOT NULL DEFAULT 'Blue')
  IF SQLCODE=0 {
    WRITE !,"Added a column",! }
  ELSEIF SQLCODE=-306 {
    WRITE !,"SQLCODE=",SQLCODE,": ",%msg }
  ELSE { WRITE "SQLCODE error=",SQLCODE }

以下の例は、ALTER TABLE を使用して、2 つの計算列 FLName および LFName を追加します。既存の行のこれらの列に値はありません。その後に挿入される行については、これらの列それぞれに対して値が計算されます。

  NEW SQLCODE,%msg
  &sql(ALTER TABLE SQLUser.MyStudents 
    ADD COLUMN FLName VARCHAR(71) COMPUTECODE { SET {FLName}={FirstName}_" "_{LastName}} 
               COMPUTEONCHANGE (FirstName,LastName),
        COLUMN LFName VARCHAR(71) COMPUTECODE { SET {LFName}={LastName}_ "," _{FirstName}} 
               COMPUTEONCHANGE (FirstName,LastName) )
  IF SQLCODE=0 {
    WRITE !,"Added two computed columns",! }
  ELSE { WRITE "SQLCODE error=",SQLCODE }

関連項目

FeedbackOpens in a new tab