CREATE TABLE文またはALTER TABLE文で表の新しい列を定義する場合、その列のデータ型を指定する必要があります。列のデータ型によって、SQLでの列の値の解釈方法および格納方法が制御されます。値式(ファンクション、パラメータおよびリテラル)にはすべて、データ型が関連付けられています。
表2-8に、SQLデータ型のキーワード、および基底OpenVMSデータ型のリストを示します。
SQLキーワード | OpenVMSデータ型 |
---|---|
CHAR (n) | 文字列(DSC$K_DTYPE_T) |
CHAR (n)、キャラクタ・セットによる修飾 | 文字列(DSC$K_DTYPE_T) |
NCHAR (n) | 文字列(DSC$K_DTYPE_T) |
VARCHAR (n) | 可変文字列(DSC$K_DTYPE_VT) |
VARCHAR (n)、キャラクタ・セットによる修飾 | 可変文字列(DSC$K_DTYPE_VT) |
NCHAR VARYING(n) | 可変文字列(DSC$K_DTYPE_VT) |
LONG VARCHAR | 可変文字列(DSC$K_DTYPE_VT) |
TINYINT [(n)]1 | 符号付きバイト整数(DSC$K_DTYPE_B) |
SMALLINT [(n)]1 | 符号付きワード整数(DSC$K_DTYPE_W) |
INTEGER [(n)]1 | 符号付きロングワード整数(DSC$K_DTYPE_L) |
QUADWORD [(n)]1、2 | 符号付きクワッドワード整数(DSC$K_DTYPE_Q) |
BIGINT [(n)]1、2 | 符号付きクワッドワード整数(DSC$K_DTYPE_Q) |
DECIMAL [(n[,n])]3 | パック10進数文字列(DSC$K_DTYPE_P) |
NUMERIC [(n[,n])]3 | 左区切り記号付き数値文字列(DSC$K_DTYPE_NL) |
FLOAT [(n)] | nの値に応じた、単精度浮動小数点数(F浮動小数点)または倍精度浮動小数点数(G浮動小数点)(DSC$K_DTYPE_FまたはDSC$K_DTYPE_G) |
REAL | 単精度浮動小数点数(DSC$K_DTYPE_F) |
DOUBLE PRECISION4 | 倍精度浮動小数点数(G浮動小数点)(DSC$K_DTYPE_G)3 |
DATE | DATE VMS(デフォルトのDATE)はDSC$K_DTYPE_ADT、DATE ANSIはOracle Rdb内部 |
TIME | Oracle Rdb内部 |
TIMESTAMP | Oracle Rdb内部 |
INTERVAL | Oracle Rdb内部 |
LIST OF BYTE VARYING | -- |
BYTE VARYING | -- 5 |
以降の項では、文字、DECIMALとNUMERIC、固定小数点数と浮動小数点数、日時、LIST OF BYTE VARYINGの各データ型、およびデータ型間の変換規則について説明します。
2.3.1 文字データ型
どのデータ型も、各文字の長さは1オクテット以上になります。この長さはキャラクタ・セットによって異なります。デフォルトでは、文字データ型の長さはオクテットです。文字の長さを指定するには、SET DIALECT文またはSET CHARACTER LENGTH文を使用します。
データ型をキャラクタ・セットで修飾しない場合は、その列のキャラクタ・セットとしてデータベースのデフォルト・キャラクタ・セットが指定されたものとみなされます。データベースのデフォルト・キャラクタ・セットを指定しない場合、その列はDEC_MCSキャラクタ・セットであるとみなされます。
テキスト値がリテラルであるか、パラメータに格納されているリテラルであるか、または表列に格納されているリテラルであるかどうかにかかわらず、テキスト値は演算式内で使用できません。
SQL> SELECT EMPLOYEE_ID + 1 FROM EMPLOYEES; %SQL-F-UNSSTRXPR, Unsupported string expression |
デフォルトでは、C言語の文字列はヌル文字で終了する文字列として処理されます。バイナリ入力を操作するCアプリケーションを作成する方法は、次のとおりです。
|
SQLのすべてのデータ型で、データベース行の領域を一定量使用します。使用される領域のほとんどは、事前にサイズが決定しています。たとえば、BIGINTデータ型の記憶域には8オクテットが必要です。ただし、CHARデータ型、VARCHARデータ型、およびこれらと同等のNATIONAL CHARACTERデータ型では、文字単位で記憶域サイズを指定できます。
Oracle Rdbでは、格納される行のサイズは65,272オクテットに制限されています。これにより、その表の列数および関連付けられるデータ型のサイズが制限されます。
また、表定義ごとに可変オーバーヘッドがあります。このオーバーヘッドのサイズは、NULLフラグを表す可変のオクテット数になります(列ごとに1つのフラグ)。表列の数が増加すると、NULLビット・ベクターも大きくなります(整数のオクテットとして格納されます)。表の8列ごとに単一のオクテットが使用され、NULLビット・ベクターが格納されます。
VARCHAR、NATIONAL CHARACTER VARYING(または同等の構文)の各列では、実際の長さの情報を保存するために2オクテットがさらに必要になります。 |
CHAR列またはVARCHAR列の最大長は、新しい列の格納に使用可能な空き領域の量に応じて制御されます。たとえば、単一のCHAR(65271)列を持つ表を作成できます。
SQL> CREATE TABLE T1 (A CHAR(65271)); |
ただし、追加でBIGINT列を定義すると、CHAR列の最大長は65,263オクテットに減少します(65,271 - 8オクテット)。
SQL> CREATE TABLE T1 (A CHAR(65271), B BIGINT); %RDB-E-NO_META_UPDATE, metadata update failed -RDMS-F-RECMAXEXC, relation T1 definition exceeds data limit SQL> CREATE TABLE T1 (A CHAR(65263), B BIGINT); |
最大の文字列長は、表のデータ型および列数によって異なります。
2.3.2 日時データ型
SQLでは、日付と時刻を表す4種類のデータ型が提供されています。これらを今後、日時データ型と呼びます。DATE、TIMEおよびTIMESTAMPの各データ型では、カレンダ日付および時計の時刻を参照します。INTERVALデータ型は、2つの日時の値で示す期間を参照する相対日時データ型です。
日時データ型には、次の種類があります。
DATEデータ型を修飾しない場合は、表に列を作成するときにDATE VMSとして解釈されます。INSERT文またはSELECT文を発行する場合は、DATEデータ型を修飾する必要があります。DATE VMSデータ型は、日時の演算には使用できません。
SET DEFAULT DATE FORMAT文、プログラムに埋め込まれているDECLARE MODULE文のプリコンパイラDEFAULT DATE FORMAT句、またはモジュール・ファイルのモジュール言語DEFAULT DATE FORMAT句を使用すると、DATEをDATE ANSIに変更できます。ドメインまたは表を作成する前に、SET DEFAULT DATE FORMAT文を使用する必要があります。データベース定義を作成した後は、この文はデータ型の変更に使用できません。
DATEデータ型の書式の詳細は、第2.4.3項を参照してください。
期間カテゴリ | 時間隔修飾子 |
---|---|
YEAR-MONTH | YEAR |
YEAR TO MONTH | |
MONTH | |
DAY-TIME | DAY |
DAY TO HOUR | |
DAY TO MINUTE | |
DAY TO SECOND | |
HOUR | |
HOUR TO MINUTE | |
HOUR TO SECOND | |
MINUTE | |
MINUTE TO SECOND | |
SECOND |
期間の書式を設定する際、Oracle Rdbでは先行フィールドの桁数を指定する必要があります。先行フィールド桁数の最小値は1桁、最大値は9桁です。期間先行フィールド精度は、第2.3節の構文図にprecとして示されています。期間先行フィールド精度を指定しない場合、2にデフォルト設定されます。
次の例では、HOURS_WORKED列が2つのTIMESTAMP列から計算されます。HOURおよびSECONDの各時間隔修飾子の先行フィールド精度は、HOURS(2)およびSECONDS(2)にデフォルト設定されます。
SQL> CREATE TABLE ACCOUNTING.DAILY_HOURS cont> (EMPLOYEE_ID CHAR(5), cont> START_TIME TIMESTAMP, cont> END_TIME TIMESTAMP, cont> HOURS_WORKED cont> COMPUTED BY (END_TIME - START_TIME) HOUR TO SECOND cont> ); SQL> -- SQL> -- Now show the columns in the table - note default precisions SQL> -- SQL> SHOW TABLE (COLUMNS) ACCOUNTING.DAILY_HOURS; Information for table DAILY_HOURS Columns for table DAILY_HOURS: Column Name Data Type Domain ----------- --------- ------ EMPLOYEE_ID CHAR(5) START_TIME TIMESTAMP(2) END_TIME TIMESTAMP(2) HOURS_WORKED INTERVAL HOUR (2) TO SECOND (2) Computed: BY (END_TIME - START_TIME) HOUR TO SECOND SQL> -- SQL> -- Output shows the two-digit precision in HOUR and SECOND qualifiers SQL> -- SQL> SELECT EMPLOYEE_ID, HOURS_WORKED FROM ACCOUNTING.DAILY_HOURS; EMPLOYEE_ID HOURS_WORKED 00415 09:44:36.85 00415 10:16:21.25 00415 10:30:17.57 . . . |
小数秒精度とは、第2.3節の構文図でfracとして示されている、SECONDフィールドの小数点以下の桁数のことです。この数字は秒の小数の桁数を表します。小数秒精度は、0〜2の間の値になります。小数秒精度を指定しない場合、SECONDフィールドの小数秒精度には2がデフォルト設定されます。
INTERVAL修飾子は、日付フィールドの重要度の高い方から低い方に指定する必要があります。日時フィールドの重要度の順序は、高い方から低い方にYEAR、MONTH、DAY、HOUR、MINUTE、SECONDです。表2-10および表2-11は、期間に含まれるフィールドを示しています。
キーワード | 意味 | 有効範囲 |
---|---|---|
YEAR | 年 | 符号付きの値 |
MONTH | 月 | 符号付きの値(YEAR TO MONTH期間の場合は--11 ... 11に制限される) |
この期間に対してMONTHのみを指定すると、月の値はY x 12 + Mとして計算されます。YおよびMは内部的に(Y,M)として格納された年および月を表します。
有効範囲 | |||
---|---|---|---|
キーワード | 意味 | 先行フィールドの場合 | それ以外 |
DAY | 日1 | --3649634 ... 3649634 | (同じ) |
HOUR | 時間2 | --87591216 ... 87591216 | 0 ... 23 |
MINUTE | 分3 | --999999999 ... 999999999 | 0 ... 59 |
SECOND | 秒4 | --21474836.47 ... 21474836.47 | 0 ... 59.99 |
日時フィールドのサブセットを指定すると、最も重要度の高いフィールドの値が合計され、指定された最も重要度の高い先行フィールドに適切な値が設定されます。
時間隔修飾子で指定されていない、重要度の低いフィールドは切り捨てられます。たとえば、期間が内部的に(D,H,M,S)として格納されているとします。時間隔修飾子でHOUR TO MINUTEを指定すると、HOURはD x 24 + Hに、MINUTEはMに設定され、SECONDフィールドは切り捨てられます。
演算式内で日時に関する変数と定数を使用できます。有効な演算子のリストは、表2-27を参照してください。日時計算の詳細は、『Oracle Rdb7 Introduction to SQL』を参照してください。
YESTERDAY、TODAYおよびTOMORROWの各文字列リテラルのコンパイル時変換の詳細は、第2.4.2項を参照してください。
例2-1は、これらの複数の日時データ型の使用方法を示しています。
例2-1 日時データ型の使用 |
---|
SQL> -- Create a simple table with a variety of data types. Note the use SQL> -- of date-time literals for the DEFAULT and CHECK clauses. SQL> -- SQL> CREATE TABLE DATE_TEST cont> (A DATE VMS, cont> B DATE ANSI, cont> C TIME(0) cont> DEFAULT TIME '06:00:00', cont> D TIMESTAMP(2), cont> E INTERVAL YEAR(4) cont> CHECK(E > INTERVAL '10' YEAR) cont> NOT DEFERRABLE, cont> F INTERVAL DAY(3) TO MINUTE, cont> G CHAR(16)); SQL> -- SQL> -- Literal dates are represented as TEXT literals. On OpenVMS , SQL> -- the date format is controlled by the LIB$DT_INPUT_FORMAT SQL> -- and SYS$LANGUAGE logical names. For more information about SQL> -- these logical names, see the OpenVMS documentation for the SQL> -- Run-Time Library. SQL> -- SQL> INSERT INTO DATE_TEST (A) VALUE ('2-APR-1957'); 1 row inserted SQL> SET LANGUAGE SPANISH SQL> INSERT INTO DATE_TEST (A) VALUE ('2-abr-1957'); 1 row inserted SQL> SET LANGUAGE ENGLISH SQL> SELECT A FROM DATE_TEST; A 2-APR-1957 00:00:00.00 2-APR-1957 00:00:00.00 2 rows selected SQL> -- SQL> -- The ANSI/ISO SQL standard specifies that only date-time literals SQL> -- can be assigned to date-time columns (for example, DATE, TIME, SQL> -- TIMESTAMP, and INTERVAL). These date-time literals are used SQL> -- in INSERT, SELECT, and UPDATE statements and in CREATE and ALTER SQL> -- statements. SQL> -- SQL> INSERT INTO DATE_TEST (B) VALUE (DATE '1993-2-23'); 1 row inserted SQL> INSERT INTO DATE_TEST (C) VALUE (TIME '12:20:00'); 1 row inserted SQL> INSERT INTO DATE_TEST (D) VALUE (TIMESTAMP '1993-2-23 12:20:00.00'); 1 row inserted SQL> INSERT INTO DATE_TEST (E) VALUE (INTERVAL '35' YEAR(4)); 1 row inserted SQL> INSERT INTO DATE_TEST (F) VALUE (INTERVAL '365:10:21' DAY(3) TO MINUTE); 1 row inserted SQL> -- SQL> -- DATE VMS columns can have associated edit strings defined SQL> -- for them. However, ANSI/ISO date-time values always print SQL> -- in ANSI/ISO format unless you cast them to DATE VMS. SQL> -- SQL> SELECT D, CAST(D AS DATE VMS) cont> FROM DATE_TEST cont> WHERE D IS NOT NULL; D 1993-02-23 12:20:00.00 23-FEB-1993 12:20:00.00 1 row selected SQL> -- SQL> -- Oracle Rdb also supports another internal format for SQL> -- DATE VMS. This format is similar to the TIMESTAMP format SQL> -- except that the punctuation is omitted. This example assigns SQL> -- the CHAR column (A) to the DATE VMS (G) column and then displays SQL> -- the result. In an application, the CHAR column could be a CHAR SQL> -- host variable or module language parameter. SQL> -- SQL> INSERT INTO DATE_TEST (G) VALUE ('1957020100000000'); 1 row inserted SQL> UPDATE DATE_TEST cont> SET A=G cont> WHERE G IS NOT NULL; 1 row updated SQL> SELECT A, G cont> FROM DATE_TEST cont> WHERE G IS NOT NULL; A G 1-FEB-1957 00:00:00.00 1957020100000000 1 row selected SQL> ROLLBACK; |