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?

CREATE TABLE

テーブル定義を作成します。

Synopsis

CREATE [GLOBAL TEMPORARY] TABLE 
table (table-element-commalist)

table-element ::= 
     [%DESCRIPTION string] 
     [%FILE string] 
     [{%EXTENTSIZE | %NUMROWS} integer] 
     [%PUBLICROWID] 
     [%ROUTINE string] 
     [{ %CLASSPARAMETER param_name [=] value }]

     { fieldname datatype
           [IDENTITY] |
           {
             [ [COLLATE] sqlcollation ]
             [ UNIQUE ]
             [ NULL | NOT NULL ]
             [ PRIMARY KEY ]
             [ DEFAULT [(]default-spec[)] ]
             [ COMPUTECODE { ObjectScript-code } 
                   [ COMPUTEONCHANGE (field-commalist) |
                     CALCULATED | TRANSIENT ] ]
                [ %DESCRIPTION literal ]
           } , }

     [{ [CONSTRAINT uname] 
          UNIQUE (field-commalist) }]

    [ [CONSTRAINT pkname] 
          PRIMARY KEY (field-commalist) ] 

     [{ [CONSTRAINT fkname] 
          FOREIGN KEY (field-commalist) REFERENCES table 
              [(reffield-commalist)] [referential-action] }]

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

このコマンド概要には、互換性目的でのみ解析されオペレーションを伴わないキーワードは記載されていません。サポートされる空命令キーワードの一覧は、後述の別セクションで示します。

引数

GLOBAL TEMPORARY オプション — このキーワード節は、一時テーブルとしてテーブルを作成します。
table 作成するテーブルの名前。有効な識別子を指定します。テーブル名は修飾 (schema.table)、未修飾 (table) のどちらでもかまいません。テーブル名が未修飾の場合は、システム既定のスキーマ名が使用されます。
table-element

1 つまたは複数のフィールド定義またはキーワード句のコンマ区切りリスト。

各フィールド定義の最も簡単な構成は、フィールド名 (有効な識別子として指定) と、それに続くデータ型です。

キーワード句は、キーワード (%PUBLICROWID) のみ、キーワードとそれに続くリテラル、またはキーワード (%CLASSPARAMETER) とそれに続く名前および関連するリテラルで構成できます。

COLLATE sqlcollation オプション — SQL 照合タイプ (%EXACT、%MINUS、%PLUS、%SPACE、%SQLSTRING、%SQLUPPER、%TRUNCATE、または %MVR) のいずれかを指定します。既定は、ネームスペースの既定の照合です (変更していない場合は %SQLUPPER です)。照合タイプ %ALPHAUP、%STRING、および %UPPER は非推奨であるため、使用しないでください。%SQLSTRING、%SQLUPPER、%STRING、および %TRUNCATE は、オプションの最大長のトランケーション引数である、括弧で囲んだ整数を指定できます。これらの照合パラメータ・キーワードの先頭のパーセント記号 (%) はオプションです。COLLATE キーワードはオプションです。詳細は、"Caché SQL の使用法" の “照合” の章にある "テーブルのフィールド/プロパティ定義の照合" を参照してください。

uname

pkname

fkname

オプション — 制約名。有効な識別子として指定されます。ALTER TABLE ではこのオプションの制約名を使用して、定義されている制約を識別します。
field-commalist フィールド名、またはコンマで区切られた順不同のフィールド名のリスト。一意制約、主キー制約または外部キー制約を定義するために使用します。制約で指定するフィールド名はすべて、フィールド定義でも同様に定義する必要があります。また、括弧で囲む必要があります。
reffield-commalist オプション — 外部キー制約で指定した参照対象テーブルで定義されているフィールド名またはコンマで区切られた既存のフィールド名のリスト。指定する場合、括弧で囲む必要があります。省略した場合は、"外部キーの定義" で説明されているように既定値が取られます。

概要

CREATE TABLE コマンドは、指定された構造のテーブル定義を作成します。Caché は、このテーブル定義に対応する永続クラスと、フィールド定義に対応するプロパティを自動的に作成します。CREATE TABLE は、対応するクラス定義で明示的な StorageStrategy を指定しません。既定では、CREATE TABLE は対応するクラス定義で Final クラス・キーワードを指定します。これは、サブクラスを持てないことを示しています。(この既定は、SetDDLFinal()Opens in a new tab メソッドを使用するか、または対応する管理ポータルの [一般 SQL 設定] : [DDL タブ] オプションを使用して変更できます。)

このリファレンス・ページは、CREATE TABLE に関する以下の考慮事項の説明です。

SQL のセキュリティおよび特権

CREATE TABLE コマンドの実行には特権が必要です。CREATE TABLE を使用する前に、%CREATE_TABLE 特権を得る必要があります。特権がない場合は、SQLCODE -99 エラー (特権違反) が返されます。適切な付与特権を持っていれば、GRANT コマンドを使用して、ユーザまたはロールに %CREATE_TABLE 特権を割り当てることができます。

この特権要件は、以下のいずれかの方法で変更できます。

既定値は “はい” (1) です。“はい” の場合、ユーザは特権が付与されているテーブルやビューのみでアクションを実行できます。この設定を推奨します。

このオプションが “いいえ” (0) に設定された場合、この設定の変更後に開始された新しいプロセスすべてで SQL セキュリティは無効になります。つまり、特権ベースのテーブルやビューのセキュリティは抑制されていることを意味します。ユーザを指定しなくてもテーブルの作成が可能になります。この場合、ダイナミック SQL はユーザとして “_SYSTEM” を、埋め込み SQL はユーザとして "" (空文字列) を割り当てます。ユーザは特権がなくてもテーブルやビューに対してアクションを実行することができます。

埋め込み SQL は、SQL 特権を使用しません。埋め込み SQL では、以下のように $SYSTEM.Security.Login()Opens in a new tab メソッドを使用して適切な特権を持ったユーザとしてログインできます。$SYSTEM.Security.Login() メソッドを呼び出すには、%Service_Login:Use 特権が必要です。詳細は、"インターシステムズ・クラス・リファレンス" の "%SYSTEM.SecurityOpens in a new tab" を参照してください。

以下の埋め込み SQL の例は、Employee テーブルを作成します。

  DO $SYSTEM.Security.Login("_SYSTEM","SYS")
  NEW SQLCODE,%msg
  &sql(CREATE TABLE Employee (
     EMPNUM     INT NOT NULL,
     NAMELAST   CHAR(30) NOT NULL,
     NAMEFIRST  CHAR(30) NOT NULL,
     STARTDATE  TIMESTAMP,
     SALARY     MONEY,
     ACCRUEDVACATION   INT,
     ACCRUEDSICKLEAVE  INT,
     CONSTRAINT EMPLOYEEPK PRIMARY KEY (EMPNUM))
  )
  IF SQLCODE=0 {WRITE !,"Table created"}
  ELSE {WRITE !,"SQLCODE=",SQLCODE,": ",%msg }

Employee という名前のこのテーブルには、いくつかの定義済みフィールドがあります。(会社の従業員の ID 番号を含む) EMPNUM フィールドは、NULL ではない整数です。また、テーブルの主キーとして宣言されています。従業員の姓と名にはそれぞれフィールドが定義され、どちらも最大 30 文字までの非 NULL 文字列で指定されます。また、従業員の入社日や有給休暇、病欠日のフィールド (TIMESTAMP と INT データ型を使用) もあります。

前述の例で作成されたテーブルを削除するには、以下のプログラムを使用します。

  DO $SYSTEM.Security.Login("_SYSTEM","SYS")
  NEW SQLCODE,%msg
  &sql(DROP TABLE Employee)
  IF SQLCODE=0 {WRITE !,"Table deleted"}
  ELSE {WRITE !,"SQLCODE=",SQLCODE,": ",%msg }

CREATE TABLE と INSERT

埋め込み SQL は、コンパイルされた SQL です。埋め込み SQL では、同じプログラム内で、テーブルの作成とそのテーブルへのデータの挿入を両方行うことはできません。この理由は以下のとおりです。テーブルは実行時に作成されます。しかし INSERT 文では、コンパイル時にテーブルの存在を確認する必要があります。SELECT 文もコンパイル時に対象テーブルの存在を確認する必要があるため、同じ制約を持ちます。

コンパイルされたプログラムでは、CREATE TABLE 文を、他の既存テーブルを参照する DML 文 (INSERTSELECT など) と自由に結合できます。

この制限は、埋め込み SQL プログラムを遅延 SQL として扱うようにプリプロセッサに指示することで回避できます。具体的には、"Caché ObjectScript の使用法" の "システム・プリプロセッサ・コマンド・リファレンス" のセクションの説明に従って、#SQLCompile Mode=Deferred マクロ・プリプロセッサ指示文を使用します。

この制約は、実行時に解析されるダイナミック SQL には適用されません。

$SYSTEM.SQL.QueryToTable()Opens in a new tab メソッドを使用すると、単一の処理で既存のテーブル定義からテーブルを作成しその既存テーブルからデータを挿入することができます。

テーブル名

テーブル名は修飾、未修飾のどちらでもかまいません。テーブル名を修飾する場合は、以下の構文を使用します。

schema.tablename

未修飾のテーブル名では、schema (およびピリオド (.) 文字) が省略され、既定のスキーマ名が使用されます。埋め込み SQL の #SQLCompile Path マクロ指示文を使用して、DDL 文にある未修飾のテーブルを解決することはできません。この指示文は SELECT 文と CALL 文でのみ使用できます。

修飾テーブル名は、既存のスキーマ名または新規スキーマ名のいずれかを指定できます。既存のスキーマ名を指定すると、テーブルはスキーマ内に配置されます。新規スキーマ名を指定すると、その名前のスキーマ (および関連するクラス・パッケージ) が作成され、テーブルがそのスキーマ内に配置されます。

テーブル名とスキーマ名は、SQL 識別子の名前付け規約と、非英数文字の使用、一意性、および最大長に関する追加の制約に従います。% 文字で始まる名前は、システムによる使用のために予約されています。既定では、スキーマ名とテーブル名は単純な識別子であり、大文字と小文字が区別されません。

Caché はテーブル名を使用して、対応するクラス名を生成します。Caché はスキーマ名を使用して、対応するクラス・パッケージ名を生成します。クラス名には英数字 (文字および数字) のみを使用し、最初の 96 文字は一意である必要があります。クラス名を生成するために、Caché はまず記号 (非英数字) 文字をテーブル名から削除し、一意性と最大長の制約を課して一意のクラス名を生成します。パッケージ名を生成するために、Caché はスキーマ名内の記号 (非英数字) 文字に対して削除または特殊処理のいずれかを実行します。次に Caché は、一意性と最大長の制約を課して一意のパッケージ名を生成します。スキーマ名とテーブル名からパッケージ名とクラス名を生成する方法の詳細は、"Caché SQL の使用法" の “テーブルの定義” の章にある "テーブル名とスキーマ名" を参照してください。

スキーマとテーブルに同じ名前を使用することはできません。同じスキーマ内でテーブルとビューに同じ名前を使用することはできません。

スキーマ名では大文字と小文字が区別されず、対応するクラス・パッケージ名では大文字と小文字が区別されます。指定したスキーマ名が、既存のクラス・パッケージ名と大文字/小文字のみが異なり、パッケージ定義が空の (クラス定義が含まれていない) 場合、Caché では、クラス・パッケージ名の大文字/小文字を変更して 2 つの名前が照合されます。詳細は、"Caché SQL の使用法" の “テーブルの定義” の章にある "テーブル名とスキーマ名" を参照してください。

Caché は Unicode システムで、16 ビット (ワイド) 文字列のテーブルやフィールドの名前付けをサポートします。大部分のロケールで、テーブル名にはアクセント記号付き文字を使用でき、生成されるクラス名にもアクセント記号が含まれます。以下の例は、SQL テーブル名の検証テストを実行します。

TableNameValidation
  SET tname="MyTestTableName"
  SET x=$SYSTEM.SQL.IsValidRegularIdentifier(tname)
  IF x=0 {IF $LENGTH(tname)>200  
             {WRITE "Tablename is too long" QUIT}
          ELSEIF $SYSTEM.SQL.IsReservedWord(tname) 
             {WRITE "Tablename is reserved word" QUIT}
          ELSE {
            WRITE "Tablename contains invalid characters",!
            SET nls=##class(%SYS.NLS.Locale).%New()
            IF nls.Language [ "Japanese" {
            WRITE "Japanese locale cannot use accented letters"
            QUIT }
         QUIT }
   }
   ELSE { WRITE tname," is a valid table name"}
Note:

日本のロケールでは、アクセント記号付きの文字を識別子でサポートしていません。日本語の識別子には、日本語の文字に加え、ラテン文字の A ~ Z と a ~ z (65 ~ 90 および 97 ~ 122)、アンダースコア文字 (_)、とギリシャ文字の大文字 (913 ~ 929 および 931 ~ 937) を使用できます。nls.Language テストでは、= ではなく [ (包括関係演算子) を使用しています。オペレーティング・システム・プラットフォームごとに日本語ロケールが異なるためです。

既定スキーマ名

未修飾のテーブル名には、既定として SQLUser スキーマが使用されます。スキーマ名はクラス・パッケージ名となります。既定のスキーマ名 SQLUser は既定のクラス・パッケージ名 User になります。例えば、未修飾のテーブル名 Employee または修飾されたテーブル名 SQLUser.Employee では、クラス User.Employee が生成されます。このため、User というスキーマ名を指定しようとすると、SQLCODE -312 エラーが発生します。

このスキーマ名の既定は設定可能です。現在のプロセスの既定スキーマ名を返すには、$SYSTEM.SQL.DefaultSchema()Opens in a new tab メソッド呼び出しを使用します。

  WRITE $SYSTEM.SQL.DefaultSchema()

既定スキーマ名を設定するには以下の方法があります。

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

  • 管理ポータルに進み、システム, 構成, 一般SQL設定 を選択します。[既定の SQL スキーマ名] の現在の設定が表示されます。

既定のスキーマ名が使用されるのは、未修飾のテーブル名が SQL 文で出現し、#import 文が指定されていない場合です。この構成は、SQL スキーマ名とクラス・パッケージ名間のマッピングとは関係ありません。既定のスキーマ名を指定するだけです。既定値は SQLUser です。既定スキーマ名に _CURRENT_USER を指定すると、この既定スキーマ名が現在ログインしているプロセスでのユーザ名になります。ログインしていなければ SQLUser が既定スキーマ名となります。既定スキーマ名に _CURRENT_USER または myname (ユーザが指定した文字列) を指定すると、これが現在ログインしているプロセスでのユーザ名になります。ログインしていなければ、myname が既定スキーマ名として使用されます。例えば、_CURRENT_USER または HMO は、プロセスがログインしていないときは既定のスキーマ名として HMO を使用します。

既存のテーブル

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

既存のテーブルと同じ名前のテーブルを作成しようとしたときの反応は、構成設定により異なります。既定では、Caché は既存のテーブルと同じ名前のテーブルを作成することを拒否し、SQLCODE -201 エラーを発行します。これは以下のように設定可能です。

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

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

既定値は “いいえ” (0) です。この設定を推奨します。このオプションを “はい” (1) に設定すると、Caché はこのテーブルに対応するクラス定義を削除し、クラスを再作成します。つまり、DROP TABLE を実行して既存のテーブルを削除し、CREATE TABLE を実行する動作と同じ結果を生じます。この場合、SQL 構成オプションの [DDL DROP TABLE がテーブルのデータを削除する] を “はい” に設定 (既定) することを強くお勧めします。

GLOBAL TEMPORARY テーブル

GLOBAL TEMPORARY キーワードを指定すると、テーブルがグローバル一時テーブルとして定義されます。テーブル定義はグローバル (すべてのプロセスで使用可能) であり、テーブル・データは一時的 (プロセスの期間中のみ存続) です。対応するクラス定義には、追加のクラス・パラメータ SQLTABLETYPE="GLOBAL TEMPORARY" が含まれます。Caché の標準的なテーブルと同様、ClassType=persistent ですが、このクラスには Final キーワードが含まれているため、このクラスにサブクラスを作成することはできません。

一時テーブルを作成するプロセスに関係なく、一時テーブルの所有者は自動的に _PUBLIC に設定されています。つまり、キャッシュされた一時テーブル定義にはすべてのユーザがアクセスできます。例えば、あるストアド・プロシージャによって一時テーブルが作成された場合、そのストアド・プロシージャを呼び出す許可が与えられているユーザであれば、誰でもこの一時テーブルにアクセスできます。この説明が該当するのは一時テーブル定義のみであり、一時テーブル・データは呼び出しに固有のものです。したがって、一時テーブル・データにアクセスできるのは、現在のユーザ・プロセスのみです。

グローバル一時テーブルのテーブル定義は、ベース・テーブルと同じです。グローバル一時テーブルには、一意の名前を付ける必要があります。既存のベース・テーブルと同じ名前を付けようとすると、SQLCODE -201 エラーが返されます。このテーブルは、明示的に削除 (DROP TABLE を使用) されるまで残り続けます。ALTER TABLE を使用してテーブル定義を変更できます。

グローバル一時テーブル内のテーブル・データ (ストリーム・データを含む) とインデックスは、一時的なものです。それらは、プロセス・プライベート・グローバルに格納されています。これは、グローバル一時テーブルを作成したプロセスのみがこのデータを使用でき、プロセスの終了時にこのデータも削除されることを意味します。

以下の埋め込み SQL の例は、グローバル一時テーブルを作成します。

  DO $SYSTEM.Security.Login("_SYSTEM","SYS")
  NEW SQLCODE,%msg
  &sql(CREATE GLOBAL TEMPORARY TABLE TempEmp (
    EMPNUM     INT NOT NULL,
    NAMELAST   CHAR(30) NOT NULL,
    NAMEFIRST  CHAR(30) NOT NULL,
    CONSTRAINT EMPLOYEEPK PRIMARY KEY (EMPNUM))
  )
  IF SQLCODE=0 {WRITE !,"Table created"}
  ELSE {WRITE !,"SQLCODE=",SQLCODE,": ",%msg }

%DESCRIPTION、%FILE、%EXTENTSIZE / %NUMROWS、%ROUTINE

これらのオプション・キーワード句は、テーブル要素のコンマ区切りリスト内の任意の場所で指定できます。

Caché SQL で提供されている %DESCRIPTION キーワードは、テーブルまたはフィールドの説明を挿入するために使用します。%DESCRIPTION の後には、一重引用符で囲んだテキスト文字列を続けます。このテキストの長さに制限はなく、空白スペースを含むすべての文字を使用できます (説明文字列内の一重引用符は、二重引用符で代用します。例えば、'Joe''s Table' のようになります)。1 つのテーブルには 1 つの %DESCRIPTION を使用できます。テーブルの各フィールドには、データ型の後にそれぞれ独自の %DESCRIPTION を指定できます。テーブル全体の %DESCRIPTION を複数指定すると、SQLCODE -82 エラーが発行されます。フィールドの %DESCRIPTION を複数指定すると、最後に指定された %DESCRIPTION のみが保持されます。スタジオでは、説明は、対応するテーブル (クラス) またはフィールド (プロパティ) の 1 つ前の行に、3 つのスラッシュが付けられて表示されます。以下はその例です。

/// Joe's Table

Caché SQL が提供する %FILE キーワードは、テーブルの説明を記録するファイル名を指定する目的で使用します。%FILE の後には、一重引用符で囲んだテキスト文字列を続けます。1 つのテーブル定義には、%FILE キーワードを 1 つのみ使用できます。複数指定すると、SQLCODE -83 エラーが生成されます。

Caché SQL に用意されているオプションの %EXTENTSIZE キーワードと %NUMROWS キーワードは、このテーブルに想定される行数を示す整数の格納に使用します。これらのキーワードは同義語です。Caché では %EXTENTSIZE の使用をお勧めします。データの行数がわかっているテーブルを作成する場合、特に最初に行数を設定しておけば以降は変更する可能性が低い場合 (都道府県のテーブルなど) は、%EXTENTSIZE を設定すると余分な格納領域が発生しないのでパフォーマンスの向上を図ることができます。%EXTENTSIZE を指定しない場合、既定の初期割り当て行数は標準テーブルで 100,000、一時テーブルで 50 です。1 つのテーブル定義には、%EXTENTSIZE キーワードまたは %NUMROWS キーワードを 1 つのみ使用できます。複数指定すると、SQLCODE -84 エラーが返されます。テーブルにデータが入力されたら、テーブルのチューニングを実行して、この %EXTENTSIZE 値を実際の行数に変更できます。詳細は、“テーブルの最適化” を参照してください。

Caché SQL が提供する %ROUTINE キーワードは、このベース・テーブルに対して生成されるルーチン名の接頭語を指定するのに使用できます。%ROUTINE の後には、一重引用符で囲んだテキスト文字列を続けます。例えば、%ROUTINE 'myname' では、myname1、myname2 というように以降も順次続く一連の名前のルーチンにコードが生成されます。%ROUTINE から ユーザ定義 ("外部") 関数を呼び出すことはできません。1 つのテーブル定義には、%ROUTINE キーワードを 1 つのみ使用できます。複数指定すると、SQLCODE -85 エラーが返されます。スタジオでは、ルーチン名の接頭語は SqlRoutinePrefix 値として表示されます。

%CLASSPARAMETER キーワード

オプションの %CLASSPARAMETER キーワードを使用すると、クラス・パラメータを CREATE TABLE コマンドの一部として定義できます。クラス・パラメータは必ず定数値として定義します。複数の %CLASSPARAMETER キーワード節を指定できます。1 つの節につき 1 つのクラス・パラメータを定義します。すべてのテーブル・キーワード節と同様、%CLASSPARAMETER は、テーブル要素のコンマ区切りリスト内の任意の場所で指定できます。複数の %CLASSPARAMETER 節を指定する場合はコンマで区切ります。

%CLASSPARAMETER キーワードの後には、そのクラス・パラメータに割り当てるクラス・パラメータ名、オプションの等号、およびリテラル値 (文字列または数値) を指定します。以下の例では、2 つのクラス・パラメータを定義します。最初の %CLASSPARAMETER 節では等号を使用し、2 番目の %CLASSPARAMETER 節では等号を省略します。

CREATE TABLE OurEmployees (
    %CLASSPARAMETER DEFAULTGLOBAL = '^EMPLOYEE',
    %CLASSPARAMETER MANAGEDEXTENT 0,
    EMPNUM     INT NOT NULL,
    NAMELAST   CHAR(30) NOT NULL,
    NAMEFIRST  CHAR(30) NOT NULL,
    CONSTRAINT EMPLOYEEPK PRIMARY KEY (EMPNUM))

現在使用されているクラス・パラメータには、DEFAULTGLOBALOpens in a new tabDSINTERVALOpens in a new tabDSTIMEOpens in a new tabEXTENTQUERYSPECOpens in a new tabEXTENTSIZEOpens in a new tabGUIDENABLEDOpens in a new tabIDENTIFIEDBYOpens in a new tabMANAGEDEXTENTOpens in a new tabREADONLYOpens in a new tabROWLEVELSECURITYOpens in a new tabSQLPREVENTFULLSCANOpens in a new tabUSEEXTENTSETOpens in a new tabVERSIONCLIENTNAMEOpens in a new tabVERSIONPROPERTYOpens in a new tab などがあります。これらのクラス・パラメータの説明は、"%Library.PersistentOpens in a new tab" クラスを参照してください。

必要に応じて追加のクラス・パラメータを指定できます。詳細は、"Caché オブジェクトの使用法" の "クラス・パラメータ" を参照してください。

互換性のみにサポートされるオプション

Caché SQL は、構文解析の目的にのみ以下の CREATE TABLE オプションをサポートし、既存の SQL コードから Caché SQL への変換を支援します。これらのオプションは、実際には機能しません。

{ON | IN} dbspace-name

LOCK MODE [ROW | PAGE]

[CLUSTERED | NONCLUSTERED]

WITH FILLFACTOR = literal

MATCH [FULL | PARTIAL]

CHARACTER SET identifier

COLLATE identifier  /* But note use of COLLATE keyword, described below */

NOT FOR REPLICATION

フィールド定義

テーブル名の後に、括弧に囲まれたテーブルの全フィールド (列) 定義があります。フィールドの定義は、コンマで区切ります。規則によって、各フィールドの定義は通常、別の行にインデントされて表示されます。これは必須ではありませんがお勧めします。最後のフィールドを定義した後は、フィールド定義の閉じ括弧を必ず記述してください。

フィールド定義部分は空白で区切ります。フィールド名は最初に記述し、その後にそのデータ特性を続けます。フィールドのデータ特性は、データ型、データ・サイズ (オプション)、データ制約 (オプション) の順に表示されます。オプション・フィールド %DESCRIPTION を追加してフィールドに説明を付けることができます。

Note:

Caché では、400 列を超えるテーブルの作成はお勧めできません。400 列を超える場合は、データベースを設計し直します。これには、列を行に置き換える方法、列を複数の関連テーブルに分割する方法、データを文字ストリームまたはビット・ストリームとして保存し、列を減らす方法などがあります。

フィールド名

フィールド名は、識別子の規約に従い、テーブル名と同様の名前付け制約を受けます。フィールド名の先頭文字に % は使用しないでください (%z または %Z で始まるフィールド名は許容されます)。フィールド名は 128 文字を超えることはできません。既定のフィールド名は、簡単な識別子です。大文字と小文字は区別されません。同一テーブル内の別フィールドと大文字/小文字区別のみが異なるフィールド名を作成しようとすると、SQLCODE -306 エラーが生成されます。詳細は、"Caché SQL の使用法" の “識別子” の章を参照してください。

Caché はフィールド名を使用して、対応するクラス・プロパティ名を生成します。プロパティ名には英数字 (文字および数字) のみを使用し、その長さは最大 96 文字です。Caché は、このプロパティ名を生成するために、最初にフィールド名から句読点を削除し、次に 96 文字以内の一意の識別子を生成します。Caché は、一意のプロパティ名を作成するために、必要に応じてフィールド名の最後の文字を (0 で始まる) 整数に置き換えます。

以下の例は、Caché が句読点のみ異なるフィールド名を処理する方法を示します。これらのフィールドに対応するクラス・プロパティには、PatNumPatNu0、および PatNu1 という名前が付けられています。

CREATE TABLE MyPatients (
     _PatNum VARCHAR(16),
     %Pat@Num INTEGER,
     Pat_Num VARCHAR(30),
     CONSTRAINT Patient_PK PRIMARY KEY (_PatNum))

CREATE TABLE で指定されたフィールド名は、クラス・プロパティで SqlFieldName キーワード値として表示されます。

動的な SELECT 操作では、一般的な大文字/小文字による変形を促すためにプロパティ名のエイリアスが生成されることがあります。例えば、フィールド名 Home_Street の場合、プロパティ名のエイリアスとして home_street、HOME_STREET、および HomeStreet が割り当てられる可能性があります。Caché では、その名前が別のフィールド名、または別のフィールド名に割り当てられているエイリアスと競合する場合、エイリアスは割り当てられません。

データ型

Caché SQL は、多くの標準 SQL データ型をサポートしています。サポートされているデータ型の完全なリストは、"データ型" セクションを参照してください。

CREATE TABLE では、同じデータ型を複数の方法で指定できます。VARCHAR(24)、CHARACTER VARYING(24)、%Library.String(MAXLEN=24)、および %String(MAXLEN=24) はすべて同じデータ型を指定します。ただし、既定の MAXLEN は異なる場合があります。VARCHAR() および CHARACTER VARYING() は既定で MAXLEN=1 に設定されます。%Library.String および %String は既定で MAXLEN=50 に設定されます。

Caché は SQL.SystemDataTypes マッピング・テーブルおよび SQL.UserDataTypes マッピング・テーブルによって、これらの標準 SQL データ型を Caché データ型にマップします。ユーザは、追加のユーザ定義のデータ型を含めるために SQL.UserDataTypes を追加できます。

現在のデータ型のマッピングを表示および変更するには、管理ポータルに進み、システム, 構成, システム定義DDLマッピング を選択します。データ型マッピングをさらに作成するには、管理ポータルに進み、システム, 構成, ユーザ定義DDLマッピング を選択します。

Caché に対応するデータ型がない SQL のデータ型を指定する場合、その SQL データ型の名前が、対応するクラス・プロパティのデータ型として使用されます。DDL の実行 (SQLExecute) 前に、このユーザ定義の Caché データ型を作成する必要があります。

また、データ型のマッピングは、1 つのパラメータ値を上書きできます。例えば、VARCHAR(100) を、与えられた %String(MAXLEN=100) 標準マッピングにマップしたくないとします。この場合、テーブルに 'VARCHAR(100)' の DDL データ型を追加して、これを上書きし、対応する Caché のタイプを指定します。以下はその例です。

VARCHAR(100) maps to MyString100(MAXLEN=100)

データ・サイズ

データ型の後に続けて、許容データ・サイズを括弧で囲んで指定できます。データ型の名前とデータ・サイズの括弧の間には、空白を挿入してもしなくてもかまいません。

文字列の場合、データ・サイズは最大の文字数を表します。例えば以下のようになります。

ProductName VARCHAR (64)

小数が許可される数値の場合、データ・サイズは (p,s) のように整数のペアとして表します。1 つ目の整数 (p) はデータ型の精度ですが、これは数値精度 (数値の桁数) とは異なります。これは、基盤となる Caché データ型クラスは精度を持ちませんが、代わりにこの数値を使用して MAXVAL と MINVAL を計算するためです。2 つ目の整数 (s) は、小数部の最大桁数を指定するスケールです。以下に例を示します。

UnitPrice NUMERIC(6,2)  /* maximum value 9999.99 */

フィールドの最大および最小の許容値を確認するには、以下の ObjectScript 関数を使用します。

  WRITE $$maxval^%apiSQL(6,2),!
  WRITE $$minval^%apiSQL(6,2)

p は桁数ではないため、スケール s の値より小さくてもかまいません。

  FOR i=0:1:6 {
      WRITE "Max for (",i,",2)=",$$maxval^%apiSQL(i,2),!}

詳細は、このドキュメントのリファレンスの "データ型" を参照してください。

フィールドのデータ制約

データ制約によって、フィールドに許可される値、フィールドの既定値、およびデータ値に使用される照合タイプが規定されます。これらのデータ制約は、すべてオプションです。複数のデータ制約は、空白で区切り、任意の順序で指定できます。詳細は、"フィールド制約" を参照してください。

NULL と NOT NULL

NOT NULL データ制約キーワードは、そのフィールドが NULL 値を受け入れないように指定します。つまり、すべてのレコードがこのフィールドに対して指定された値を持つ必要があります。NULL と空文字列 ('') は、Caché では異なる値です。フィールドが NOT NULL 制約で定義されているとしても、文字列を受け入れるフィールドに空文字列を挿入することができます。数値フィールドに空文字列を挿入することはできません。詳細は、"Caché SQL の使用法" の “言語要素” の章にある "NULL" のセクションを参照してください。

NULL データ制約キーワードは、このフィールドが NULL 値を受け入れることを明示的に指定します。これは、フィールドの既定の定義です。

UNIQUE

UNIQUE データ制約は、このフィールドが一意の値のみ受け入れることを指定します。したがって、このフィールドには同じ値を持つレコードは存在しないことになります。SQL では、空文字列 ('') はデータ値と見なされるため、UNIQUE データ制約が適用されている場合は、複数のレコードでこのフィールドを空文字列値にすることはできません。NULL はデータ値と見なされないため、UNIQUE データ制約は複数の NULL に対して適用されません。フィールドに対して NULL を制限するには、NOT NULL キーワード制約を使用します。

  • UNIQUE データ制約では、指定されたフィールドのすべての値が一意の値であることが求められます。

  • 複数フィールドでの UNIQUE 制約 (CONSTRAINT キーワードを使用) では、フィールドの指定されたグループのすべての値を 1 つに連結した場合にその値が一意の値であることが求められます。個々のフィールドを一意の値に制限する必要はありません。

DEFAULT

DEFAULT データ制約では、INSERT でこのフィールドに対してデータ値が指定されていない場合に、INSERT 処理中に Caché でこのフィールドに対して自動的に指定される既定のデータ値が指定されます。INSERT 処理でフィールド・データ値に対して NULL が指定されている場合、既定のデータ値ではなく NULL が取られます。したがって、通常は、同じフィールドに対して DEFAULT データ制約と NOT NULL データ制約の両方を指定します。

DEFAULT 値は、リテラル値またはキーワード・オプションとして指定できます。リテラル既定値として指定する文字列は一重引用符で囲む必要があります。数値既定値には一重引用符は必要ありません。例えば以下のようになります。

CREATE TABLE membertest
(MemberId INT NOT NULL,
Membership_status CHAR(13) DEFAULT 'M',
Membership_term INT DEFAULT 2)

DEFAULT 値はテーブル作成時に検証されません。DEFAULT 値を定義すると、その値ではデータ型およびデータ制約の制限を無視できます。ただし、INSERT を使用してテーブルにデータを提供する際には、DEFAULT 値が制限されます。DEFAULT 値はデータ型の制限は受けませんが、データ制約の制限は受けます。例えば、Ordernum INT UNIQUE DEFAULT 'No Number' で定義されたフィールドの場合、最初は INT データ型の制限を無視して規定値を取ることができますが、2 回目はフィールドの UNIQUE データ制約に違反するため既定値を取ることができません。

DEFAULT が指定されていなければ、暗黙の既定は NULL になります。フィールドに NOT NULL データ制約があれば、このフィールドには明示的に、または DEFAULT で値を指定する必要があります。NOT NULL の既定値として長さゼロの SQL 文字列 (空文字列) は使用しないでください。NULL および空文字列の詳細は、"Caché SQL の使用法" の 言語要素 の章にある "NULL" のセクションを参照してください。

DEFAULT キーワード

DEFAULT データ制約には、その値を定義するキーワード・オプションを指定できます。サポートされているオプションは、NULL、USER、CURRENT_USER、SESSION_USER、SYSTEM_USER、CURRENT_DATE、CURRENT_TIME、CURRENT_TIMESTAMP、SYSDATE、OBJECTSCRIPT です。

USER、CURRENT_USER、および SESSION_USER の DEFAULT キーワードは、"Caché ObjectScript リファレンス" で説明しているように、フィールド値を ObjectScript の $USERNAME 特殊変数に設定します。

CURRENT_DATECURRENT_TIMECURRENT_TIMESTAMPGETDATEGETUTCDATE、および SYSDATE SQL 関数も、DEFAULT 値として使用できます。これらについては、それぞれのリファレンス・ページで説明しています。DEFAULT 値として使用する場合、タイムスタンプ関数は、有効桁数の値を付けても付けなくても指定できます。DEFAULT 値として使用する場合、CURRENT_TIME に有効桁数の値を指定することはできません。

CURRENT_TIMESTAMPGETDATEGETUTCDATE、および SYSDATE は、%Library.TimeStamp フィールド (データ型 TIMESTAMP または DATETIME) の既定値として指定できます。Caché は、データ型に合った形式にデータ値を変換します。

CREATE TABLE mytest
(TestId INT NOT NULL,
CREATE_DATE DATE DEFAULT CURRENT_TIMESTAMP(2),
WORK_START DATE DEFAULT SYSDATE)

データ型 DATE には TO_DATE 関数を DEFAULT データ制約として使用できます。データ型 TIMESTAMP には TO_TIMESTAMP 関数を DEFAULT データ制約として使用できます。

また、OBJECTSCRIPT literal キーワード句を使用すると、以下の例に示すように、ObjectScript コードを含む引用符付き文字列を指定することで既定値を生成できます。

CREATE TABLE mytest
(TestId INT NOT NULL,
CREATE_DATE DATE DEFAULT OBJECTSCRIPT '+$HOROLOG' NOT NULL,
LOGNUM NUMBER(12,0) DEFAULT OBJECTSCRIPT '$INCREMENT(^LogNumber)')

詳細は、"Caché ObjectScript リファレンス" を参照してください。

COMPUTECODE

COMPUTECODE データ制約は、このフィールドの既定値を計算する ObjectScript コードを指定します。ObjectScript コードは中括弧内に指定します。ObjectScript コード内では、SQL フィールド名を中括弧で区切って指定することができます。ObjectScript コードは複数のコード行で構成できます。それには、埋め込み SQL を含むことができます。空白および改行は中括弧で区切られた ObjectScript コードの前後で使用できます。

COMPUTECODE は、SqlComputeCode フィールド名とこのフィールドの値の計算を指定します。COMPUTECODE 内または SqlComputeCode クラス・プロパティ内で、計算されたフィールド名を指定する場合は、対応する生成済みテーブル・プロパティ名ではなく、SQL フィールド名を指定する必要があります。SqlComputeCode プロパティ・キーワードについては、"Caché クラス定義リファレンス" を参照してください。

計算コードによって提供される既定データ値は、論理 (内部保存) モードである必要があります。計算コード内の埋め込み SQL は、自動的にコンパイルされ、論理モードで実行されます。

以下の例では、Birthday COMPUTECODE フィールドを定義します。この定義は、ObjectScript コードを使用して DOB フィールド値から既定値を計算します。

CREATE TABLE MyStudents (
   Name VARCHAR(16) NOT NULL,
   DOB DATE,
   Birthday VARCHAR(10) COMPUTECODE {SET {Birthday}=$PIECE($ZDATE({DOB},9),",")},
   Grade INT
   )

COMPUTECODE には、擬似フィールド参照変数 {%%CLASSNAME}、{%%CLASSNAMEQ}、{%%OPERATION}、{%%TABLENAME}、および {%%ID} を含めることができます。これらの擬似フィールドは、クラスのコンパイル時に特定の値に変換されます。これらの擬似フィールド・キーワードは、すべて大文字と小文字が区別されません。

COMPUTECODE 値は既定値であるため、フィールドに値を指定しなかった場合にのみ返されます。COMPUTECODE 値はデータ型の制限を受けません。COMPUTECODE 値は UNIQUE データ制約などのデータ制約の制限を受けます。DEFAULT および COMPUTECODE の両方を指定した場合は、必ず DEFAULT が取られます。

COMPUTECODE ではオプションで COMPUTEONCHANGE、CALCULATED、または TRANSIENT キーワードを取ることができます。以下のキーワードの組み合わせの動作がサポートされています。

  • COMPUTECODE:値は、計算されて INSERT 時に保存されます。UPDATE 時には変更されません。

  • COMPUTEONCHANGE の COMPUTECODE:値は、計算されて INSERT 時に保存されます。UPDATE 時には再計算されて保存されます。

  • DEFAULT と COMPUTEONCHANGE の COMPUTECODE:既定値は、INSERT 時に保存されます。値は、UPDATE 時に計算されて保存されます。

  • CALCULATED または TRANSIENT の COMPUTECODE:値は保存されません。クエリ時に値は計算されます。

ObjectScript の COMPUTECODE コードにエラーがある場合は、そのコードが初めて実行されるときまで、SQL ではこのエラーは検出されません。そのため、挿入時に値が初めて計算される場合は、INSERT 操作は SQLCODE -415 エラーで失敗します。更新時に値が初めて計算される場合は、UPDATE 操作は SQLCODE -415 エラーで失敗します。クエリ時に値が初めて計算される場合は、SELECT 操作は SQLCODE -400 エラーで失敗します。

COMPUTECODE 保存値にインデックスを付けることができます。アプリケーション開発者は、特に計算フィールドのインデックスを定義する (またはしようとしている) 場合、そのデータ型に基づいて、計算フィールドの保存値が検証され、正規化されている (キャノニック形式の数値) ことを確認する必要があります。

COMPUTEONCHANGE

COMPUTECODE を使用することで、自動的に、INSERT 時にフィールド値が計算されてデータベースに保存されます。この値は、後続の操作でも変更されないままとなります。既定では、計算された値はその後の UPDATE 操作またはトリガ・コードの処理で変更されません。COMPUTEONCHANGE キーワードを指定することで、後続の UPDATE またはトリガ・コード処理が起こり、この保存された値が再計算されて置き換えられます。

COMPUTEONCHANGE 節を使用してフィールドまたはコンマ区切りのフィールドのリストを指定した場合、これらのフィールドのいずれかの値が変更されると COMPUTECODE フィールド値が再計算されます。

COMPUTEONCHANGE で指定されたフィールドがテーブル仕様に含まれていない場合は、SQLCODE -31 が生成されます。

以下の例では、Birthday は、挿入時に DateOfBirth 値に基づいて計算されます。Birthday は、DateOfBirth が更新されるときに再計算されます。

CREATE TABLE SQLUser.MyStudents (
   Name VARCHAR(16) NOT NULL,
   DateOfBirth DATE,
   Birthday VARCHAR(40) COMPUTECODE {
        SET {Birthday}=$PIECE($ZDATE({DOB},9),",")
        _" changed: "_$ZTIMESTAMP }
        COMPUTEONCHANGE (DOB)
     )
Note:

既存の DateOfBirth 値を指定する DateOfBirth 値に対して UPDATE を実行しても Birthday フィールドの値は再計算されません。

COMPUTEONCHANGE は、フィールド定義に対応するクラス・プロパティのために SqlComputeOnChange キーワードを %%UPDATE 値と共に定義します。このプロパティ値は、最初に INSERT 処理の一部として計算され、UPDATE 処理の間に再計算されます。対応する永続クラスの定義は、"Caché SQL の使用法" の “テーブルの定義” の章の "永続クラスの作成によるテーブルの定義" を参照してください。

CALCULATED および TRANSIENT

CALCULATED または TRANSIENT キーワードを指定すると、COMPUTECODE フィールド値はデータベースに保存されず、このフィールド値にアクセスする各クエリ操作の一環として計算されます。これにより、データ・ストレージのサイズが縮小しますが、クエリのパフォーマンスが低下するおそれがあります。この 2 つのキーワード節を指定すると COMPUTECODE フィールド値が保存されないため、これらのキーワードと COMPUTEONCHANGE キーワードは相互排他的です。以下は、CALCULATE フィールドの例です。

CREATE TABLE MyStudents (
   Name VARCHAR(16) NOT NULL,
   DOB DATE,
   Days2Birthday INT COMPUTECODE{SET {Days2Birthday}=$ZD({DOB},14)-$ZD($H,14)} CALCULATED
   )

CALCULATED は、フィールド定義に対応するクラス・プロパティの Calculated ブーリアン・キーワードを定義します。TRANSIENT は、フィールド定義に対応するクラス・プロパティの Transient ブーリアン・キーワードを定義します。これらのプロパティ・キーワードについては、"Caché クラス定義リファレンス" を参照してください。

CALCULATED と TRANSIENT はほぼ同じ動作を提供しますが、次のような違いがあります。TRANSIENT ではプロパティが保存されません。CALCULATED ではプロパティに対してインスタンス・メモリが割り当てられません。そのため、CALCULATED が指定されるとTRANSIENT が暗黙的に設定されます。

TRANSIENT のプロパティにインデックスを付けることはできません。CALCULATED のプロパティには、そのプロパティが SQLComputed でない場合はインデックスを付けることはできません。

照合パラメータ

オプションの照合パラメータは、フィールドの値のソート時に使用する文字照合タイプを指定します。Caché SQL は、10 タイプの照合をサポートします。照合を指定しない場合、既定は %SQLUPPER 照合で、大文字と小文字が区別されません。

プログラミングを明確にする目的で、照合パラメータの前にオプション・キーワードの COLLATE を指定することを推奨します。ただし、このキーワードは必須ではありません。これらのさまざまな照合パラメータ・キーワードの先頭のパーセント記号 (%) はオプションです。

%EXACT 照合は、ANSI (または Unicode) 文字の照合順に従います。大文字/小文字を区別する文字列照合を行い、先頭および末尾の空白およびタブ文字を認識します。

%MVR 照合では、文字列を部分文字列のグループとして処理します。数値の部分文字列は符号付き数値の照合順で並べ替えられ、数値以外の部分文字列は大文字/小文字を区別する文字列照合順で並べ替えられます。%MVR は、MultiValue データベース・システムとの互換性を保つためのものです。

%ALPHAUP、%SQLUPPER、%STRING、および %UPPER 照合は、照合目的ですべての文字を大文字に変換します。%ALPHAUP、%STRING、および %UPPER 照合は非推奨です。このタイプの文字列照合には %SQLUPPER が推奨されます。大文字と小文字を区別しない照合の詳細は、"%SQLUPPER" 関数を参照してください。

%SPACE、%SQLUPPER、および %STRING 照合はデータに空白を追加します。これにより、NULL と数値の文字列照合が強制されます。

%SQLSTRING、%SQLUPPER、および %STRING 照合では、括弧で囲む必要のある maxlen パラメータをオプションで使うことができます。maxlen は切り捨てを命令する整数で、照合の実行時に対象とする最大文字数を指定します。このパラメータは、サイズの大きなデータ値を持つフィールドにインデックスを作成するときに便利です。

%PLUS および %MINUS 照合は、NULL をゼロ (0) 値として処理します。

Caché SQL には、これらの照合タイプのほとんどに対応する関数があります。詳細は、"%EXACT"、"%MVR"、"%ALPHAUP"、"%SQLSTRING"、"%SQLUPPER"、"%STRING"、"%UPPER" の各関数を参照してください。

ObjectScript では、データ照合変換のために %SYSTEM.UtilOpens in a new tab クラスの Collation()Opens in a new tab メソッドが提供されています。

Note:

ネームスペースの既定の照合を %SQLUPPER (大文字/小文字の区別なし) から %SQLSTRING (大文字/小文字の区別あり) などの他の照合タイプに変更するには、以下のコマンドを使用します。

  WRITE $$SetEnvironment^%apiOBJ("collation","%Library.String","SQLSTRING")

このコマンドを発行した後に、インデックスを削除し、すべてのクラスを再コンパイルしてから、再度インデックスを構築する必要があります。他のユーザがテーブルのデータにアクセスしている間はインデックスを再構築しないでください。再構築すると、クエリ結果が不正確になる可能性があります。

%DESCRIPTION

フィールドには、説明用のテキストを追加できます。このオプションに適用される規則は、テーブルの説明テキストと同じです。それらの規則は、その他のテーブル要素と共に前述されています。

複数フィールドでの一意制約

複数フィールドでの一意制約では、複数のフィールドを組み合わせた値に一意の値の制約が適用されます。この構文は以下のとおりです。

CONSTRAINT uname UNIQUE (f1,f2)

この制約はフィールド値 f1 および f2 の組み合わせが必ず一意でなければならいことを示します。これらの個々のフィールドの値自体は一意でなくてもかまいません。この制約に対して、1 つ、2 つ、あるいは 3 つ以上のフィールドを指定できます。

この制約で指定するフィールドはすべて、フィールド定義で定義する必要があります。フィールド定義で定義されていないフィールドをこの制約で指定すると、SQLCODE -86 エラーが生成されます。指定するフィールドには NOT NULL を定義する必要があります。指定するフィールドにはいずれも UNIQUE を定義しないでください。そのように定義すると、この制約を指定しても意味がありません。

フィールドは任意の順序で指定できます。このフィールドの順序によって、対応するインデックス定義のフィールドの順序が決まります。フィールド名の重複が許可されています。複数フィールドでの UNIQUE 制約に単一のフィールド名を指定することができますが、これはそのフィールドに UNIQUE データ制約を指定するのと機能的には同じです。将来的に使用できるように、個々の単一フィールドの制約が 1 つの制約名を指定します。

複数フィールドでの一意制約の複数の文を 1 つのテーブル定義で指定することができます。制約文はフィールド定義の任意の場所で指定できます。慣例により、通常は定義されるフィールドのリストの最後に配置します。

制約名

CONSTRAINT キーワードおよび複数フィールドでの一意制約名はオプションです。以下は機能的に同じです。

CONSTRAINT myuniquefields UNIQUE (name,dateofbirth)
UNIQUE (name,dateofbirth)

制約名は任意の有効な識別子にすることができます。制約名はその制約を一意に識別し、対応するインデックス名を生成する際にも使用されます。CONSTRAINT name を指定することをお勧めします。この制約名は、ALTER TABLE コマンドを使用してテーブル定義から制約を削除する際に必要になります。

CONSTRAINT UNIQUE にリストされている列を ALTER TABLE で削除することはできません。これを実行しようとすると、SQLCODE -322 エラーが生成されます。

RowID レコード識別子

SQL では、すべてのレコードは RowID という一意の整数値によって識別される必要があります。Caché SQL では、RowID フィールドを指定する必要はありません。テーブルを作成して希望のデータ・フィールドを指定するとき、RowID フィールドが自動的に作成されます。この RowID は内部的に使用されますが、クラス・プロパティにマップはされません。既定では、クラスが SQL に投影される場合にのみ、表示されます。この投影された SQL では、追加の RowID フィールドが表示されます。

例えば、CREATE TABLE 文は Name、Age、Address という 3 つのフィールドを指定します。これに対応するクラスには、Name、Age、Address という 3 つのクラス・プロパティが含まれていますが、このクラスから投影された SQL には ID という追加のフィールドも含まれています。

既定では、このフィールドの名前は "ID" です。ただし、このフィールド名は予約されていません。“ID” という名前のフィールドを定義した場合、Caché によって RowId には “ID1” という名前が割り当てられます。例えば、その後でユーザが ALTER TABLE を使用して “ID1” という名前のフィールドを定義すると、Caché は RowID の名前を “ID2” に変更します (それ以降も同様に動作します)。そのため、Caché は、どのような名前が RowID に割り当てられていても常に RowID (オブジェクト ID) 値を返す、%ID 疑似列名 (エイリアス) を提供しています。

RowID 値は、1 から始まる連続する正の整数です。RowID 用に生成される値には、以下の制約があります。各値は一意です。NULL 値は許可されていません。照合は EXACT です。値は変更できません。この既定値は、Config.SQLOpens in a new tab クラスの AllowRowIDUpdateOpens in a new tab プロパティを使用して変更できます。このメソッドを使用する際には、十分に注意する必要があります。

レコードをテーブルに挿入すると、Caché は各レコードに整数の ID 値を割り当てます。既定では、Caché は ID の割り当てを、複数のプロセスによるテーブルへの迅速な同時入力ができる $SEQUENCE を使用して実行します。(Caché が $INCREMENT を使用して ID 割り当てを実行するように構成するには、SetDDLUseSequence()Opens in a new tab メソッドを設定するか、または対応する管理ポータルの [一般 SQL 設定] : [DDL タブ] オプションを設定することができます。)

%PUBLICROWID

既定では、RowId は非表示で (SELECT * では表示されない)、PRIVATE です。%PUBLICROWID キーワードを指定すると、RowID は非公開から公開に変更されます。このキーワードはテーブルの RowID を PUBLIC にすることを指定しているため、この RowID は外部キー参照として使用できるようになります。%PUBLICROWID キーワードを指定する場合、テーブルに対応するクラスは “Not SqlRowIdPrivate” で定義されます。このオプション・キーワードは、テーブル要素のコンマ区切りリスト内の任意の場所で指定できます。

ALTER TABLE を使用して %PUBLICROWID を指定することはできません。

ビットマップ・エクステント・インデックス

CREATE TABLE を使用してテーブルを作成する場合、既定では、Caché は自動的に対応するクラスのビットマップ・エクステント・インデックスを定義します。ビットマップ・エクステント・インデックスの SQL マップ名は、%%DDLBEIndex です。

Index DDLBEIndex [ Extent, SqlName = "%%DDLBEIndex", Type = bitmap ];

このビットマップ・エクステント・インデックスは、以下の状況では作成されません

ビットマップ・インデックスを作成した後に、CREATE BITMAPEXTENT INDEX を呼び出して、ビットマップ・エクステント・インデックスが自動的に定義されたテーブルに対して実行すると、それ以前に定義されているビットマップ・エクステント・インデックスは、CREATE BITMAPEXTENT INDEX 文により指定された名前に変更されます。

既存のビットマップ・エクステント・インデックスを自動的に削除する DDL 操作については、“ALTER TABLE” を参照してください。

詳細は、“Caché SQL 最適化ガイド” の “インデックスの定義と構築” の章の “ビットマップ・エクステント・インデックス” を参照してください。

IDENTITY フィールド

Caché SQL は各テーブルについて自動的に RowID を作成します。これはシステムが作成する整数値で、一意のレコード ID となります (以下のセクションを参照)。この IDENTITY キーワード・オプションを使用すると、同じプロパティを持つ名前付きのフィールドを RowID レコード ID フィールドとして定義できます。IDENTITY フィールドは、システムが生成する整数値を値として持つ単一フィールドの IDKEY 値として動作します。

システムが生成するあらゆる ID フィールドと同様に、IDENTITY フィールドは以下の特性を持ちます。

  • IDENTITY フィールドとして定義できるのは、1 テーブルに 1 つのフィールドです。複数の IDENTITY フィールドを定義しようとすると、SQLCODE -308 エラーが発生します。

  • IDENTITY フィールドのデータ型は整数データ型であることが必要です。データ型を指定しないと、自動的に INTEGER として定義されます。SMALLINT や BIGINT など、任意の整数データ型を指定できます。NOT NULL や UNIQUE のようなフィールド制約は受け入れられますが、無視されます。

  • データ値はシステムが生成します。値は一意で、0 以外の正の整数です。

  • 既定では、IDENTITY フィールドのデータ値をユーザが指定することはできません。既定では、INSERT 文は IDENTITY フィールドの値を指定しません。指定しようとしてもできません。これを実行しようとすると、SQLCODE -111 エラーが生成されます。IDENTITY フィールドの値を指定できるかどうかを確認するには、%SYSTEM.SQLOpens in a new tab クラスの GetIdentityInsert()Opens in a new tab メソッドを呼び出します。この設定を変更するには、%SYSTEM.SQLOpens in a new tab クラスの SetIdentityInsert()Opens in a new tab メソッドを呼び出します。詳細は、"INSERT" 文を参照してください。

  • IDENTITY フィールドのデータ値を UPDATE 文で変更することはできません。これを実行しようとすると、SQLCODE -107 エラーが生成されます。

  • システムが自動的に、IDENTITY フィールド上の主キーを ODBC および JDBC に投影します。CREATE TABLE 文または ALTER TABLE 文によって、IDENTITY フィールドまたは IDENTITY フィールドを含む列セット上に主キー制約または一意の制約を定義すると、その制約定義は無視されます。したがって、対応する主キーまたは一意のインデックス定義が作成されることはありません。

  • SELECT * 文はテーブルの IDENTITY フィールドを返します

INSERTUPDATE、または DELETE 操作に続いて LAST_IDENTITY 関数を使用すると、直前に変更したレコードの IDENTITY フィールドの値を返すことができます。IDENTITY フィールドが定義されていない場合、LAST_IDENTITY は直前に変更したレコードの RowID 値を返します。

以下の 2 つの埋め込み SQL プログラムでは、IDENTITY フィールドを持つテーブルを作成し、テーブルにレコードを挿入して、IDENTITY フィールド値を生成します。埋め込み SQL では、CREATE TABLE 文と INSERT 文を異なるプログラム内に配置する必要があることに注意してください。

   DO $SYSTEM.Security.Login("_SYSTEM","SYS")
   &sql(CREATE TABLE Employee (
  EmpNum INT NOT NULL,
  MyID   IDENTITY NOT NULL,
  Name   CHAR(30) NOT NULL,
  CONSTRAINT EMPLOYEEPK PRIMARY KEY (EmpNum))
  )
  IF SQLCODE'=0 {
    WRITE !,"CREATE TABLE error is: ",SQLCODE }
  ELSE {
   WRITE !,"Table created" }
  &sql(INSERT INTO Employee (EmpNum,Name) 
    SELECT ID,Name FROM SQLUser.Person WHERE Age >= '25')
  IF SQLCODE'=0 {
    WRITE !,"INSERT error is: ",SQLCODE }
  ELSE {
   WRITE !,"Record inserted into table" }

この場合、主キー (EmpNum) は別のテーブルの ID フィールドから取得されます。したがって EmpNum の値は一意の整数になりますが、WHERE 節のため、数字が連続しない場合もあります。IDENTITY フィールドの MyID は、ユーザから可視の一意の連続した整数を、各レコードに割り当てます。

ROWVERSION と SERIAL フィールド

InterSystems SQL には、次の 2 つの整数カウンタ・フィールドのデータ型が用意されています。

  • ROWVERSION (%Library.RowVersionOpens in a new tab) では、ネームスペース全体のすべての RowVersion テーブルに対する挿入と更新をカウントします。ROWVERSION フィールドを含むテーブルの挿入と更新のみが、この整数カウンタをインクリメントします。ROWVERSION の値は一意で、変更できません。このネームスペース全体のカウンタがリセットされることはありません。

  • SERIAL (%Library.CounterOpens in a new tab) では、テーブルへの挿入をカウントします。既定では、このフィールドは自動的にインクリメントされた整数を受け取ります。ただし、ユーザはこのフィールドに値を指定できます。ユーザ指定の値によって、自動カウンタのインクリメント開始点を増やすことができます。

主キーの定義

PRIMARY KEY 節を使用して、フィールドを主レコード識別子として明示的に定義することができます。主キーを定義する場合、以下の 3 つの構文形式を使用できます。

CREATE TABLE MyTable (Field1 INT PRIMARY KEY, Field2 INT)

CREATE TABLE MyTable (Field1 INT, Field2 INT, PRIMARY KEY (Field1))

CREATE TABLE MyTable (Field1 INT, Field2 INT, CONSTRAINT MyTablePK PRIMARY KEY (Field1))

最初の構文では、1 つのフィールドを主キーとして定義します。フィールドを主キーとして指定する場合、そのフィールドは定義上は一意で、NULL ではありません。2 番目と 3 番目の構文は、単一フィールドの主キーに使用できますが、複数のフィールドで構成される主キーに使用することもできます。これは例えば、PRIMARY KEY (Field1,Field2) などの場合です。単一フィールドを指定する場合、そのフィールドは定義上一意であり、NULL ではありません。コンマ区切りリストのフィールドを指定する場合、各フィールドは NULL ではないと定義されますが、フィールドの値の組み合わせが一意の値である限り、重複する値を含めることができます。3 番目の構文では、主キーの名前を明示的に付けることができます。最初の 2 つの構文形式では、テーブル名 + “PKey” + 位置カウント整数という形式で主キーの名前が生成されます。したがって、最初の構文例は MyTablePKey1 という主キー名を持ちます。2 番目の構文例は MyTablePKey3 という主キー名を持ちます。

主キーには、重複する値や NULL 値は設定できません (主キー・インデックス・プロパティは自動的に必須として定義されるわけではありませんが、主キー・フィールドには NULL 値を保存できないので、事実上、必須です)。主キーの照合タイプは、フィールドそのものの定義で指定されます。

定義済みの主キーを持つクラスが SQL に投影される場合、追加の "ID" という RowID フィールドが表示されます。その値は IDKEY フィールドの値と同じになります。

IDKEY の主キー

既定では、主キーは IDKEY ではありません。通常は、主キー値の更新や、主キーの照合タイプの設定などを行えるため、既定を推奨します。ただし、主キーを IDKEY として定義する方が好ましい場合もあります。その場合は、その後主キーを使用するにあたって IDKEY が制限されることを考慮する必要があります。

既存のフィールドに主キー制約を追加する場合、フィールドが自動的に 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) です。このオプションが “はい” (1) に設定されている場合、主キーは IDKEY に対応しません。IDKEY ではない主キーを使用したレコードへのアクセスはかなり非効率的です。 しかし、主キーの値は変更することができます。このオプションが “いいえ” (0) に設定されている場合、データ・アクセスはより効率的ですが、一度設定されたキー値は二度と変更することはできません。

Caché では、IDKEY に属するプロパティ (フィールド) を SqlComputed にすることができます。例えば、親参照フィールドなどです。このプロパティは、トリガによって計算されるフィールドとする必要があります。SqlComputed として定義した IDKEY プロパティは、新規オブジェクトを初めて保存するときまたは INSERT 操作のときにのみ計算されます。IDKEY フィールドは更新できないので、UPDATE 操作でトリガする計算はできません。

主キーなし

多くの場合、明示的に主キーを定義する必要があります。ただし、主キーが指定されない場合、Caché では、以下のルールに基づいて、別のフィールドを ODBC/JDBC プロジェクションの主キーとして使用します。

  1. 単一のフィールド上に IDKey インデックスが存在する場合、IDKEY フィールドを SQLPrimaryKey フィールドとして報告する。

  2. そうでない場合、クラスが SqlRowIdPrivate=0 (既定) で定義されていれば、RowID フィールドを SQLPrimaryKeyフィールド として報告する。

  3. そうでない場合、IDKey インデックスが存在すると、IDKEY フィールドを SQLPrimaryKey フィールドとして報告する。

  4. そうでない場合、SQLPrimaryKey を報告しない。

複数の主キー

主キーは 1 つしか定義できません。テーブルに複数の主キーを指定しようとすると、設定によって結果が異なります。既定では、Caché は、主キーが既に存在する場合に主キーを定義しようとしたり、同じ主キーを 2 回定義しようとしたりすると、それを拒否して 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) です。このオプションの設定が “いいえ” の場合、テーブルに既に主キー制約が存在するのに DDL で主キー制約を追加しようとすると、Caché は SQLCODE -307 エラーを発行します。主キーの第 2 定義が最初の定義と同じ場合もエラーを発行します。

例えば、以下に CREATE TABLE 文があります。

CREATE TABLE MyTable (f1 VARCHAR(16), 
CONSTRAINT MyTablePK PRIMARY KEY (f1))

この文は、主キーを作成します (存在しない場合)。次に、ALTER TABLE 文があります。

ALTER TABLE MyTable ADD CONSTRAINT MyTablePK PRIMARY KEY (f1)

上記の例は、SQLCODE -307 エラーを生成します。

[既存キーに対して DDL の Create Primary Key を許可] が “はい” (1) に設定されている場合、Caché は既存の主キー制約を排除し、最後に指定された主キーをテーブルの主キーとして設定します。

外部キーの定義

外部キーは他のテーブルを参照するフィールドです。外部キー・フィールドに保存された値は、他のテーブル内のレコードを一意に識別します。この参照の最も単純な形式を以下の例に示します。この例では、外部キーが Customers テーブルの主キー・フィールド CustID を暗黙的に参照しています。

CREATE TABLE Orders (
   OrderID INT UNIQUE NOT NULL,
   OrderItem VARCHAR,
   OrderQuantity INT,
   CustomerNum INT,
   CONSTRAINT OrdersPK PRIMARY KEY (OrderID),
   CONSTRAINT CustomersFK FOREIGN KEY (CustomerNum) REFERENCES Customers (CustID)
   )

通常、外部キーは他のテーブルの主キー・フィールドを参照します。ただし、外部キーは IDKEY 列または IDENTITY 列を参照できます。外部キー参照は参照されるテーブルに常に存在し、一意として定義される必要があります。参照されるフィールドは重複値または NULL を持つことはできません。

外部キー定義では以下の内容を指定できます。

  • 1 つのフィールド名:FOREIGN KEY (CustomerNum) REFERENCES Customers (CustID)。外部キー・フィールド (CustomerNum) および参照されるフィールド (CustID) は異なる名前でも (同じ名前でも) かまいませんが、データ型とフィールドの制約は同じでなければなりません。

  • コンマで区切られたフィールド名のリスト:FOREIGN KEY (CustomerNum,SalespersonNum) REFERENCES Customers (CustID,SalespID)。外部キー・フィールドおよび参照されるフィールドは、フィールドの数およびリストでの順序が一致している必要があります。

  • 省略されたフィールド名:FOREIGN KEY (CustomerNum) REFERENCES Customers

外部キーを定義して、参照されるフィールド名を省略した場合、外部キーの既定は次のようになります。

  1. 指定されたテーブルで定義されている主キー・フィールド。

  2. 指定されたテーブルに主キーが定義されていない場合、外部キーの既定は指定されたテーブルで定義されている IDENTITY 列になります。

  3. 指定されたテーブルに主キーも IDENTITY 列も定義されておらず、指定されたテーブルの RowID が public の場合、外部キーの既定は RowID になります。指定されたテーブル定義でこれを明示的に行うには、%PUBLICROWID キーワードを指定するか、対応するクラス定義で SqlRowIdPrivate=0 (既定) を指定します。

上記のいずれの既定も適用されない場合は、SQLCODE -315 エラーが発行されます。

次の例に示すように、クラス定義では、親テーブルの IDKEY プロパティに基づくフィールドを含む外部キーを指定できます。

  ForeignKey Claim(CheckWriterPost.Hmo,Id,Claim) References SQLUser.Claim.Claim(DBMSKeyIndex);

子の外部キーに定義された親フィールドは親クラスの IDKey インデックスの一部である必要があるため、このタイプの外部キーでサポートされている参照動作は NO ACTION のみです。

  • 存在しないテーブルを外部キーで参照すると、SQLCODE -310 エラーが発行され、%msg に補足情報が示されます。

  • 存在しないフィールドを外部キーで参照すると、SQLCODE -316 エラーが発行され、%msg に補足情報が示されます。

  • 一意ではないフィールドを外部キーで参照すると、SQLCODE -314 エラーが発行され、%msg に補足情報が示されます。

外部キー・フィールドが 1 つのフィールドを参照する場合は、2 つのフィールドで、データ型とフィールドのデータ制約が同じである必要があります。

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

参照アクション節

テーブルに外部キーが含まれる場合は、1 つのテーブルでの変更が他のテーブルにも影響します。外部キーを定義するときにデータの整合性を維持するには、外部キーの元となっているレコードを変更したときに外部キー値に与える影響も定義します。

外部キー定義は、以下の 2 つの参照動作節を含みます。

ON DELETE ref-action

あるいは以下のコードを入力します。

ON UPDATE ref-action

ON DELETE 節は、参照されるテーブルに対する DELETE ルールを定義します。参照されるテーブルから行が削除されるとき、ON DELETE 節は参照しているテーブルの行に対してどのような操作を行うかを定義します。

ON UPDATE 節は、参照されるテーブルに対する UPDATE ルールを定義します。参照されるテーブルから行の主キー値を変更 (更新) しようとする場合、参照しているテーブルの行に対してどのように作用するかは ON UPDATE 節に定義します。

Caché SQL は以下の外部キー参照動作をサポートします。

  • NO ACTION

  • SET DEFAULT

  • SET NULL

  • CASCADE

NO ACTION — 参照されるテーブル内の行が削除されたり、キー値が更新されるとき、参照されるすべてのテーブルは、削除や更新される行を参照している行があるかどうかをチェックします。参照している行がある場合は、削除や更新は失敗します。(この制約は、外部キーが自身を参照している場合、適用されません。)NO ACTION は既定です。

SET NULL — 参照されるテーブル内の行が削除されたり、そのキー値が更新されるとき、参照されるすべてのテーブルは、削除や更新される行を参照している行があるかどうかをチェックします。参照している行がある場合は、削除や更新されている行を参照する外部キー・フィールドが NULL に設定されます。外部キー・フィールドは、NULL 値を許可します。

SET DEFAULT — 参照されるテーブル内の行が削除されたり、そのキー値が更新されるとき、参照されるすべてのテーブルは、削除や更新される行を参照している行があるかどうかをチェックします。参照している行がある場合は、削除や更新されている行を参照する外部キー・フィールドにそのフィールドの既定値が設定されます。外部キー・フィールドが既定値を持たない場合は、NULL に設定されます。行は参照されるテーブル内に存在しなければならないことに注意してください。また、参照されるテーブルには、既定値に対するエントリが含まれます。

CASCADE — 参照されるテーブル内の行が削除される場合、参照するすべてのテーブルでは、削除されている行を参照している行があるかどうかがチェックされます。参照している行がある場合は、削除によって、削除される行を参照している外部キー・フィールドの行も削除されます。

参照されるテーブルで行のキーの値が更新されると、参照しているすべてのテーブルでは、更新される行を参照している行があるかどうかがチェックされます。参照している行がある場合は、更新によって、更新される行を参照する外部キー・フィールドの参照しているすべての行も続けて更新されます。

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

以下は、CREATE TABLE 文を発行する埋め込み SQL の例です。このコマンドは両方の参照動作節を使用します。この例では、(主キー フィールド PhysNum を持つ) Physician という関連テーブルが既に存在していることが前提となっています。

  DO $SYSTEM.Security.Login("_SYSTEM","SYS")
  &sql(CREATE TABLE Patient (
     PatNum VARCHAR(16),
     Name VARCHAR(30),
     DOB DATE,
     Primary_Physician VARCHAR(16) DEFAULT 'A10001982321',
     CONSTRAINT Patient_PK PRIMARY KEY (PatNum),
     CONSTRAINT Patient_Physician_FK FOREIGN KEY
          Primary_Physician REFERENCES Physician (PhysNum)
          ON UPDATE CASCADE
          ON DELETE SET NULL)
  )
  WRITE !,"SQL code: ",SQLCODE

詳細は、"Caché SQL の使用法" の “外部キーの使用法” の章を参照してください。

暗黙的な外部キー

すべての外部キーは明示的に定義することをお勧めします。ただし、暗黙的な外部キーを ODBC/JDBC および管理ポータルに投影することもできます。

外部キーが明示的に定義されていない場合、暗黙的な外部キーは以下の規則に従います。

  1. 明示的な外部キーが定義されている場合、Caché はその制約を報告する。

  2. そうでない場合、テーブルの各参照列の参照が主キーおよび IDKEY であるインデックスを持つテーブルに対するものであるかどうかを確認する。その場合、Caché はこの参照を外部キー制約として報告する。

  3. そうでない場合、参照フィールドが親参照フィールドであり、参照されるテーブルが RowID フィールドを暗黙的な主キー・フィールドとして報告していると、Caché はこの親参照を外部キー制約として報告する。

これらの暗黙的な外部キー制約のいずれかが明示的な外部キー定義の対象になると、暗黙的な外部キー制約は定義されません。

例 : ダイナミック SQL と埋め込み SQL

以下の例は、ダイナミック SQL と埋め込み SQL を使用した CREATE TABLE を示しています。ダイナミック SQL では、同じプログラムを使用してテーブルの作成とテーブルへのデータの挿入を実行することができます。埋め込み SQL では、テーブルの作成とテーブルへのデータの挿入には異なるプログラムを使用する必要があります。

最後のプログラム例でこのテーブルを削除するので、これらの例は繰り返して実行できます。

以下のダイナミック SQL の例では、SQLUser.MyStudents テーブルを作成しています。COMPUTECODE は ObjectScript コードであり、SQL コードではないため、ObjectScript $PIECE 関数は二重引用符の区切り文字を使用します。コード行自体が引用符付き文字列であるため、$PIECE 区切り文字は、以下に示すように引用符で二重に囲んでリテラルとしてエスケープする必要があります。

CreateStudentTable
  ZNSPACE "Samples"
    SET stuDDL=5
    SET stuDDL(1)="CREATE TABLE SQLUser.MyStudents ("
    SET stuDDL(2)="StudentName VARCHAR(32),StudentDOB DATE,"
    SET stuDDL(3)="StudentAge INTEGER COMPUTECODE {SET {StudentAge}="
    SET stuDDL(4)="$PIECE(($PIECE($H,"","",1)-{StudentDOB})/365,""."",1)} CALCULATED,"
    SET stuDDL(5)="Q1Grade CHAR,Q2Grade CHAR,Q3Grade CHAR,FinalGrade VARCHAR(2))"
  SET tStatement = ##class(%SQL.Statement).%New(0,"Sample")
  SET qStatus = tStatement.%Prepare(.stuDDL)
    IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
  SET rtn = tStatement.%Execute()
  IF rtn.%SQLCODE=0 {WRITE !,"Table Create successful"}
  ELSEIF rtn.%SQLCODE=-201 {WRITE "Table already exists, SQLCODE=",rtn.%SQLCODE,!}  
  ELSE {WRITE !,"table create failed, SQLCODE=",rtn.%SQLCODE,!
        WRITE rtn.%Message,! }

以下の埋め込み SQL の例では、SQLUser.MyStudents テーブルを作成しています。

   ZNSPACE "Samples"
  &sql(CREATE TABLE SQLUser.MyStudents (
       StudentName VARCHAR(32),StudentDOB DATE,
       StudentAge INTEGER COMPUTECODE {SET {StudentAge}=
       $PIECE(($PIECE($H,",",1)-{StudentDOB})/365,".",1)} CALCULATED,
       Q1Grade CHAR,Q2Grade CHAR,Q3Grade CHAR,FinalGrade VARCHAR(2))
       )
  IF SQLCODE=0 {WRITE !,"Created table" }
  ELSEIF SQLCODE=-201 {WRITE !,"SQLCODE=",SQLCODE," ",%msg }
  ELSE {WRITE !,"CREATE TABLE failed, SQLCODE=",SQLCODE } 

次の例では、前の例で作成したテーブルを削除します。

  &sql(DROP TABLE SQLUser.MyStudents)
  IF SQLCODE=0 {WRITE !,"Table deleted" }
  ELSE {WRITE !,"SQLCODE=",SQLCODE," ",%msg }

関連項目

FeedbackOpens in a new tab