SQL データ型は、COBOL で使用されるデータ型とは異なります。
SQL にはデータ型の標準セットがありますが、 それらの正確な実装はデータベースによって異なるため、 多くのデータベースでは、完全には実装されていません。
COBOL プログラムでは、ホスト変数は COBOL プログラムの変数として、 あるいは SQL データベースの変数として機能するため、プリプロセッサが COBOL データ型を適切な SQL データ型に変換したり、 マップしなければなりません。これは、プリプロセッサが正しい SQL データ型にマップするように、 COBOL の picture 句で正しくホスト変数を宣言しなければならないことを意味します。 それを行うには、接続するデータソースが使用する SQL データ型について知ることが必要です。
次の節では、さまざまな SQL データ型と、直接それらにマップするホスト変数の宣言方法について説明します。
COBSQL で Sybase、Informix、または Oracle を使用する場合は、 データベースエンジンは変換プログラムを実行して、COBOL データ型のデータをデータベースのデータ型に変更することができます。 一般的な方法として、数値または整数データ型のホスト変数は、次のように定義します。
PIC S9(..)..COMP..
一方、文字またはテキストデータ型は次のように定義します。
PIC X(...)
.
Oracle と Sybase はどちらも、データベースのデータ型を所定のホスト変数に定義することができます。 これは、より複雑なデータ型が使用される場合に有用です。
Oracle では、次のように記述します。
EXEC SQL BEGIN DECLARE SECTION END-EXEC. * * データ項目を Oracle のデータ型 DISPLAY として定義します。 * 01 emp-comm pic s9(6)v99 DISPLAY SIGN LEADING SEPARATE * EXEC SQL VAR emp-comm IS DISPLAY(8,2) END-EXEC. EXEC SQL END DECLARE SECTION END-EXEC.
Sybase では、次のように記述します。
EXEC SQL BEGIN DECLARE SECTION END-EXEC. * * 項目を Sybase 特定データ型として定義します。 * 01 money-item CS-MONEY. * EXEC SQL END DECLARE SECTION END-EXEC.
ホスト変数のデータベースタイプの定義については、 データベースベンダが提供する COBOL プリコンパイラのマニュアルを参照してください。
Informix では、さまざまなデータ型を操作するために呼び出せる システムルーチンが数多く提供されています。これらのルーチンについては、 『Programming with INFORMIX-ESQL/COBOL』 マニュアルを参照してください。
tiny integer (TINYINT) は、 1 バイト整数の SQL データ型であり、 COBOL では次のように宣言されます。
PIC S9(4) COMP-5.
DB2
tiny integer データ型は、DB2 ではサポートしていません。
COBSQL
Sybase では、tiny integer ホスト変数の使用をサポートしています。
Sybase 用の定義は、次のようになります。
03 tinyint1 PIC S9(2) COMP-5. 03 tinyint2 PIC S9(2) COMP. 03 tinyint3 PIC S9(2) BINARY.
これらは Sybase データ型の TINYINT にマップします。
small integer (SMALLINT) は、2 バイト整数の SQL データ型であり、 COBOL では BINARY、COMP、COMP-X、COMP-5 または COMP-4 を使用して宣言されます。
たとえば、以下の定義はすべて、ホスト変数を直接 SMALLINT データ型にマップします。
03 shortint1 PIC S9(4) COMP. 03 shortint2 PIC S9(4) BINARY. 03 shortint3 PIC X(2) COMP-5. 03 shortint4 PIC S9(4) COMP-4. 03 shortint5 PIC 9(4) USAGE DISPLAY. 03 shortint6 PIC S9(4) USAGE DISPLAY.
OpenESQL
COBSQL - Oracle
Oracle では、ホスト変数を shortint1
または shortint2
として定義するか、次のように記述するのが最良の方法です。
03 shortint7 PIC S9(4) COMP-5.
これらは Oracle データ型 NUMBER(38) にマップします。
COBSQL - Sybase
Sybase では、shortint3
以外はすべて受け入れられます。
次のように記述することもできます。
03 shortint7 PIC S9(4) COMP-5.
これらは Sybase データ型 SMALLINT にマップします。
COBSQL - Informix
Informix では、ホスト変数を shortint1
または shortint2
として定義するか、次のように記述するのがもっともよい方法です。
03 shortint7 PIC S9(4) COMP-5.
これらは Informix データ型 SMALLINT にマップします。
integer (INT) は、4 バイト整数の SQL データ型であり、COBOL では BINARY、 COMP、COMP-X、COMP-5 または COMP-4 を使用して宣言されます。
ホスト変数を直接 INT データ型にマップするには、 以下の定義がすべて有効です。
03 longint1 PIC S9(9) COMP. 03 longint2 PIC S9(9) COMP-5. 03 longint3 PIC X(4) COMP-5. 03 longint4 PIC X(4) COMP-X. 03 longint5 PIC 9(9) USAGE DISPLAY. 03 longint6 PIC S9(9) USAGE DISPLAY.
OpenESQL
COBSQL - Oracle
Oracle では、integer ホスト変数を longint1
または longint2
として定義するか、次のように記述するのが最良の方法です。
03 longint7 PIC S9(9) COMP-5.
これらは Oracle データ型 NUMBER(38) にマップします。
COBSQL - Sybase
Sybase では、longint3
以外はすべて受け入れられます。
次のように記述することもできます。
03 longint7 PIC S9(9) COMP-5.
これらは Sybase データ型 INT にマップします。
COBSQL - Informix
Informix では、integer ホスト変数を longint1
またはlongint2
として定義するか、次のように記述するのがもっともよい方法です。
03 longint7 PIC S9(9) COMP-5.
これらは Informix データ型 INT にマップします。
big integer (BIGINT) は、8 バイト整数の SQL データ型であり、 COBOL では次のように宣言されます。
PIC S9(18) COMP-3.
OpenESQL
OpenESQL は、ホスト変数として使われる COBOL データ項目に S9(18)
という最大サイズをサポートして、SQL データ型 BIGINT からマップされた値を保持します。
ところが、BIGINT データ型は、PIC S9(18)
データ項目で保持できる最大値よりも大きい値を保持できるため、
コードでデータの切り捨てが確実にチェックされるようにする必要があります。
DB2
big integer データ型は、
DB2 UDB V6.1 以降でサポートされています。
COBSQL
Oracle、Informix、および Sybase は、big integer をサポートしていません。
固定長文字列 (CHAR) は、最大長がドライバで定義される SQL デ ータタイプです。COBOL では PIC X(n) と宣言され、n には 1 か ら最大長までの整数が入ります。
たとえば、次のように記述します。
03 char-field1 pic x(5). 03 char-field2 pic x(254).
COBSQL
これは Oracle データ型の CHAR(n)、Sybase データ型の CHAR
(n)、Informix データ型の CHAR(n) にマップします。
Oracle と Sybase の場合に、サポートされる固定長文字列の最大長は
255 バイトです。Informix の場合に、サポートされる固定長文字列の最大長は
32KB です。
DB2
これは DB2 データ型の CHAR にマップします。 サポートされる長さの最大は 254バイトです。これ以上の長さを必要とする場合は
VARCHAR フィールドを使用します。
OpenESQL を使用している場合は、長さフィールドを COMP-5 として定義する必要があります。
可変長文字列 (VARCHAR) は、SQL データ型であり、 COBOL では次の 2 つのどちらかとして宣言されます。
たとえば、次のように記述します。
03 varchar1. 49 varchar1-len pic 9(4) comp-5. 49 varchar1-data pic x(200). 03 Longvarchar1. 49 Longvarchar1-len pic 9(4) comp. 49 Longvarchar1-data pic x(30000).
SQL文中でこの項目を参照するときには、集団項目の名称で参照します。
SQL CHAR、VARCHAR、または LONG VARCHAR データ型にコピーされたデータが、 定義された長さより長い場合は、そのデータが切り捨てられ、 SQLCA データ構造体の SQLWARN1 フラグが設定されます。データが定義された長さより短い場合は、 受け取った CHAR データ型が空白で埋められます。
Oracle では、ホスト変数は Oracle キーワード VARYING を使用して定義されます。 以下は、それを使用した例です。
EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 USERNAME PIC X(20) VARYING. EXEC SQL END DECLARE SECTION END-EXEC.
Oracle は、USERNAME データ項目を次のグループ項目に 拡張します。
01 USERNAME 02 USERNAME-LEN PIC S9(4) COMP-5. 02 USERNAME-ARR PIC X(20).
COBOL コードでは、USERNAME-LEN
または USERNAME-ARR
のどちらか一方に参照が行われますが、SQL 文 では、USERNAME
グループ名を使用しなければなりません。たとえば、次のようになります。
move "SCOTT" to USERNAME-ARR. move 5 to USERNAME-LEN. exec sql connect :USERNAME identified by :pwd using :db-alias end-exec.
これは Oracle データ型、VARCHAR(n) または VARCHAR2(n) にマップします。 非常に長い文字項目については、Oracle は LONG データ型を提供しています。
Sybase では、プリコンパイラが SQL データ型 VARCHAR を操作するグループ項目の使用をサポートしていないため、 ホスト変数は PIC X(n) picture 句で定義する必要があります。
これらは VARCHAR(n) という Sybase のデータ型にマップします。
Informix では、プリコンパイラが SQL データ型 VARCHAR を操作するグループ項目の使用をサポートしていないため、 ホスト変数は PIC X(n) picture 句 で定義する必要があります。
これらは VARCHAR(n) という Informix データ型にマップします。VARCHAR フィールドの最大長は、 使用する Informix のバージョンによって決まります。VARCHAR データ項目については、『Informix Guide to SQL』マニュアルを参照してください
32 ビット SQL 浮動小数点データ型である REAL は、COBOL では COMP-1 を使用して宣言されます。
64 ビット SQL 浮動小数点データ型である FLOAT および DOUBLE は、 COBOL では COMP-2 を使用して宣言されます。
たとえば、次のように記述します。
01 float1 usage comp-2.
OpenESQL
32 ビットおよび 64 ビットの浮動小数点データ型は、
OpenESQL が埋め込み SQL で単精度浮動小数点をサポートしてしていないため、
COMP-2 の COBOL データ項目にマップされます。
DB2
COBSQL - Oracle
Oracle は COMP-1 および COMP-2 の両方のデータ項目の使用をサポートしています。
どちらも Oracle データ型の NUMBER にマップします。
COBSQL - Sybase
Sybase は COMP-1 および COMP-2 データ項目の使用をサポートしています。
COMP-1 データ項目は Sybase データ型である REAL にマップします。
COMP-2 データ項目は Sybase データ型の FLOAT にマップします。
COBSQL - Informix
Informix は COMP-1 または COMP-2 データ項目のどちらもサポートしていません。
Informix がサポートしているのは、COBOL の固定数値データ項目、つまり PIC S9(m)V9(n)
だけです。
Informix は FLOAT および SMALLFLOAT SQL カラムをこのフォーマットに変換します。
正確な数値データ型である DECIMAL および NUMERIC は、 ドライバで指定された精度とスケールまで値を保持することができます。
これらは COBOL では、COMP-3、PACKED-DECIMAL または NUMERIC USAGE DISPLAY として宣言されます。
たとえば、次のように記述します。
03 packed1 pic s9(8)v9(10) usage comp-3. 03 packed2 pic s9(8)v9(10) usage display.
COBSQL - Oracle
Oracle では、これらは NUMBER(p,s) データ型にマップします。
Sybase では、NUMBER(p,s) または DECIMAL(p,s) のどちらかにマップします。
Informix では、DECIMAL(p,s) または MONEY(p,s) のどちらかにマップします。
COBOL には日付/時間データ型がないため、SQLの 日付/時間カラムは 文字の表現に変換されます。
COBOL の出力ホスト変数が、SQL タイムスタンプ値に対して PIC X(n) として定義され、n が 19 以上の場合に、日付と時間は yyyy-mm-dd hh:mm:ss.ff... のフォーマットで指定されますが、 少数点以下の桁数はドライバ定義となります。
たとえば、次のようになります。
1994-05-24 12:34:00.000
OpenESQL は任意のリレーショナルデータベースにアクセスすることが可能であり、 各データベースには日付と時間を指定するさまざまな方法があるため、 入力ホスト変数の日付と時間を指定するという標準的な方法が提供されています。 この方法を使用すると、プログラムをコンパイルする際に、SQL の命令に DETECTDATE オプションを使用しなければなりません。
たとえば、次のように記述します。
$set sql(dbman=odbc, detectdate)
01 Hire-Date pic x(26).
move "{d'1965-11-02'} to Hire-Date exec sql insert into emp (HireDate) values (:Hire-Date) end-exec
DB2 では、TIMESTAMP データ型の最大長は 26 文字です。
Oracle データ項目には独自のデータ定義がありますが、Oracle は date、time および datetime フィールドが COBOL プログラムで使用される場合に、 それらを変換する関数を提供しています。その関数は、次のとおりです。
Oracle の日付フォーマットを文字列に変換します。
文字列を Oracle の日付に変換します。
どちらの関数も変換される項目を引数にとり、その後にデータ項目に適用される date、 time または datetime のマスクが続きます。 この例は、次のようになります。
exec sql select ename, TO_CHAR(hiredate, 'DD-MM-YYYY') from emp into :ename, :hiredate where empno = :empno end-exec. exec sql insert into emp (ename, TO_DATE(hiredate, 'DD-MM-YYYY')) values (:ename, :hiredate) end-exec.
これは Oracel データ型の DATE にマップします。 DATE データ型については、『SQL Language Reference Manual』を 参照してください。Oracle の SQL 文の関数の使いかたについては、 このマニュアルで調べることができます。
Sybase は convert と呼ばれるデータ型のフォーマットを変換する関数を提供しています。 上記の Oracle の例を使用すると、SQL 構文は次のようになります。
exec sql select ename, convert(varchar(12) hiredate, 105) from emp into :ename, :hiredate where empno = :empno end-exec. exec sql insert into emp (ename, hiredate) values (:ename, convert(datetime :hiredate, 105) end-exec.
これは SMALLDATETIME または DATETIME のどちらかの Sybase データ型にマップします。SMALLDATETIME と DATETIME データ型の違いについては、 『Transact-SQL User's Guide』の「Using and Creating Datatypes」 の章を参照してください。
Sybase の convert 関数については、Sybase の『SQL Server Reference Manual: Volume 1 Commands, Functions and Topics』を参照してください。
Informix では、日付はユリウスまたは mm/dd/yyyy フォーマットのどちらかを要求します。
PIC S9(9) COMP
として定義します。
PIC X(10)
として定義します。
Informix に日付を渡す方法については、『INFORMIX-ESQL/COBOL Programmer's Manual』のマニュアルを参照してください。
SQL BINARY、VARBINARY および IMAGE データは、COBOL では PIC X (n) フィールドとして表現されます。データ変換は実行されません。 データがデータベースからフェッチされると、COBOL フィールドがデータ量より小さい場合は、 データが切り捨てられ、SQLCA データ構造体の SQLWARN1 フィールドが "W" に設定されます。COBOL フィールドがデータ量より大きい場合は、フィールドが null (x"00") バイトで埋められます。データを BINARY、VARBINARY または LONG VARBINARY カラムに挿入するには、動的 SQL 文を使用する必要があります。
DB2 では、CHAR FOR BIT DATA を使用して BINARY を表現し、VARCHAR(n) FOR BIT DATA を使用して VARBINARY を表現し、LONG VARCHAR FOR BIT DATA を使用して LONG VARBINARY を表現します。IBM の ODBC ドライバを使用する場合は、 BINARY、VARBINARY、LONG VARBINARY が IBM の対応するデータ型の代わりに返されます。 IMAGE データ型は、BLOB で表現されます。 DB2 は LOB (Character Large Object、Binary Large Object、Graphical Large Object) を使用して、きわめて大きいカラム (最大 2 ギガバイト) を定義します。 これらのデータ型とともに静的 SQL を使用することができます。
Oracle はバイナリデータをサポートします。バイナリデータと文字データの違いは、 Oracle は文字データにはコードセット変換を行いますが、 バイナリデータはそのままにするという点です。
2 つの Oracle データ型は、RAW と LONG RAW です。 RAW と LONG RAW の使用には制約があります。 詳しくは Oracle のマニュアルに記載されています。
Sybase は 3 つのバイナリデータ型 BINARY、VARBINARY、IMAGE を提供しています。 IMAGE は複雑なデータ型であり、そのために、ホスト変数は CS-IMAGE として 定義されます。たとえば、次のように記述します。
EXEC SQL BEGIN DECLARE SECTION END-EXEC. * * 項目を Sybase 特定データ型として定義します。 * 01 image-item CS-IMAGE. * EXEC SQL END DECLARE SECTION END-EXEC.
注: Sybase データ型の使いかたについては、 『Sybase Transact-SQL User's Guide』の『Using and Creating Datatypes 』の章を参照してください。
Informix は 2 種類のバイナリデータ項目 TEXT と BYTE をサポートしています。 これらのデータ型には実データは格納しません。実際、これらはファイル名です。 したがって、これらに対応する COBOL の項目は、PIC X(n) となります。
TEXT および BYTE データ型については、『Informix Guide to SQL』 を参照してください。
OpenESQL を使用していない場合や、ほかの ESQL プリプロセッサとの互換性を保持する必要がある場合には、この節を飛ばして先へ進んでも構いません。そうでない場合は、可能な限りこの節に記述されている SQL データ型を使用するようお薦めします。
通常の COBOL ホスト変数の使用により日付/時間やバイナリのデータを含む SQL データの操作がより複雑になる可能性があることが経験から明らかになっており、さらに可変長文字列データを処理する従来の技術にも問題は内在しています。そのため、SQL TYPE 機能を介して SQL テーブルに格納されるデータタイプをより正確に反映するよう、ホスト変数をより簡潔に宣言できるように OpenESQL を拡張しました。これにより、動的 SQL 構文ではなく静的 SQL 構文を使用してより多くのアプリケーションを構築できるようになります。
SQL TYPE 機能に使用するホスト変数として、次に示すデータタイプが使用できます。
以下のすべての例において、"TYPE" および "IS" は付けても付けなくても構いません。
01 hv-name SQL TYPE IS BINARY(n) 生成結果は次のようになります。 01 hv-name pic x(n).
01 hv-name SQL TYPE IS CHAR-VARYING(n) 生成結果は次のようになります。 01 hv-name pic x(n).
CHAR-VARYING データは SQL_VARCHAR として OpenESQL に渡されます。データソースにデータを送信する時、値がすべて空白である場合の最初の空白を除き、値のあとに続く空白文字の長さが調整され、データスペースから取り出した値には空白が付加されます。
01 hv-name SQL TYPE IS DATE 生成結果は次のようになります。 01 hv-name pic x(10).
DATE のデータは YYYY-MM-DD というフォーマットで指定します。
01 hv-name SQL TYPE IS DATE-RECORD 生成結果は次のようになります。 01 hv-name. 03 hv-name-year pic s9(4) comp-5. 03 hv-name-month pic 9(4) comp-5. 03 hv-name-day pic 9(4) comp-5.
01 hv-name SQL TYPE IS TIMESTAMP 生成結果は次のようになります。 01 hv-name pic x(29).
TIMESTAMP のデータは YYYY-MM-DD HH:MM:SS というフォーマットで指定します。
01 hv-name SQL TYPE IS TIMESTAMP-RECORD 生成結果は次のようになります。 01 hv-name. 03 hv-name-year pic s9(4) comp-5. 03 hv-name-month pic 9(4) comp-5. 03 hv-name-day pic 9(4) comp-5. 03 hv-name-hour pic 9(4) comp-5. 03 hv-name-min pic 9(4) comp-5. 03 hv-name-sec pic 9(4) comp-5. 03 hv-name-frac pic 9(9) comp-5.
SQL [TYPE] [IS] BINARY(n)
01 hv-name SQL TYPE IS BINARY(n)
生成結果は次のようになります:
01 hv-name pic x(n).
SQL [TYPE] [IS] CHAR-VARYING(n)
01 hv-name SQL TYPE IS CHAR-VARYING(n)
生成結果は次のようになります:
01 hv-name pic x(n).
SQL [TYPE] [IS] DATE
01 hv-name SQL TYPE IS DATE
生成結果は次のようになります:
01 hv-name pic x(10).
SQL [TYPE] [IS] DATE-RECORD
01 hv-name SQL TYPE IS DATE-RECORD
生成結果は次のようになります:
01 hv-name. 03 hv-name-year pic s9(4) comp-5. 03 hv-name-month pic 9(4) comp-5. 03 hv-name-day pic 9(4) comp-5.
OpenESQL supports the TIMESTAMP and TIMESTAMP-RECORD SQL TYPEs to make working with TIMESTAMP column data easier. Each of these types requires that data be organized in fixed date/time formats. Use TIMESTAMP to generate a single working-storage record to contain all timestamp information. Use TIMESTAMP-RECORD to generate a group-level record for the timestamp containing individual records for each element of the timestamp as follows:
SQL [TYPE] [IS] TIMESTAMP
SQL [TYPE] [IS] TIMESTAMP-RECORD
Note: If the OpenESQL format does not match the value of Oracle's NLS_TIMESTAMP_FORMAT parameter, Oracle generates an error message. Use Oracle's SQLPLUS utility to determine the value of NLS_TIMESTAMP_FORMAT. Then do one of the following:
exec sql insert into mf_datetime (col_a ,col_date ,col_timestamp ) values (:mf-col-a ,TO_DATE(:mf-col-date, 'YYYY-MM-DD') ,TO_TIMESTAMP(:mf-col-timestamp, 'YYYY-MM-DD HH24:MI.SS.FF') ) end-exec
See your Oracle documentation for information on the SQLPLUS utility and the NLS_TIMESTAMP_FORMAT parameter.
01 hv-name SQL TYPE IS TIMESTAMP
生成結果は次のようになります:
01 hv-name pic x(29).
01 hv-name SQL TYPE IS TIMESTAMP-RECORD
生成結果は次のようになります:
01 hv-name. 03 hv-name-year pic s9(4) comp-5. 03 hv-name-month pic 9(4) comp-5. 03 hv-name-day pic 9(4) comp-5. 03 hv-name-hour pic 9(4) comp-5. 03 hv-name-min pic 9(4) comp-5. 03 hv-name-sec pic 9(4) comp-5. 03 hv-name-frac pic 9(9) comp-5.
This host variable definition:
01 mf. 03 mf-col-a pic s9(09) comp-5. 03 mf-col-date sql type date. 03 mf-col-timestamp sql type timestamp. 03 mf-col-tsrec sql type timestamp-record. 01 ws-char-ts pic x(29).
Requires this field initialization:
move 1 to mf-col-a move "2005-03-31" to mf-col-date move "2005-04-15 13:45:56.456123" to mf-col-timestamp move 2005 to mf-col-tsrec-year move 04 to mf-col-tsrec-month move 16 to mf-col-tsrec-day move 16 to mf-col-tsrec-hour move 55 to mf-col-tsrec-min move 58 to mf-col-tsrec-sec move 678000000 to mf-col-tsrec-frac
And this INSERT statement:
exec sql insert into mf_datetime (col_a ,col_date ,col_timestamp ) values (:mf-col-a ,:mf-col-date ,:mf-col-timestamp ) end-exec
Copyright © 2006 Micro Focus International Limited. All rights reserved.