キャッシュなしでのOracle DatabaseからTimesTen表へのデータのロード

結果を含めるためのキャッシュ・グループおよびキャッシュ表を作成しないで、バックエンドOracle DatabaseからのSQL問合せの結果をTimesTenの単一表にロードできます。TimesTenでは、Oracle Databaseでユーザーが指定したSELECT文を実行し、その結果セットをTimesTenの表にロードするツールが提供されます。

次は、このタスクを実行するために行う主要なステップです。

  1. 適切な列とデータ型を備えた表をTimesTenに作成します。

  2. Oracle Databaseで実行されて目的の結果セットを生成するSELECT文を指定します。

  3. 結果セットをTimesTenの表にロードします。

TimesTenには、これらのタスクを実行するために2通りの方法があります。

  • ttIsqlユーティリティは、createandloadfromoraqueryコマンドを備えており、このコマンドではTimesTen表名およびSELECT文が指定されると自動的にTimesTen表を作成し、SELECT文をOracle Databaseで実行して、結果セットをTimesTen表にロードします。このコマンドの詳細は、「ttIsqlを使用した表の作成およびSQL問合せ結果のロード」を参照してください。

  • ttTableSchemaFromOraQueryGet組込みプロシージャは、ユーザー指定のSELECT文を評価して、TimesTenに表を作成するために実行できるCREATE TABLE文を生成します。これは、SELECT文からの結果セットを受け取るのに適しています。ttLoadFromOracle組込みプロシージャは、Oracle DatabaseでSELECT文を実行し、結果セットをTimesTen表にロードします。これらの組込みプロシージャの詳細は、「TimesTen組込みプロシージャを使用した表の推奨およびSQL問合せ結果のロード」を参照してください。

両方の方法では、次のことが必要です。

  • 関係するTimesTenデータベースとOracle Databaseの両方が同じ各国語データベース文字セットで構成されている必要があります。

  • TimesTenデータベースに接続する場合、接続は、次のようにキャッシュ・グループを使用するときに必要な同じ接続属性を含んでいる必要があります。

    • TimesTenデータベースとOracle Databaseの両方で同じである必要があるユーザー名

      ノート:

      SQL文がそのために実行されるように、データベースごとにユーザーに適切な権限が付与されている必要があります。

    • PWDおよびOraclePWD接続属性で適切な各ユーザーの適切なパスワード

    • Oracle Databaseインスタンスを識別するOracleNetServiceName接続属性

  • いずれの方法でも、ユーザーは次のものを指定します。

    • SQL問合せの結果がロードされるTimesTenデータベースの表名。表の所有者を指定しない場合、現行のユーザーが所有者として表が作成されます。表名は、SQL文が実行されるOracle Databaseの表名と同じである必要はありません。この表は主キーを必要としません。表がすでに存在している場合は、警告が発行され、取得された行が表に追加されます。

    • オプションで、ttIsql createandloadfromoraqueryまたはttLoadFromOraclenumThreadsパラメータを使用して、結果セットを含む表をロードするときに並行して使用するパラレル・スレッドの数を指定します。このデフォルトは4です。

    • 必要な行を取得するためにOracle Databaseに対して実行されるSQL SELECT文。このSELECT文内に指定する表は、表が現行のOracle Databaseユーザーのスキーマ内にある場合を除き、完全修飾する必要があります。問合せはパラメータ・バインディングを持つことができません。

      SELECTリストには、単一の列参照または列エイリアスを含める必要があります。たとえば、SELECTリスト内の式は、列エイリアスとともに指定する必要があります。結果表内で列の重複を避けるために、列エイリアスを使用することもできます。たとえば、SELECT C1+1 FROM T1を使用するかわりに、SELECT C1 + 1 C2 FROM T1を使用します。これは、C2という列を作成します。

TimesTenは、SELECT文を評価し、列名、データ型およびNULL値可能情報を使用して、結果セットをロードする表をTimesTenに作成します。列名およびデータ型(同じまたはマップ済)は、SELECT文に関係するOracle Databaseの表から取得されます。ただし、その他のOracle Database表定義情報(DEFAULT値、主キー、外部キー関係など)は、TimesTen表にCREATE TABLE文を作成する場合には使用されません。

ノート:

サポートされていないデータ型が評価によって返される場合、または構文エラーなどでOracle Databaseで問合せが実行できない場合、警告がログに記録され、出力中のサポートされていない行にコメントが表示されます。ただし、データ型がTimesTenでサポートされていない場合、SELECTリストでデータ型を、TimesTenでサポートされているデータ型にキャストできます。

ロード・プロセスでは、TimesTen表の列のデータ型とサイズが結果セットのデータ型とサイズに一致することを確認しません。かわりに、挿入が試行され、列のデータ型がマップできない場合、またはSQL問合せからのOracle DatabaseデータがTimesTenの列サイズを超える場合は、TimesTenによってエラーが返されます。

256行ごとにロードは自動的にコミットされます。ロード時にエラーが発生した場合、ロードは終了しますが、コミットされたトランザクションはロールバックされません。Oracle Databaseから返されるエラーは、キャッシュ・グループを使用する場合と同じ方法で報告されます。

createandloadfromoraqueryコマンドおよびttLoadFromOracle組込みプロシージャを使用して既存のTimesTen表にロードできるため、次の制限事項が適用されます。

  • システム表、ディクショナリ表、一時表、ビューのディテール表、マテリアライズド・ビュー表、表、またはキャッシュ・グループ内にすでにある表にはロードできません。また、表名にシノニムは使用できません。

  • 外部キー制約の参照表(子表)である既存の表に結果セットをロードする場合、その制約は検証されません。その結果、親行を失っている行がロードされることがあります。そのかわり、表がロードされた後ですべての外部キーを確認する必要があります。ただし、ttLoadFromOracle組込みプロシージャでは、オプション・パラメータをIgnoreDuplicates=Yに設定することにより、制約違反を無視できます。

次の項では、個々の方法の詳細について説明します。

ttIsqlを使用した表の作成およびSQL問合せ結果のロード

ttIsqlユーティリティは、createandloadfromoraqueryコマンドを提供します。これは、表名、パラレル・スレッドの数、および入力パラメータとしてOracle Databaseで実行できるSELECT文を取得します。

これらのパラメータで、TimesTenは次のことを実行します。

  1. SQL問合せを評価し、適切な表を作成します(まだ作成されていない場合)。そのとき、この表は提供された表名を持ち、列名はSQL問合せで指定された名前を使用し、結果データの取得元のOracle Database表と同じ(またはマップされた)データ型を持ちます。

  2. Oracle Databaseで実行されるSQL問合せの結果をこの表にロードします。コールは、ロードされる行数を示す単一の数を返します。このコマンドに対する後続のコールは、取得された行を表に追加します。

ノート:

『Oracle TimesTen In-Memory Databaseリファレンス』ttIsqlcreateandloadfromoraqueryコマンドを参照してください。

次のttIsqlの例では、DSN、ユーザー名、このユーザーのTimesTenでのパスワード、およびOracle Databaseでの同じユーザー名のパスワードを指定して接続します。次に、createandloadfromoraqueryコマンドを実行して、SELECT文を評価します。取得された行の列とデータ型と同じ列名とデータ型のemployees表がTimesTenに作成されます。この表には、2つのパラレル・スレッドによってOracle Databaseから返された結果セットが移入されます。

% ttisql -connstr "DSN=database1;UID=hr;PWD=hr;OraclePWD=oracle"
Copyright (c) 1996, 2024 Oracle.  All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql
connect -connstr "DSN=database1;UID=hr;PWD=********;OraclePWD=********";
Connection successful: DSN=database1;UID=hr;
DataStore=/timesten/install/sample_db/DemoDataStore/database1;
DatabaseCharacterSet=AL32UTF8;
ConnectionCharacterSet=AL32UTF8;DRIVER=/timesten/install/lib/libtten.so;
PermSize=128;TempSize=64;OracleNetServiceName=inst1;

(Default setting AutoCommit=1)
Command> createandloadfromoraquery employees 2 SELECT * FROM hr.employees;
Mapping query to this table:
    CREATE TABLE "HR"."EMPLOYEES" (
    "EMPLOYEE_ID" number(6,0) NOT NULL,
    "FIRST_NAME" varchar2(20 byte),
    "LAST_NAME" varchar2(25 byte) NOT NULL,
    "EMAIL" varchar2(25 byte) NOT NULL,
    "PHONE_NUMBER" varchar2(20 byte),
    "HIRE_DATE" date NOT NULL,
    "JOB_ID" varchar2(10 byte) NOT NULL,
    "SALARY" number(8,2),
    "COMMISSION_PCT" number(2,2),
    "MANAGER_ID" number(6,0),
    "DEPARTMENT_ID" number(4,0)
     )
Table employees created
< 107, 0, 0, Started=2015-09-11 21:12:45 (GMT); Ended=2015-09-11 21:12:46 (GMT);
Load successfully completed; OracleSCN=779534; Rows Loaded=107; Errors=0;
Statement=ttLoadFromOracle(HR, EMPLOYEES, SELECT * FROM hr.employees, 2) >
1 row found.

DESCRIBEコマンドを実行して、新しい表を発行します。

ノート:

この例では表の所有者が指定されていないため、デフォルトで現行のユーザーになります。この例では、現行のユーザーはhrです。

Command> DESCRIBE employees;
 
Table HR.EMPLOYEES:
  Columns:
    EMPLOYEE_ID                     NUMBER (6) NOT NULL
    FIRST_NAME                      VARCHAR2 (20) INLINE
    LAST_NAME                       VARCHAR2 (25) INLINE NOT NULL
    EMAIL                           VARCHAR2 (25) INLINE NOT NULL
    PHONE_NUMBER                    VARCHAR2 (20) INLINE
    HIRE_DATE                       DATE NOT NULL
    JOB_ID                          VARCHAR2 (10) INLINE NOT NULL
    SALARY                          NUMBER (8,2)
    COMMISSION_PCT                  NUMBER (2,2)
    MANAGER_ID                      NUMBER (6)
    DEPARTMENT_ID                   NUMBER (4)
 
1 table found.
(primary key columns are indicated with *)
 
Command> SELECT * FROM employees;
< 114, Den, Raphaely, DRAPHEAL, 515.127.4561, 2002-12-07 00:00:00, PU_MAN, 
11000, <NULL>, 100, 30 >
< 115, Alexander, Khoo, AKHOO, 515.127.4562, 2003-05-18 00:00:00, PU_CLERK, 
3100, <NULL>, 114, 30 >
…
< 205, Shelley, Higgins, SHIGGINS, 515.123.8080, 2002-06-07 00:00:00, 
AC_MGR, 12008, <NULL>, 101, 110 >
< 206, William, Gietz, WGIETZ, 515.123.8181, 2002-06-07 00:00:00, 
AC_ACCOUNT, 8300, <NULL>, 205, 110 >
107 rows found. 

次の例は、createandloadfromoraqueryコマンドを使用してTimesTenにemp表を作成し、この表に、Oracle Databaseのhr.employees表のデータ(employee_idが200未満)を、4つのスレッドによりパラレルに移入します。

Command> createandloadfromoraquery emp 4 SELECT * FROM hr.employees 
WHERE employee_id < 200;
Mapping query to this table:
    CREATE TABLE "HR"."EMP" (
    "EMPLOYEE_ID" number(6,0) NOT NULL,
    "FIRST_NAME" varchar2(20 byte),
    "LAST_NAME" varchar2(25 byte) NOT NULL,
    "EMAIL" varchar2(25 byte) NOT NULL,
    "PHONE_NUMBER" varchar2(20 byte),
    "HIRE_DATE" date NOT NULL,
    "JOB_ID" varchar2(10 byte) NOT NULL,
    "SALARY" number(8,2),
    "COMMISSION_PCT" number(2,2),
    "MANAGER_ID" number(6,0),
    "DEPARTMENT_ID" number(4,0)
     )
 
Table emp created< 100, 0, 0, Started=2015-09-11 21:30:56 (GMT); Ended=2015-09-11 21:30:57 (GMT);
Load successfully completed; OracleSCN=780073; Rows Loaded=100; Errors=0;
Statement=ttLoadFromOracle(HR, EMP, SELECT * FROM hr.employees 
WHERE employee_id < 200, 4) >1 row found.

そして、次のcreateandloadfromoraqueryは、idが200より大きいすべての従業員を取得し、結果セットはTimesTenの既存の表に追加されます。警告によって、表がすでに存在していて、6行がこの表に追加されたことが伝えられます。

Command> createandloadfromoraquery emp 4 SELECT * FROM hr.employees 
WHERE employee_id > 200;
Warning 2207: Table HR.EMP already exists
< 6, 0, 0, Started=2015-09-11 21:34:31 (GMT); Ended=2015-09-11 21:34:31 (GMT);
Load successfully completed; OracleSCN=780176; Rows Loaded=6; Errors=0; 
Statement=ttLoadFromOracle(HR, EMP, SELECT * FROM hr.employees 
WHERE employee_id > 200, 4) >
1 row found.

パラレル・ロード処理は実行時間が長くなる場合があるため、処理を取り消す必要がある場合があります。「パラレル・ロード処理の取消し」を参照してください。

TimesTen組込みプロシージャを使用した表の推奨とSQL問合せ結果のロード

組込みプロシージャを使用して、TimesTen表を作成しOracleデータベースからその表に結果セットをロードできます。

createandloadfromoraqueryコマンドが、TimesTen表を作成しOracle Databaseからの結果セットをこの表にロードするためのすべてのタスクを自動的に実行する一方で、次の2つの組込みプロシージャは同じ機能を次の2つのステップに分離します。

  1. ttTableSchemaFromOraQueryGet組込みプロシージャは、SQL問合せを評価し、発行を選択できるCREATE TABLE SQL文を生成します。この文を実行するには、Oracle Databaseで問合せを実行するために必要なすべての権限をユーザーが持つ必要があります。これにより、処理を行わずに表構造を表示することができます。ただし、推奨されたCREATE TABLE文を自分で発行する必要があります。

  2. ttLoadFromOracle組込みプロシージャは、バックエンドOracle DatabaseでSQL問合せを実行し、次に結果セットをTimesTen表にロードします。これは、結果をロードするTimesTen表名、必要な行を取得するためのOracle Database SQL SELECT文、および表に結果セットをロードする際に並行して使用するパラレル・スレッドの数を必要とします。オプションで、エラーしきい値オプションを指定して、一意性の違反などの問題およびIgnoreDuplicatesオプションでのデータ変換の問題を回避できます。

ノート:

『Oracle TimesTen In-Memory Databaseリファレンス』ttTableSchemaFromOraQueryGetおよびttLoadFromOracleを参照してください。

次の例は、DSN、ユーザー名、このユーザーのTimesTenでのパスワード、Oracle Databaseでの同じ名前のユーザーのパスワード、およびOracle DatabaseインスタンスのOracleNetServiceNameを指定して接続します。次に、ttTableSchemaFromOraQueryGet組込みプロシージャをコールして、SELECT文を評価し、employees表用に推奨されたCREATE TABLE文を返します。次に、CREATE TABLE文が実行されます。最後に、この例では、ttLoadFromOracle組込みプロシージャをコールして、Oracle Databaseからの結果セットをemployees表にロードします。ロードは、4つのスレッドによりパラレルに実行されます(デフォルト)。

ノート:

autocommitがoffに設定されている場合、表のロード後に、ユーザーは手動でコミットまたはロールバックを行う必要があります。

% ttisql -connstr "DSN=database1;uid=hr;pwd=hr;OraclePWD=oracle"
Copyright (c) 1996, 2024 Oracle.  All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql
connect -connstr "DSN=database1;UID=hr;PWD=********;OraclePWD=********";
Connection successful: DSN=database1;UID=hr;
DataStore=/timesten/install/sample_db/DemoDataStore/database1;
DatabaseCharacterSet=AL32UTF8;
ConnectionCharacterSet=AL32UTF8;DRIVER=/timesten/install/lib/libtten.so;
PermSize=128;TempSize=64;OracleNetServiceName=inst1;

Command> call ttTableSchemaFromOraQueryGet('hr','employees', 
'SELECT * FROM hr.employees');
< CREATE TABLE "HR"."EMPLOYEES" (
"EMPLOYEE_ID" number(6,0) NOT NULL,
"FIRST_NAME" varchar2(20 byte),
"LAST_NAME" varchar2(25 byte) NOT NULL,
"EMAIL" varchar2(25 byte) NOT NULL,
"PHONE_NUMBER" varchar2(20 byte),
"HIRE_DATE" date NOT NULL,
"JOB_ID" varchar2(10 byte) NOT NULL,
"SALARY" number(8,2),
"COMMISSION_PCT" number(2,2),
"MANAGER_ID" number(6,0),
"DEPARTMENT_ID" number(4,0)
 ) >
1 row found.

Command> CREATE TABLE "HR"."EMPLOYEES" (
"EMPLOYEE_ID" number(6,0) NOT NULL,
"FIRST_NAME" varchar2(20 byte),
"LAST_NAME" varchar2(25 byte) NOT NULL,
"EMAIL" varchar2(25 byte) NOT NULL,
"PHONE_NUMBER" varchar2(20 byte),
"HIRE_DATE" date NOT NULL,
"JOB_ID" varchar2(10 byte) NOT NULL,
"SALARY" number(8,2),
"COMMISSION_PCT" number(2,2),
"MANAGER_ID" number(6,0),
"DEPARTMENT_ID" number(4,0)
 );

Command> call ttLoadFromOracle ('HR','EMPLOYEES','SELECT * FROM HR.EMPLOYEES');
< 107, 0, 0, Started=2015-09-11 21:52:51 (GMT); Ended=2015-09-11 21:52:51 (GMT);
Load successfully completed; OracleSCN=780552; Rows Loaded=107; Errors=0;
Statement=ttLoadFromOracle(HR, EMPLOYEES, SELECT * FROM HR.EMPLOYEES, 4) >
1 row found.

Command> SELECT * FROM hr.employees;
< 100, Steven, King, SKING, 515.123.4567, 2003-06-17 00:00:00, AD_PRES, 24000,
<NULL>, <NULL>, 90 >
< 101, Neena, Kochhar, NKOCHHAR, 515.123.4568, 2005-09-21 00:00:00, AD_VP, 17000, 
<NULL>, 100, 90 >
...
< 205, Shelley, Higgins, SHIGGINS, 515.123.8080, 2002-06-07 00:00:00, AC_MGR, 
12008, <NULL>, 101, 110 >
< 206, William, Gietz, WGIETZ, 515.123.8181, 2002-06-07 00:00:00, AC_ACCOUNT, 
8300, <NULL>, 205, 110 >
107 rows found.

次の例では、Oracle Databaseに表を作成しますが、ここでemployee_idPRIMARY KEY制約のある列で、emailUNIQUE制約のある列です。

CREATE TABLE employees
(employee_id NUMBER(6) PRIMARY KEY, 
first_name VARCHAR2(20), 
last_name VARCHAR2(25) NOT NULL, 
email VARCHAR2(25) NOT NULL UNIQUE, 
phone_number VARCHAR2(20), 
hire_date DATE NOT NULL, 
job_id VARCHAR2(10) NOT NULL, 
salary NUMBER(8,2), 
commission_pct NUMBER(2,2), 
manager_id NUMBER(6), 
department_id NUMBER(4));

次に、次のttTableSchemaFromOraQueryGet組込みプロシージャがSQL問合せを評価し、CREATE TABLE SQL文を生成します。推奨されたCREATE TABLE SQL文では、PRIMARY KEY制約およびUNIQUE制約はOracle Databaseから継承されないことに注意してください。NULL値可能制約はOracle Databaseから継承されます。これはcreateandloadfromoraqueryコマンドにも適用されます。

Command> call ttTableSchemaFromOraQueryGet ('hr', 'employees', 
'SELECT * FROM hr.employees');
< CREATE TABLE "HR"."EMPLOYEES" ( 
"EMPLOYEE_ID" number(6,0) NOT NULL,
"FIRST_NAME" varchar2(20 byte),
"LAST_NAME" varchar2(25 byte) NOT NULL,
"EMAIL" varchar2(25 byte) NOT NULL,
"PHONE_NUMBER" varchar2(20 byte),
"HIRE_DATE" date NOT NULL,
"JOB_ID" varchar2(10 byte) NOT NULL,
"SALARY" number(8,2),
"COMMISSION_PCT" number(2,2),
"MANAGER_ID" number(6,0),
"DEPARTMENT_ID" number(4,0)
 ) >
1 row found.

パラレル・ロード処理は実行時間が長くなる場合があるため、処理を取り消す必要がある場合があります。「パラレル・ロード処理の取消し」を参照してください。

パラレル・ロード処理の取消し

SQLCancel(hstmt) ODBC関数(ODBC 2.5およびODBC 3.5に適用される)を使用して、またはttIsqlユーティリティで[Ctrl]キーを押したまま[C]キーを押すことによって、パラレル・ロード処理を実行しているすべてのスレッドを取り消して、完全に停止できます。

『Oracle TimesTen In-Memory Database C開発者ガイド』TimesTenのODBCのサポート、およびこのマニュアル内の「ODBC関数の取消し」を参照してください。

パラレル・ロード処理は定期的にコミットされるため、成功した処理はロールバックされません。cancelコマンドを発行すると、次の時点でTimesTenは処理を取り消します。

  • 挿入スレッドが生成される前。

  • 挿入バッチのコミット後(256行ごと)。

  • メイン・スレッドがOracle Databaseからのフェッチを完了した後。

取り消したパラレル・ロード処理を再試行するには、重複行を避けるためにTimesTenデータベースから前回挿入した行を削除します。