この章では、PL/SQL、TimesTen SQLおよびアプリケーション・プログラムでのデータの操作に使用可能なデータ型の範囲について説明します。
TimesTenでは、PL/SQLデータ型と、PL/SQL、TimesTenおよびクライアント・アプリケーション・プログラムの各データ型間の相互作用がサポートされています。また、データ型の変換およびデータ型のマッピングがサポートされています。
TimesTen固有の考慮事項の詳細は、章の最後を参照してください。
この章の内容は次のとおりです。
データ型について説明する場合、次のような3つの異なる環境を考慮する必要があります。
PL/SQLデータ型を使用する変数および定数を含むPL/SQLプログラム
データベースの行、列および定数を使用するTimesTen SQL文
これらの要素は、TimesTen SQLデータ型を使用して表されます。
データベースおよびPL/SQLプログラミング言語と相互作用するアプリケーション・プログラム
アプリケーション・プログラムは、CやJavaなどのプログラミング言語で作成され、これらのプログラミング言語のデータ型を使用する変数および定数を含みます。
表3-1に、環境の概要および各環境のデータ型の例を示します。
ここでは、PL/SQLプログラムでサポートされているPL/SQLデータ型について説明します。TimesTen SQL文でサポートされているデータ型の説明ではありません。TimesTen SQL文でサポートされているデータ型の詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス・ガイド』のデータ型に関する説明を参照してください。
この項では、次のトピックについて説明します。
詳細は、『Oracle Database PL/SQL言語リファレンス』のPL/SQLデータ型に関する説明を参照してください。
PL/SQLブロックには、各定数、変数、およびパラメータにはデータ型があります。PL/SQLには事前定義されたデータ型およびサブタイプが用意されており、ユーザー自身でPL/SQLサブタイプを定義することもできます。
表3-2に、事前定義されたPL/SQLデータ型のカテゴリを示します。
表3-2 事前定義されたPL/SQLデータ型のカテゴリ
データ型のカテゴリ | 説明 |
---|---|
スカラー |
内部コンポーネントを持たない単一値 |
複合 |
スカラーまたは複合のいずれかである内部コンポーネント |
参照 |
REF CURSORなどの他のデータ項目へのポインタ。 |
スカラー・データ型には、内部コンポーネントを持たない単一値が格納されます。表3-3に、事前定義されたPL/SQLの重要なスカラー・データ型をデータ型ファミリごとに分類して示します。
表3-3 事前定義されたPL/SQLのスカラー・データ型
データ型ファミリ | データ型名 |
---|---|
|
|
|
|
|
|
|
注意: SQL文で |
|
|
|
|
|
|
|
|
例3-1 PL/SQL変数の宣言
Command> DECLARE > v_emp_job VARCHAR2 (9); > v_count_loop BINARY_INTEGER := 0; > v_dept_total_sal NUMBER (9,2) := 0; > v_orderdate DATE := SYSDATE + 7; > v_valid BOOLEAN NOT NULL := TRUE; > ...
PLS_INTEGER
データ型およびBINARY_INTEGER
データ型は同一のものであり、このマニュアルでは同じ意味で使用されています。
PLS_INTEGER
データ型は、32ビットで表される-2,147,483,648から2,147,483,647の範囲の符号付き整数を格納します。このデータ型には、NUMBER
データ型およびそのサブタイプと比較して次のようなメリットがあります。
PLS_INTEGER
値の方が、必要な記憶域が少なくなります。
PLS_INTEGER
演算はハードウェア算術計算を使用するため、ライブラリ算術計算を使用するNUMBER
演算より処理速度が速くなります。
適用範囲に含まれるすべての計算にPLS_INTEGER
値を使用した方が効率的です。PLS_INTEGER
の範囲外の計算には、NUMBER
データ型の事前定義されたサブタイプであるINTEGER
を使用してください。
詳細は、『Oracle Database PL/SQL言語リファレンス』のPLS_INTEGERデータ型およびBINARY_INTEGERデータ型に関する説明を参照してください。
注意: 2つのPLS_INTEGER データ型による計算がPLS_INTEGER の範囲をオーバーフローすると、結果がNUMBER データ型に割り当てられている場合でも、オーバーフロー例外が発生します。 |
SIMPLE_INTEGER
は、PLS_INTEGER
データ型の事前定義されたサブタイプであり、PLS_INTEGER
と同じ範囲(-2,147,483,648から2,147,483,647)とNOT NULL
制約を持ちます。PLS_INTEGER
と異なるのは、オーバーフローが発生しないという点です。
SIMPLE_INTEGER
は、値がnullになることがなく、オーバーフロー・チェックが不要な場合に使用できます。NULL値およびオーバーフローをチェックするオーバーヘッドがないため、SIMPLE_INTEGER
はPLS_INTEGER
よりも高いパフォーマンスを実現します。
詳細は、『Oracle Database PL/SQL言語リファレンス』のPLS_INTEGERのSIMPLE_INTEGERサブタイプに関する説明を参照してください。
表の各行は、ROWIDと呼ばれる一意の識別子を持っています。
アプリケーションでは、SQL文のWHERE
句などで、一重引用符で囲んだCHAR
定数としてリテラルのROWID値を指定できます。
また、ROWIDおよびROWID
データ型の使用方法や存続期間の詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』のROWIDデータ型およびROWIDに関する説明も参照してください。
LOB(ラージ・オブジェクト)型ファミリには、CLOB
(キャラクタLOB)、NCLOB
(各国語キャラクタLOB)、およびBLOB
(バイナリLOB)が含まれています。
LOBは、LOBロケータおよびLOB値で構成されています。ロケータは、値へのハンドルとして機能します。たとえば、アプリケーションがLOBを選択する場合、またはパラメータとしてLOBを渡す場合、それは実際の値ではなくロケータを使用しています。
LOBは、永続的または一時的のいずれかに設定できます。永続LOBは、データベース内の特にLOB列の行に存在します。一時LOBはプログラム内で内部的に使用されますが、その後、そのLOBをデータベース内のLOB列に挿入して永続LOBにすることもできます。
TimesTenでのLOBの追加情報は、『Oracle TimesTen In-Memory Database SQLリファレンス』のLOBのデータ型に関する説明を参照してください。
また、使用方法については、「ラージ・オブジェクト(LOB)」も参照してください。
複合型には、配列、レコードまたは表の要素などの、個別に操作できる内部コンポーネントがあります。
Oracle TimesTen In-Memory Databaseでは、次の複合データ型がサポートされています。
連想配列(索引付き表)
ネストした表
VARRAY
レコード
連想配列、ネストした表およびVARRAYは、コレクションとも呼ばれます。
次の項で、複合データ型の使用について説明します。
詳細は、『Oracle Database PL/SQL言語リファレンス』のPL/SQLコレクションおよびレコードに関する説明を参照してください。
コレクション・データ型は、他の言語で使用される配列、セットおよびハッシュ表と同じように宣言できます。コレクションとは、要素(すべて同じ型)の順序付きグループのことです。各要素には、コレクション内での位置を決定する一意の添字があります。
PL/SQLでは、配列型はVARRAY(可変サイズ配列)と呼ばれ、セット型はネストした表と呼ばれ、ハッシュ表型は連想配列または索引付き表と呼ばれます。これらはすべてコレクション型です。
例3-2 PL/SQLのコレクション型の使用
この例では、コレクション型staff_list
をemployee_id
の表として宣言し、このコレクション型をループおよびSELECT
文のWHERE
句で使用します。
Command> DECLARE > TYPE staff_list IS TABLE OF employees.employee_id%TYPE; > staff staff_list; > lname employees.last_name%TYPE; > fname employees.first_name%TYPE; > BEGIN > staff := staff_list(100, 114, 115, 120, 122); > FOR i IN staff.FIRST..staff.LAST LOOP > SELECT last_name, first_name INTO lname, fname FROM employees > WHERE employees.employee_id = staff(i); > DBMS_OUTPUT.PUT_LINE (TO_CHAR(staff(i)) || > ': ' || lname || ', ' || fname ); > END LOOP; > END; > / 100: King, Steven 114: Raphaely, Den 115: Khoo, Alexander 120: Weiss, Matthew 122: Kaufling, Payam PL/SQL procedure successfully completed.
PL/SQLサブプログラム間ではどのコレクションもパラメータとして渡すことができますが、TimesTenでは、PL/SQLと他の言語で記述されたアプリケーションの間で渡すことができるのは連想配列だけです。(以降の「アプリケーションからの連想配列の使用」を参照してください。)
バルクSQLを使用すると、コレクションによってTimesTen表からデータを出し入れできます。
レコードは、異なるデータ型を持つフィールドで構成された複合データ構造です。レコードは、単一のパラメータでサブプログラムに渡すことができます。例2-2に示すとおり、フィールドの名前および型を指定せずにしなくても、%ROWTYPE
属性を使用して、表内の行を表すレコード、または問合せの結果セットの行を表すレコードを宣言することもできます。
TimesTen PL/SQLでは、以前は索引付き表またはPL/SQL表と呼ばれていた連想配列が、OCI、Pro*C/C++、またはJDBCアプリケーションなどからのIN
、OUT
またはIN OUT
バインド・パラメータとしてサポートされます。これにより、データの配列をアプリケーションとデータベースの間で効率的に渡すことができます。
連想配列は、キー/値ペアのセットです。TimesTenでは、連想配列バインドの場合(PL/SQL内のみで連想配列を使用する場合を除く)、キー(索引)は整数(BINARY_INTEGER
またはPLS_INTEGER
)である必要があります。値は、同じデータ型の単純なスカラー値である必要があります。たとえば、部門番号で索引付けされた部門マネージャの配列を使用できます。索引は、作成された順序ではなく、ソートされた順序で格納されます。
連想配列型を宣言した後、次の例のようにPL/SQLの連想配列を宣言できます(INDEX BY
に注目)。
declare TYPE VARCHARARRTYP IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER; x VARCHARARRTYP; ...
以降の例3-4および「連想配列の使用」の例を参照してください。
『Oracle TimesTen In-Memory Database C開発者ガイド』のTimesTen OCIにおけるの連想配列バインドおよびTimesTen Pro*C/C++における連想配列バインドに関する説明、および『Oracle TimesTen In-Memory Database Java開発者ガイド』の連想配列のバインドに関する説明も参照してください。
連想配列に関する一般的な情報については、『Oracle Database PL/SQL言語リファレンス』の連想配列に関する説明を参照してください。
注意: TimesTenでは、次の制限に注意してください。
|
次の例では、連想配列の簡単な操作を行い、ttIsql
から効率的に連想配列をバインドし、配列を出力します。
例3-4 ttIsqlからの連想配列の使用
Command> var lngvc[1000] varchar2(30); Command> declare > TYPE VARCHARARRTYP IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER; > x VARCHARARRTYP; > begin > x := :lngvc; > x ( 1 ) := 'One'; > x ( 10 ) := 'Ten'; > :lngvc := x; > end; > / PL/SQL procedure successfully completed. Command> print lngvc; LNGVC : ARRAY [ 1000 ] (Current Size 10) LNGVC[1] : One LNGVC[2] : <NULL> LNGVC[3] : <NULL> LNGVC[4] : <NULL> LNGVC[5] : <NULL> LNGVC[6] : <NULL> LNGVC[7] : <NULL> LNGVC[8] : <NULL> LNGVC[9] : <NULL> LNGVC[10] : Ten
REF CURSORは、PL/SQLとアプリケーション間でパラメータとして渡すことのできる、SQL結果セットに対するカーソルへのハンドルです。TimesTenでは、PL/SQLからアプリケーションへのOUT
REF CURSORをサポートしています。アプリケーションは、PL/SQL内でREF CURSORをオープンし、適用可能なAPIでそれを渡し、結果セットをフェッチします。
TimesTenでは、ダイレクト接続またはクライアント/サーバー接続のいずれかのために、ODBC、JDBC、ODP.NET、OCI、Pro*C/C++およびTTClassesでREF CURSORがサポートされています。REF CURSORについては、次のTimesTenドキュメントでも説明しています。
『Oracle TimesTen In-Memory Database C開発者ガイド』のREF CURSORの使用に関する説明
『Oracle TimesTen In-Memory Database Java開発者ガイド』のREF CURSORの使用に関する説明
『Oracle TimesTen In-Memory Database TTClassesガイド』のREF CURSORの使用に関する説明
注意: TimesTenでは、文1つにつき1つのOUT REF CURSORがサポートされています。 |
Oracle Databaseで行うときと同じ方法で、TimesTenでもPL/SQLでREF CURSORを定義できます。(『Oracle Database PL/SQL言語リファレンス』のカーソル変数に関する説明を参照。)REF CURSORは通常はメタタイプとして使用され、ご使用のデータに合せて強力な(固有の) REF CURSOR型を定義し、その型のカーソル変数を宣言します。次に例を示します。
Command> DECLARE > TYPE DeptCurTyp IS REF CURSOR RETURN departments%ROWTYPE; > dept_cv DeptCurTyp; -- declare cursor variable > ...
例3-5 出力パラメータとしてのREF CURSORの使用
この例では、FOO_PACK
パッケージのGET_EMP
プロシージャを作成して、employees
表から従業員情報を取得します。プロシージャではREF CURSOR型のcursor_out
を宣言し、その型を出力パラメータとして使用します。
まず、パッケージ定義、REF CURSOR型およびプロシージャ定義を指定します。
create or replace package foo_pack is type cursor_out is ref cursor; procedure get_emp (results out cursor_out); end foo_pack;
その後、パッケージ本体とプロシージャ実装を指定します。
create or replace package body foo_pack as procedure get_emp (results out cursor_out) is begin open results for select employee_id, last_name from employees where employee_id < 110 order by last_name; end get_emp; end foo_pack;
出力用にREF CURSOR変数を宣言し、プロシージャを実行して、結果を表示します。PL/SQLの外部で宣言できるのは弱い(汎用的な) REF CURSORのみであることに注意してください。
Command> var proc_result refcursor; Command> exec foo_pack.get_emp(:proc_result); PL/SQL procedure successfully completed. Command> print proc_result; PROC_RESULT : < 105, Austin > < 102, De Haan > < 104, Ernst > < 109, Faviet > < 108, Greenberg > < 103, Hunold > < 100, King > < 101, Kochhar > < 107, Lorentz > < 106, Pataballa > 10 rows found.
または、弱い型指定のREF CURSOR変数はFOO_PACK
で宣言できます。
create or replace package foo_pack is procedure get_emp (results out sys_refcursor); end foo_pack; create or replace package body foo_pack as procedure get_emp (results out sys_refcursor) is begin open results for select employee_id, last_name from employees where employee_id < 110 order by last_name; end get_emp; end foo_pack;
ここでは、次のデータ型の変換について説明します。
「TimesTenにおける相違点: データ型に関する考慮事項」のデータ型の変換に関する情報も参照してください。
TimesTenでは、PL/SQLのデータ型間での暗黙的および明示的な変換がサポートされています。
型がVARCHAR2
の変数v_sal_hike
の例について検討します。給与の合計を計算する場合、PL/SQLでは最初にv_sal_hike
がNUMBER
に変換されてから、操作が実行されます。結果の型はNUMBER
になります。正しい結果を取得するために、PL/SQLでは暗黙的変換が使用されます。
Command> DECLARE > v_salary NUMBER (6) := 6000; > v_sal_hike VARCHAR2(5) := '1000'; > v_total_salary v_salary%TYPE; > BEGIN > v_total_salary := v_salary + v_sal_hike; > DBMS_OUTPUT.PUT_LINE (v_total_salary); > end; > / 7000 PL/SQL procedure successfully completed.
TimesTenでは、アプリケーション・プログラムのデータ型とPL/SQLのデータ型の変換、およびアプリケーション・プログラムのデータ型とTimesTen SQLのデータ型の変換がサポートされています。SQLでは、SQLがPL/SQLプログラムによって起動されたか、アプリケーションによって直接起動されたかに関係なく、同じ変換が行われます。
表3-4に、ODBC APIを使用するアプリケーションからPL/SQLプログラムのデータ型への典型的なデータ型マッピングを示します。ODBCからPL/SQLへの型マッピングの詳細は、『Oracle TimesTen In-Memory Database C開発者ガイド』のパラメータの型の割当ておよび型の変換の決定に関する説明を参照してください。
表3-4 ODBC SQLからPL/SQLへの型マッピングの例
ODBC型 | PL/SQL型 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
例3-6 ODBCからPL/SQLへのデータ型の変換
CプログラムでODBC APIを使用しており、VARCHAR2
型のC変数をNUMBER
型のPL/SQL変数にバインドする場合を検討します。TimesTenでは、暗黙的な変換が行われます。
Command> VARIABLE c_var VARCHAR2 (30) := '961'; Command> DECLARE v_var NUMBER; > BEGIN > v_var := :c_var; > DBMS_OUTPUT.PUT_LINE (v_var); > END; > / 961 PL/SQL procedure successfully completed.
例3-7 ODBCからTimesTen SQLへのデータ型の変換
この例では、型TT_BIGINT
の列を持つ表を作成し、PL/SQLを使用してTimesTen SQL INSERT
文を起動します。型SQL_VARCHAR
のバインド変数がINSERT
文で使用されます。アプリケーションでINSERT
文を直接起動する場合と同様の変換が行われます。
Command> CREATE TABLE conversion_test2 (Col1 TT_BIGINT); Command> VARIABLE v_var VARCHAR2 (100) := '1000'; Command> BEGIN > INSERT INTO conversion_test2 VALUES (:v_var); > END; > / PL/SQL procedure successfully completed. Command> SELECT * FROM conversion_test2; < 1000 > 1 row found.
ここでは、データ型のサポートおよび型変換に関する、次のようなTimesTenに固有の考慮事項について説明します。
TimesTenでは、PL/SQLのデータ型とTimesTen SQLのデータ型との間の変換がサポートされています。
表3-5に、サポートされているデータ型の変換を示します(上の1行がPL/SQLの型を表し、左の1列がSQLの型を表します)。データ型はデータ型ファミリごとに分類されており、列がPL/SQLの型ファミリを表し、行がTimesTenの型ファミリを表します。Yは該当の2つのファミリ間で変換が可能であることを示します。サポートされている変換は双方向です。
表3-5 PL/SQLのデータ型とTimesTen SQLのデータ型との間でサポートされている変換
型ファミリ | NUMERIC | CHARACTER | BINARY | DATETIME | INTERVAL | ROWID |
---|---|---|---|---|---|---|
|
Y |
Y |
||||
|
Y |
Y |
Y |
Y |
Y |
Y |
|
Y |
Y |
||||
|
Y |
|||||
|
Y |
Y |
||||
|
Y |
Y |
Y |
次の表3-6に、TimesTenのデータ型の概要、およびPL/SQLの型マッピングに関する推奨事項を示します。
表3-6 データ型の使用方法およびサイズ
TimesTenデータ型 | 説明 |
---|---|
|
0から255までの範囲の符号なし整数が対象です。 型PL/SQL |
|
-32,768から32,767の範囲の16ビットの符号付き整数が対象です。 型PL/SQL |
|
-2,147,483,648から2,147,483,647の範囲の符号付き整数が対象です。 これは、 |
|
-9,223,372,036,854,775,808から9,223,372,036,854,775,807の範囲の8バイトの符号付き整数が対象です。 PL/SQL |
|
浮動小数点の精度が必要な場合に使用します。 |
キャラクタ・タイプ |
すべてのPL/SQLキャラクタ・タイプに、32,767バイトまでのデータを格納できます。
|
日時、時間隔および時間の型 |
これらの型をキャラクタ・タイプ間で変換するときに使用されるデフォルトの書式とは異なる書式が必要な場合は、組込みファンクション |
バイナリ型 |
|
例3-8 TimesTen SQLのデータ型とPL/SQLのデータ型との間の変換
2つの列を持つ表がある場合を検討します。Col1
のデータ型はTT_INTEGER
であり、Col2
のデータ型はNUMBER
です。PL/SQLプログラムで、型PLS_INTEGER
のv_var1
および型VARCHAR2
のv_var2
という2つの変数を宣言します。SELECT
によって表のデータ行を2つのPL/SQL変数に格納します。
SELECT
文を実行すると、データ型の変換が行われます。Col1
は、TimesTenのSQL TT_INTEGER
型からPLS_INTEGER
型に変換されます。Col2
は、TimesTenのSQL NUMBER
型からPL/SQL VARCHAR2
型に変換されます。問合せが正しく実行されます。
Command> CREATE TABLE test_conversion (Col1 TT_INTEGER, Col2 NUMBER); Command> INSERT INTO test_conversion VALUES (100, 20); 1 row inserted. Command> DECLARE > v_var1 PLS_INTEGER; > v_var2 VARCHAR2 (100); > BEGIN > SELECT Col1, Col2 INTO v_var1, v_var2 FROM test_conversion; > DBMS_OUTPUT.PUT_LINE (v_var1); > DBMS_OUTPUT.PUT_LINE (v_var2); > END; > / 100 20 PL/SQL procedure successfully completed.
TimesTenでは、ユーザー指定のNLS_DATE_FORMAT
設定およびNLS_TIMESTAMP_FORMAT
設定はサポートされていません。
NLS_DATE_FORMAT
は常にyyyy-mm-dd
です。
NLS_TIMESTAMP_FORMAT
は常にyyyy-mm-dd hh:mi:ss.ff6
(秒を示す小数点以下桁数が6桁まで)です。
SQLおよびPL/SQL TO_DATE
およびTO_CHAR
ファンクションを使用して、必要な他の形式を指定することができます。これらのファンクションの詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス・ガイド』の式に関する説明を参照してください。
次のデータ型は、サポートされていません。
PL/SQLデータ型カテゴリ: TimesTenのPL/SQLでは、インターネット・データ型(XMLType
、URIType
、HttpURIType
)またはAnyデータ型(AnyType
、AnyData
、AnyDataSet
)はサポートされていません。
PL/SQLスカラー・データ型: TimesTenでは、PL/SQLデータ型TIMESTAMP WITH [LOCAL] TIME ZONE
およびUROWID
はサポートされていません。
TimesTenのPL/SQLでは、TimesTen型TT_DECIMAL
はサポートされていません。
TimesTen型モードでは、下位互換性をサポートしているため、TimesTenは文字列の値""を、Null値ではなく空、つまり長さゼロの文字列とみなします。ただし、PL/SQLでは、長さゼロの文字列は、常にnullとみなされます。値が空の文字列であるパラメータが、PL/SQLで実行されるSQL文に渡された場合、SQL文は、パラメータがPL/SQLによってNULL
に変換された後で、TimesTenに渡されます。
このモードの詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』のTimesTen型モード(下位互換性)に関する説明を参照してください。