Oracle Databaseユーティリティ 11g リリース1(11.1) E05768-02 |
|
この章の内容は、次のとおりです。
制御ファイルの列オブジェクトは、その属性によって記述されています。列オブジェクトの基になるオブジェクト型がNOT FINALであると宣言されると、制御ファイルの列オブジェクトは、基になるオブジェクト型から導出されたサブタイプの(導出および宣言された)属性によって記述されます。データ・ファイルでは、列オブジェクトの各属性に対応するデータは、単純なリレーショナル列に対応するデータ・フィールドと同様の形式でデータ・ファイルに記述されています。
次に、列オブジェクトのロードに関する例を示します。
例10-1に、事前にサイズが決まっているフィールドにデータがある例を示します。終了文字は、物理レコードの終わりを示します。オペレーティング・システムのファイル処理句(os_file_proc_clause
)のカスタム・レコード・セパレータを使用して、物理レコードの終わりを示すこともできます。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE departments (dept_no POSITION(01:03) CHAR, dept_name POSITION(05:15) CHAR, 1 dept_mgr COLUMN OBJECT (name POSITION(17:33) CHAR, age POSITION(35:37) INTEGER EXTERNAL, emp_id POSITION(40:46) INTEGER EXTERNAL) )
データ・ファイル(sample.dat)
101 Mathematics Johny Quest 30 1024 237 Physics Albert Einstein 65 0000
例10-2に、デリミタ・フィールドにデータがある例を示します。
制御ファイルの内容
LOAD DATA 1 INFILE 'sample.dat' "var 6" INTO TABLE departments FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' 2 (dept_no dept_name, dept_mgr COLUMN OBJECT (name CHAR(30), age INTEGER EXTERNAL(5), emp_id INTEGER EXTERNAL(5)) )
データ・ファイル(sample.dat)
3 000034101,Mathematics,Johny Q.,30,1024, 000039237,Physics,"Albert Einstein",65,0000,
"var"
文字列には、各レコードの先頭にある長さフィールドのバイト数(この例では6)が含まれます。値が指定されない場合、デフォルトは5バイトです。可変レコードの最大サイズは、2の32乗-1で、それ以上の値を指定するとエラーになります。
CHAR
型になります。
emp_id
フィールドの後の終了記号のために無視される改行文字も含まれます。
例10-3に、ネストした列オブジェクト(他の列オブジェクト内にネストした1つの列オブジェクト)の制御ファイルの記述方法を示します。
制御ファイルの内容
LOAD DATA INFILE `sample.dat' INTO TABLE departments_v2 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (dept_no CHAR(5), dept_name CHAR(30), dept_mgr COLUMN OBJECT (name CHAR(30), age INTEGER EXTERNAL(3), emp_id INTEGER EXTERNAL(7), 1 em_contact COLUMN OBJECT (name CHAR(30), phone_num CHAR(20))))
データ・ファイル(sample.dat)
101,Mathematics,Johny Q.,30,1024,"Barbie",650-251-0010, 237,Physics,"Albert Einstein",65,0000,Wife Einstein,654-3210,
例10-4に、NOT FINALのベース・オブジェクト型を拡張して新しく導出されたサブタイプを作成する例を示します。表定義の列オブジェクトは、ベース・オブジェクト型であると宣言されますが、サブタイプがベース・オブジェクト型から導出される場合は、SQL*Loaderによってサブタイプを列オブジェクトにロードできます。
オブジェクト型定義
CREATE TYPE person_type AS OBJECT (name VARCHAR(30), ssn NUMBER(9)) not final; CREATE TYPE employee_type UNDER person_type (empid NUMBER(5)); CREATE TABLE personnel (deptno NUMBER(3), deptname VARCHAR(30), person person_type);
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE personnel FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (deptno INTEGER EXTERNAL(3), deptname CHAR, 1 person COLUMN OBJECT TREAT AS employee_type (name CHAR, ssn INTEGER EXTERNAL(9), 2 empid INTEGER EXTERNAL(5)))
データ・ファイル(sample.dat)
101,Mathematics,Johny Q.,301189453,10249, 237,Physics,"Albert Einstein",128606590,10030,
TREAT
AS
句で指定すると、SQL*Loaderでは、実際の宣言型がperson_type
である列オブジェクトperson
が、導出型employee_type
であると宣言されたかのように処理されます。
empid
属性はemployee_type
の属性であるため、ここで使用できます。TREAT
AS
句が指定されていない場合、この属性は、列の宣言型の属性ではないためエラーを返します。
非スカラー・データ型でNULL値を指定する場合、スカラー・データ型で指定するよりも複雑です。オブジェクトは、その属性のサブセットをNULLにするか、すべての属性をNULL(NULLオブジェクトにかぎります)にするか、またはオブジェクト自身をNULL(アトミックNULLオブジェクト)にできます。
オブジェクト列に対応するフィールドでは、NULLIF
句を使用して、特殊属性をNULL
に初期化するフィールド条件を指定できます。例10-5に、この方法を示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE departments (dept_no POSITION(01:03) CHAR, dept_name POSITION(05:15) CHAR NULLIF dept_name=BLANKS, dept_mgr COLUMN OBJECT 1 ( name POSITION(17:33) CHAR NULLIF dept_mgr.name=BLANKS, 1 age POSITION(35:37) INTEGER EXTERNAL NULLIF dept_mgr.age=BLANKS, 1 emp_id POSITION(40:46) INTEGER EXTERNAL NULLIF dept_mgr.empid=BLANKS))
データ・ファイル(sample.dat)
2 101 Johny Quest 1024 237 Physics Albert Einstein 65 0000
列オブジェクトがNULL値(アトミックNULL)を取る条件を制御ファイルで指定するには、NULLIF
句で使用するオブジェクトの名前は、マップ・フィールドの論理的な組合せに基づいている必要があります(たとえば、例10-5では、指定されたマップ・フィールドは、dept_no
、dept_name
、name
、age
およびemp_id
です。dept_mgr
は、データ・ファイルのどのフィールドにも対応していない(マップされていない)ため、指定されたマップ・フィールドではありません)。
前述の方法は使用可能ですが、オブジェクトがNULL値を取るための条件が、マップ・フィールドに依存していない場合は、理想的な方法ではありません。このような場合は、FILLERフィールドを使用できます。
FILLERフィールドをデータ・ファイルのフィールドにマップし(列オブジェクトがアトミックNULLかどうかを示す)、そのFILLERフィールドを列オブジェクトのNULLIF
句のフィールド条件で使用できます。この例を例10-6に示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE departments_v2 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (dept_no CHAR(5), dept_name CHAR(30), 1 is_null FILLER CHAR, 2 dept_mgr COLUMN OBJECT NULLIF is_null=BLANKS (name CHAR(30) NULLIF dept_mgr.name=BLANKS, age INTEGER EXTERNAL(3) NULLIF dept_mgr.age=BLANKS, emp_id INTEGER EXTERNAL(7) NULLIF dept_mgr.emp_id=BLANKS, em_contact COLUMN OBJECT NULLIF is_null2=BLANKS (name CHAR(30) NULLIF dept_mgr.em_contact.name=BLANKS, phone_num CHAR(20) NULLIF dept_mgr.em_contact.phone_num=BLANKS)), 1 is_null2 FILLER CHAR)
データ・ファイル(sample.dat)
101,Mathematics,n,Johny Q.,,1024,"Barbie",608-251-0010,, 237,Physics,,"Albert Einstein",65,0000,,650-654-3210,n,
CHAR
型(デリミタ付きフィールドであるため、CHAR
のデフォルトはCHAR(255)
)のフィールドです。NULLIF
句は、FILLERフィールド自体には使用できません。
is_null
フィールドが空白の場合は、NULL(アトミックNULL)の値を取得します。Oracle Databaseでは、すべてのオブジェクト型に対してデフォルトのコンストラクタが自動的に提供されます。このコンストラクタを使用するには、コンストラクタに対するコールで、その型のすべての属性を引数として指定する必要があります。オブジェクトの新しいインスタンスが作成されると、その属性は引数リスト内の対応する値を取ります。このコンストラクタは、属性値コンストラクタと呼ばれます。SQL*Loaderでは、列オブジェクトのロード時に、デフォルトで属性値コンストラクタが使用されます。
1つ以上のユーザー定義コンストラクタを作成することによって、属性値コンストラクタを上書きできます。ユーザー定義コンストラクタを作成する場合、オブジェクトの新しいインスタンスが作成されると、常に、ユーザー定義論理を実行する型本体を指定する必要があります。ユーザー定義コンストラクタの引数リストは、属性値コンストラクタと同じ場合もありますが、型本体で実装される論理は異なります。
ユーザー定義コンストラクタのファンクションの引数リストが属性値コンストラクタの引数リストと一致する場合、従来型パスとダイレクト・パスではSQL*Loaderの動作が異なります。従来型パス・モードでは、ユーザー定義コンストラクタがコールされます。ダイレクト・パス・モードでは、属性値コンストラクタがコールされます。この相違点を例10-7に示します。
オブジェクト型定義
CREATE TYPE person_type AS OBJECT (name VARCHAR(30), ssn NUMBER(9)) not final; CREATE TYPE employee_type UNDER person_type (empid NUMBER(5), -- User-defined constructor that looks like an attribute-value constructor CONSTRUCTOR FUNCTION employee_type (name VARCHAR2, ssn NUMBER, empid NUMBER) RETURN SELF AS RESULT); CREATE TYPE BODY employee_type AS CONSTRUCTOR FUNCTION employee_type (name VARCHAR2, ssn NUMBER, empid NUMBER) RETURN SELF AS RESULT AS --User-defined constructor makes sure that the name attribute is uppercase. BEGIN SELF.name := UPPER(name); SELF.ssn := ssn; SELF.empid := empid; RETURN; END; CREATE TABLE personnel (deptno NUMBER(3), deptname VARCHAR(30), employee employee_type);
制御ファイルの内容
LOAD DATA INFILE * REPLACE INTO TABLE personnel FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (deptno INTEGER EXTERNAL(3), deptname CHAR, employee COLUMN OBJECT (name CHAR, ssn INTEGER EXTERNAL(9), empid INTEGER EXTERNAL(5))) BEGINDATA 1 101,Mathematics,Johny Q.,301189453,10249, 237,Physics,"Albert Einstein",128606590,10030,
Johny
Q.
およびAlbert
Einstein
は、両方とも大文字でロードされます。これは、従来型パス・モードではユーザー定義コンストラクタがコールされるためです。これに対し、この制御ファイルがダイレクト・パス・モードで実行された場合、名前フィールドは入力データに表示されているとおりにロードされます。これは、ダイレクト・パス・モードでは属性値コンストラクタがコールされるためです。
引数リストが属性値コンストラクタと一致しないユーザー定義コンストラクタの作成もできます。この場合は、従来型パス・モードおよびダイレクト・パス・モードの両方で、属性値コンストラクタがコールされます。例10-8に示す定義について考えてみます。
オブジェクト型定義
CREATE SEQUENCE employee_ids START WITH 1000 INCREMENT BY 1; CREATE TYPE person_type AS OBJECT (name VARCHAR(30), ssn NUMBER(9)) not final; CREATE TYPE employee_type UNDER person_type (empid NUMBER(5), -- User-defined constructor that does not look like an attribute-value -- constructor CONSTRUCTOR FUNCTION employee_type (name VARCHAR2, ssn NUMBER) RETURN SELF AS RESULT); CREATE TYPE BODY employee_type AS CONSTRUCTOR FUNCTION employee_type (name VARCHAR2, ssn NUMBER) RETURN SELF AS RESULT AS -- This user-defined constructor makes sure that the name attribute is in -- lowercase and assigns the employee identifier based on a sequence. nextid NUMBER; stmt VARCHAR2(64); BEGIN stmt := 'SELECT employee_ids.nextval FROM DUAL'; EXECUTE IMMEDIATE stmt INTO nextid; SELF.name := LOWER(name); SELF.ssn := ssn; SELF.empid := nextid; RETURN; END; CREATE TABLE personnel (deptno NUMBER(3), deptname VARCHAR(30), employee employee_type);
例10-7で説明した制御ファイルがこれらの定義に従って使用された場合、名前フィールドは、入力データに表示されているとおりに(大文字と小文字の組合せで)ロードされます。これは、従来型パス・モードおよびダイレクト・パス・モードの両方で属性値コンストラクタがコールされるためです。
SQL式でユーザー定義コンストラクタを明示的に参照することによって、従来型パス・モードを使用してこの表をロードすることもできます。例10-9に、この方法を示します。
制御ファイルの内容
LOAD DATA INFILE * REPLACE INTO TABLE personnel FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (deptno INTEGER EXTERNAL(3), deptname CHAR, name BOUNDFILLER CHAR, ssn BOUNDFILLER INTEGER EXTERNAL(9), 1 employee EXPRESSION "employee_type(:NAME, :SSN)") BEGINDATA 1 101,Mathematics,Johny Q.,301189453, 237,Physics,"Albert Einstein",128606590,
Johny
Q.
およびAlbert
Einstein
は、両方とも小文字でロードされます。また、各行の従業員列オブジェクトの従業員識別子は、employee_ids
順序番号から値を取ります。
例10-9に示した制御ファイルがダイレクト・パス・モードで使用された場合は、次のエラーが通知されます。
SQL*Loader-951: Error calling once/load initialization ORA-26052: Unsupported type 121 for SQL expression on column EMPLOYEE.
オブジェクト表のロードに必要な制御ファイルの構文は、典型的なリレーショナル表のロードの場合とほぼ同じです。例10-10に、主キーOIDを使用したオブジェクト表のロード例を示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' DISCARDFILE 'sample.dsc' BADFILE 'sample.bad' REPLACE INTO TABLE employees FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (name CHAR(30) NULLIF name=BLANKS, age INTEGER EXTERNAL(3) NULLIF age=BLANKS, emp_id INTEGER EXTERNAL(5))
データ・ファイル(sample.dat)
Johny Quest, 18, 007, Speed Racer, 16, 000,
前述の制御ファイルを見ただけでは、ロードされる表がシステム生成OIDを持つオブジェクト表か、主キーOIDを持つオブジェクト表か、またはリレーショナル表かを判断できません。
すでにシステム生成OIDを含むデータをロードし、新しいOIDを生成するのではなく、データ・ファイル内の既存のOIDを使用するように指定する必要がある場合もあります。そのような場合は、INTO
TABLE
句に続けてOID
句を使用します。
OID (fieldname)
この場合、fieldname
には、システム生成実OIDを含むデータ・ファイルにマップされた、フィールド指定リストのフィールド名(通常はFILLERフィールド)を指定します。SQL*Loaderでは、その指定されたOIDが、正しい形式で、グローバルな独自性を保持したOIDであるとみなされます。そのため、OracleのOIDジェネレータを使用してOIDを生成し、ロードされたOIDの一意性を確保する必要があります。
また、そのOID
句は、主キーOIDではなく、システム生成のOIDでのみ使用できます。
例10-11に、行オブジェクトを使用したシステム生成OIDのロード例を示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE employees_v2 1 OID (s_oid) FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (name CHAR(30) NULLIF name=BLANKS, age INTEGER EXTERNAL(3) NULLIF age=BLANKS, emp_id INTEGER EXTERNAL(5), 2 s_oid FILLER CHAR(32))
データ・ファイル(sample.dat)
3 Johny Quest, 18, 007, 21E978406D3E41FCE03400400B403BC3, Speed Racer, 16, 000, 21E978406D4441FCE03400400B403BC3,
OID
句には、s_oid
のロード・フィールドがOIDを含むように指定します。カッコが必要です。
s_oid
に有効な16進数が含まれていない場合、そのレコードは拒否されます。
RAW
に変換されてオブジェクト表に格納されます。
オブジェクト表の列オブジェクトがNOT FINALに基づいている場合、SQL*Loaderによって導出サブタイプをオブジェクト表にロードできます。前述のとおり、オブジェクト表に導出サブタイプをロードする場合に必要な構文は、典型的なリレーショナル表のロードの場合とほぼ同じです。ただし、この場合、実際に使用するサブタイプがオブジェクト表で有効であるかどうかをSQL*Loaderで判断できるように、サブタイプに名前を指定する必要があります。この概念を例10-12に示します。
オブジェクト型定義
CREATE TYPE employees_type AS OBJECT (name VARCHAR2(30), age NUMBER(3), emp_id NUMBER(5)) not final; CREATE TYPE hourly_emps_type UNDER employees_type (hours NUMBER(3)); CREATE TABLE employees_v3 of employees_type;
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE employees_v3 1 TREAT AS hourly_emps_type FIELDS TERMINATED BY ',' (name CHAR(30), age INTEGER EXTERNAL(3), emp_id INTEGER EXTERNAL(5), 2 hours INTEGER EXTERNAL(2))
データ・ファイル(sample.dat)
Johny Quest, 18, 007, 32, Speed Racer, 16, 000, 20,
TREAT
AS
句で指定すると、SQL*Loaderでは、実際の宣言型がemployee_type
であるオブジェクト表が、hourly_emps_type
型であると宣言されたかのように処理されます。
hours
属性はhourly_emps_type
の属性であるため、ここで使用できます。TREAT
AS
句が指定されていない場合、この属性は、オブジェクト表の宣言型の属性ではないためエラーを返します。
SQL*Loaderは、システム生成OIDのREF
列、主キーREF
列および主キーを使用可能な有効範囲なしREF
列をロードできます。これらの各列については、次の項で説明するとおり、表名を指定する方法が重要です。
SQL*Loader制御ファイルでは、REF
列に対応するフィールドの記述は、列名の後にREF句を記述することによって行います。REF句には、引数として表名とロードされるREF
列の型に適用可能な属性を取ります。表名は、(FILLERフィールドを使用して)動的に、または定数として指定できます。また、表名は、スキーマ名の有無にかかわらず指定できます。
REF句で指定する表名が、定数として、またはFILLERフィールドを使用して指定されるかどうかにかかわらず、大/小文字を区別して認識されます。このため、次のような状況が発生します。
SCOTT
が、小文字で表名を引用符で囲まずにtable2
という名前の表を作成する場合、その表は次のいずれの方法でもREF句で使用できます。
SCOTT
が、大文字と小文字を組み合せた名前を引用符で囲んで"Table2"
という名前の表を作成する場合、その表は次のいずれの方法でもREF句で使用できます。
いずれの状況においても、定数
がFILLERフィールドに置換された場合、同じ値がデータ・セクションに書き込まれると、例に示したとおり値が処理されます。
システム生成REF
列をロードする場合、SQL*Loaderでは、REF
列を構築する実OIDが残りのデータとともにデータ・ファイル内にあるとみなされます。REF
列に対応するフィールドの記述は、列名の後にREF
句を記述することによって行います。
REF
句には、引数として表名とOIDを取ります。その引数は、定数として、または(FILLERフィールドを使用して)動的に指定できます。適切な構文については、「ref_spec」を参照してください。例10-13に、システム生成OID型のREF
列のロード例を示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE departments_alt_v2 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (dept_no CHAR(5), dept_name CHAR(30), 1 dept_mgr REF(t_name, s_oid), s_oid FILLER CHAR(32), t_name FILLER CHAR(30))
データ・ファイル(sample.dat)
22345, QuestWorld, 21E978406D3E41FCE03400400B403BC3, EMPLOYEES_V2, 23423, Geography, 21E978406D4441FCE03400400B403BC3, EMPLOYEES_V2,
主キーREF
列をロードするには、SQL*Loader制御ファイルのフィールドで列名の後にREF
句を記述する必要があります。REF
句には、カンマで区切ったフィールド名および定数値のリストが引数として必要です。最初の引数は表名で、その後にロードするREF
列の基になる主キーOIDを指定する引数を記述します。適切な構文については、「ref_spec」を参照してください。
SQL*Loaderでは、引数の順序は、参照されている表で主キーOIDを作成する列の相対順序に一致しているとみなされます。例10-14に、主キーREF
列のロード例を示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE departments_alt FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (dept_no CHAR(5), dept_name CHAR(30), dept_mgr REF(CONSTANT 'EMPLOYEES', emp_id), emp_id FILLER CHAR(32))
データ・ファイル(sample.dat)
22345, QuestWorld, 007, 23423, Geography, 000,
主キーが使用可能な有効範囲なしREF
列によって、システム生成および主キーの両方の型のREF
を参照できます。このようなREF
列をロードするための構文は、システム生成OID型のREF
列または主キーREF
列にロードする場合と同じです。例10-13「システム生成REF列のロード」および例10-14「主キーREF列のロード」を参照してください。
主キーが使用可能な有効範囲なしREF
列をロードする場合は、次の制限が適用されます。
REF
のみを参照できます。両方は参照できません。両方の型の参照を試行すると、データ行が拒否され、参照表名が無効であることを示すエラー・メッセージが表示されます。
REF
をロードする場合、単一表へのロード中は、1つのオブジェクト表のみ参照できます。複数の有効範囲なし主キーREF
(いくつかのREFはオブジェクト表Xを指し、別のREFはオブジェクト表Yを指す)をロードする場合、次のいずれかの操作を実行する必要があります。
REF
のオブジェクト表名など、WHEN
句によってデータのいくつかの要素が指定されている複数のINTO
TABLE
句を使用して、ロードを1回実行します。次に例を示します。
LOAD DATA INFILE 'data.dat' INTO TABLE orders_apk APPEND when CUST_TBL = "CUSTOMERS_PK" fields terminated by "," ( order_no position(1) char, cust_tbl FILLER char, cust_no FILLER char, cust REF (cust_tbl, cust_no) NULLIF order_no='0' ) INTO TABLE orders_apk APPEND when CUST_TBL = "CUSTOMERS_PK2" fields terminated by "," ( order_no position(1) char, cust_tbl FILLER char, cust_no FILLER char, cust REF (cust_tbl, cust_no) NULLIF order_no='0' )
この2つの方法のいずれも使用しない場合、データ行が拒否され、参照されている表の名前が無効であることを示すエラー・メッセージが表示されます。
REF
は、SQL*Loaderではサポートされていません。
REF
列にシステム生成のREF
をロードする場合は、「システム生成OID型のREF列」で説明されている制限も適用されます。
REF
列に主キーREF
をロードする場合は、「主キーREF列」で説明されている制限も適用されます。LOBは、ラージ・オブジェクト型です。SQL*Loaderでは、次のLOB型がサポートされています。
BLOB
: 非構造化バイナリ・データを含む内部LOB。
CLOB
: 文字データを含む内部LOB。
NCLOB
: 各国語キャラクタ・セットの文字を含む内部LOB。
BFILE
: サーバー側のオペレーティング・システム・ファイルのデータベース表領域外に格納されるBLOB
。
LOBは列データ型で、NCLOB
以外は、オブジェクトの属性データ型です。LOBは実際の値を持ち、その値はNULLでも「値なし(空)」でもかまいません。LOBに格納される長さ0のフィールドがある場合は、SQL*Loaderによって空のLOBが作成されます。(他のデータ型の場合は、このデータ型とは異なり、長さ0の文字列に対して、列はSQL*LoaderによってNULLに設定されます。)つまり、NULL値をLOB列にロードする方法は、NULL句を使用する方法のみです。
XML
列は、SYS
.XMLTYPE
型であると宣言された列です。SQL*Loaderは、XML
列をCLOB
と同様に処理します。次の項で説明するプライマリ・データ・ファイルまたはLOBFILESからのLOBデータのロード方法は、XML
列のロードに適用できます。
LOBは非常に大きなデータであるため、SQL*Loaderでは、LOBデータをプライマリ・データ・ファイル(残りのデータを持つインライン)またはLOBFILEのいずれかからロードできます。この項では、次の項目について説明します。
プライマリ・データ・ファイルから内部LOB(BLOB
、CLOB
およびNCLOB
)またはXML
列をロードするには、次の標準SQL*Loader形式を使用できます。
これらの各形式については、次の項で説明します。
例10-15に示すように、これはLOBデータをロードする場合、最も高速で、概念的に単純な形式です。
この形式でLOBをロードするには、ロード時のデータ型としてCHAR
またはRAW
を使用する必要があります。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' "fix 501" INTO TABLE person_table (name POSITION(01:21) CHAR, 1 "RESUME" POSITION(23:500) CHAR DEFAULTIF "RESUME"=BLANKS)
データ・ファイル(sample.dat)
Johny Quest Johny Quest 500 Oracle Parkway jquest@us.oracle.com ...
DEFAULTIF
句が使用されているため、RESUMEが含まれているデータ・フィールドが空の場合、NULLのLOBではなく、空のLOBになります。ただし、DEFAULTIF
ではなくNULLIF
句が使用されている場合は、空のデータ・フィールドではなくNULLになります。また、ロード時に、CHAR
以外にもSQL*Loaderのデータ型を使用できます。たとえば、BLOB
のロード時、RAW
データ型を使用する場合があります。
この形式で、同じ列(データ・ファイルのフィールド)で異なるサイズのLOBを、問題なく処理できます。ただし、このような柔軟性によって、SQL*Loaderで区切り文字列を探してデータをスキャンする必要があるため、パフォーマンスに影響します。
単一キャラクタのデリミタで、文字列のデリミタを指定する場合は、データ・ファイルのキャラクタ・セットに注意してください。データ・ファイルのキャラクタ・セットが制御ファイルのキャラクタ・セットと異なる場合は、デリミタを16進文字列の表記法で指定できます(X'hexadecimal
string
'
)。デリミタを実際に16進文字列で指定する場合は、入力データ・ファイルのキャラクタ・セット中の有効な文字で指定する必要があります。一方、16進文字列で指定しない場合、デリミタは、クライアント(制御ファイル)のキャラクタ・セットで指定してください。この場合、デリミタは、SQL*Loaderによってデータ・ファイル内で検索される前に、データ・ファイルのキャラクタ・セットに変換されます。
次のことに注意してください。
WHITESPACE
で終わる場合、先頭の空白は切り捨てられます。
SQL*Loaderによる
注意:
CLOB
データ移動時のフィールドのデフォルト最大長は255バイトですが、最大2GBまでの値を指定できます。デリミタフィールドでは、長さが指定されている場合、その長さが最大長として使用されます。値が指定されない場合、デフォルトは255バイトです。デリミタ付きで255バイトを超えるCHAR
フィールドの場合、最大長を指定する必要があります。CHAR
データ型の詳細は、「CHAR」を参照してください。
例10-16にデリミタ付きフィールドへのLOBデータのロードの例を示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' "str '|'" INTO TABLE person_table FIELDS TERMINATED BY ',' (name CHAR(25), 1 "RESUME" CHAR(507) ENCLOSED BY '<startlob>' AND '<endlob>')
データ・ファイル(sample.dat)
Johny Quest,<startlob> Johny Quest 500 Oracle Parkway jquest@us.oracle.com ... <endlob> 2 |Speed Racer, .......
<startlob>
および<endlob>
は、囲み文字列です。デフォルトのバイト長セマンティクスでは、CHAR(507)
を使用して読み込むことができるLOBの最大長は507バイトです。文字長セマンティクスが使用された場合、最大長は507文字になります。詳細は、「文字長セマンティクス」を参照してください。
'|'
は、<endlob>
のすぐ後にあり、その後に改行文字が続く場合、改行は、次のレコードの一部として解釈されます。代替方法は、レコード・セパレータに改行部分を作成することです(たとえば'|\n'
、または16進ではX'7C0A'
)。
VARCHAR
、VARCHARC
またはVARRAW
データ型を使用して、Length-Value Pairフィールドで編成されたLOBデータをロードできます。このロード方法を使用すると、デリミタ付きフィールドを使用するより高いパフォーマンスを得ることができます。ただし、柔軟性は損なわれます(たとえば、ロード前に各LOBの長さの確認が必要です)。例10-17に、Length-Value PairフィールドのLOBデータのロード例を示します。
制御ファイルの内容
LOAD DATA 1 INFILE 'sample.dat' "str '<endrec>\n'" INTO TABLE person_table FIELDS TERMINATED BY ',' (name CHAR(25), 2 "RESUME" VARCHARC(3,500))
データ・ファイル(sample.dat)
Johny Quest,479 Johny Quest 500 Oracle Parkway jquest@us.oracle.com ... <endrec> 3 Speed Racer,000<endrec>
"RESUME"
は、CLOB
列に対応するフィールドです。制御ファイルでは、VARCHARC
がそのフィールドで、フィールド長は3バイト、最大サイズは500バイト(バイト長セマンティクスで)です。文字長セマンティクスが使用された場合、長さは3文字で最大サイズは500文字です。詳細は、「文字長セマンティクス」を参照してください。
VARCHARC
のlengthサブフィールドは、0(サブフィールドの値が空)です。このため、LOBインスタンスは、空に初期化されます。
LOBデータは、非常に長いデータであるため、プライマリ・データ・ファイルからではなく、LOBFILEからロードすると有効です。LOBFILEでは、LOBデータのインスタンスは、フィールド(事前に決められたサイズ、デリミタ付き、Length-Value)内にあるとみなされますが、これらのフィールドは、レコードに編成されていません(LOBFILEにはレコードの概念がありません)。そのため、レコードを扱うことによって発生する処理のオーバーヘッドを回避できます。このようなデータの編成方法は、LOBのロードにとって理想的です。
LOBFILEからロードしたLOBをメモリーに合わせる必要はありません。SQL*Loaderでは、64KB単位でLOBFILEが読み込まれます。
LOBFILEのデータ・フィールドは、次のいずれかの型です。
TERMINATED
BY
またはENCLOSED
BY
)PRESERVE
BLANKS
句は、LOBFILEから読み込むフィールドには使用できません。
この型のフィールドからデータをロードするためには、SQL*Loaderデータ型のVARRAW
、VARCHAR
またはVARCHARC
を使用します。
これらの各フィールド型の使用例については、「LOBFILEからのLOBデータのロードの例」を参照してください。前述のすべてのフィールド型は、XML
列のロードに使用できます。
LOBFILE構文については、「lobfile_spec」を参照してください。
LOBFILEを静的に指定(制御ファイルにファイル名を指定)するか、または動的に指定(FILLER
フィールドをファイル名のソースとして使用)できます。いずれの場合も、LOBFILEがEOFで終了しない場合は、LOBFILEの終わりに到達するとファイルがクローズされ、そのファイルからさらにデータを読み込む場合は、空のフィールドからデータを読み込むことになります。
ただし、LOBFILEをEOFで終了する場合は、ファイルからデータを読み込むと、常に、ファイル全体が戻されます。
同じLOBFILEを、2つの異なるフィールドのソースとして指定しないでください。指定すると、通常、2つのフィールドは、データを別々に読み込みます。
この項では、LOBFILEの異なるフィールド型からデータをロードする例を示します。
例10-18では、各LOBFILEは、それぞれ1つのLOBのソースです。この方法で編成されたLOBデータをロードするには、列名またはフィールド名の後にLOBFILEデータ型を指定します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE person_table FIELDS TERMINATED BY ',' (name CHAR(20), 1 ext_fname FILLER CHAR(40), 2 "RESUME" LOBFILE(ext_fname) TERMINATED BY EOF)
データ・ファイル(sample.dat)
Johny Quest,jqresume.txt, Speed Racer,'/private/sracer/srresume.txt',
セカンダリ・データ・ファイル(jqresume.txt)
Johny Quest 500 Oracle Parkway ...
セカンダリ・データ・ファイル(srresume.txt)
Speed Racer 400 Oracle Parkway ...
CHAR
データ型を使用して読み込まれる、40バイトのデータ・フィールドにマップされています。ここでは、デフォルトのバイト長セマンティクスの使用を想定しています。文字長セマンティクスが使用された場合、フィールドは40文字データ・フィールドにマップされます。
ext_fname
のLOBFILE名が使用されます。(CHAR
データ型を使用する)LOBFILEの最初のバイトからEOF文字までのデータがロードされます。既存のLOBFILEが指定されていない場合、RESUME
フィールドは空に初期化されます。
例10-19では、制御ファイルの特定の列にロードするLOBのサイズを指定します。ロード時、列にロードしたLOBデータは、指定したサイズとみなされます。事前に決められたサイズのフィールドでは、データ解析機能を最適に実行できます。ただし、すべてのLOBデータが必ずしも同じサイズであるとはかぎりません。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE person_table FIELDS TERMINATED BY ',' (name CHAR(20), 1 "RESUME" LOBFILE(CONSTANT '/usr/private/jquest/jqresume.txt') CHAR(2000))
データ・ファイル(sample.dat)
Johny Quest, Speed Racer,
セカンダリ・データ・ファイル(jqresume.txt)
Johny Quest 500 Oracle Parkway ... Speed Racer 400 Oracle Parkway ...
CHAR
データ型を使用して、jqresume.txt
LOBFILEから2000バイトのデータをロードするように指定しています。ここでは、デフォルトのバイト長セマンティクスの使用を想定しています。文字長セマンティクスが使用された場合、SQL*Loaderでは、最後にロードされた文字の直後の文字から順番に、2000文字のデータがロードされます。詳細は、「文字長セマンティクス」を参照してください。
例10-20では、LOBFILEがデリミタ付きフィールドである場合の、LOBデータの例を示します。この形式では、サイズの異なるLOBを同じ列にロードしても、問題は発生しません。ただし、このような柔軟性によって、SQL*Loaderで区切り文字列を探してデータをスキャンする必要があるため、パフォーマンスに影響します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE person_table FIELDS TERMINATED BY ',' (name CHAR(20), 1 "RESUME" LOBFILE( CONSTANT 'jqresume') CHAR(2000) TERMINATED BY "<endlob>\n")
データ・ファイル(sample.dat)
Johny Quest, Speed Racer,
セカンダリ・データ・ファイル(jqresume.txt)
Johny Quest 500 Oracle Parkway ... <endlob> Speed Racer 400 Oracle Parkway ... <endlob>
CHAR
の最大長に2000が指定されているため、SQL*Loaderで、フィールドの最大長を推測でき、メモリーの使用量を最適化できます。最大長を指定する場合、小さすぎる値は指定しないように注意してください。TERMINATED
BY
句は、LOBのロードを終了する文字列を指定します。かわりに、ENCLOSED
BY
句も使用できます。ENCLOSED
BY
句を使用すると、LOBFILE(LOBFILE内のLOBには順序が不要)内でのLOBの相対的な位置指定に関して、多少柔軟に対応できます。
例10-21では、LOBFILEの各LOBの先頭でデータ長が定義されています。VARCHAR
、VARCHARC
またはVARRAW
データ型を使用して、この方法で編成されたLOBデータをロードできます。
このロード方法を使用すると、デリミタ付きフィールドを使用するより高いパフォーマンスを得ることができます。ただし、柔軟性は損なわれます(たとえば、各LOBのロード前に、LOBの長さの確認が必要です)。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE person_table FIELDS TERMINATED BY ',' (name CHAR(20), 1 "RESUME" LOBFILE(CONSTANT 'jqresume') VARCHARC(4,2000))
データ・ファイル(sample.dat)
Johny Quest, Speed Racer,
セカンダリ・データ・ファイル(jqresume.txt)
2 0501Johny Quest 500 Oracle Parkway ... 3 0000
VARCHARC(4,2000)
のエントリによって、LOBFILEのLOBがLength-Value Pair形式であり、最初の4バイトが長さを示すことをSQL*Loaderに指定します。この2000
という値は、フィールドの最大サイズが2000であることを示します。ここでは、デフォルトのバイト長セマンティクスの使用を想定しています。文字長セマンティクスが使用された場合、最初の4文字は文字単位の長さとして解釈されます。フィールドの最大サイズは2000文字です。詳細は、「文字長セマンティクス」を参照してください。
Johny
Quest
の前の0501
は、次の501文字がLOBのデータであることを示します。
LOBFILEからLOBをロードする場合は、次のことに注意してください。
XML
列のみがLOBFILEからロードできます。
XML
列の場合、LOBのロード中に失敗するとNULL値が挿入されます。
pos_spec
)はできません。
NULLIF
またはDEFAULTIF
のフィールド条件は、LOBFILEから読み込まれたフィールドに基づくことはできません。
XML
列をロードするか、LOB列を参照する場合は、SQL*LoaderでLOBデータを一時LOBとして処理する必要があります。このような場合のロード・パフォーマンスを最適化するには、 『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』の一時LOBのパフォーマンスに関するガイドラインを参照してください。
BFILE
データ型には、データベースの外側にあるオペレーティング・システム・ファイルの非構造化バイナリ・データが格納されます。BFILE
列または属性には、データを含む外部ファイルを示すロケータが格納されます。BFILE
としてロードされるファイルは、ロード時に存在している必要はなく、後で作成できます。SQL*Loaderでは、必要なオブジェクト(サーバーのファイル・システム上の物理ディレクトリに対する論理的な別名)がすでに作成されていると想定しています。詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。
BFILE
列に対応する制御ファイルのフィールドの記述は、列名の後にBFILE
句を記述して行います。BFILE
句には、引数としてディレクトリ・オブジェクト(server_directoryの別名)名の後にBFILE
名が必要です。いずれの引数も文字列定数として指定するか、他のフィールドを介して動的にロードできます。詳細は、 『Oracle Database SQL言語リファレンス』を参照してください。
次の2つのBFILE
のロード例を示します。例10-22では、1つのファイル名のみを動的に指定する方法を、例10-23では、BFILE
とディレクトリ・オブジェクトの両方を動的に指定する方法を示します。
制御ファイルの内容
LOAD DATA INFILE sample.dat INTO TABLE planets FIELDS TERMINATED BY ',' (pl_id CHAR(3), pl_name CHAR(20), fname FILLER CHAR(30), 1 pl_pict BFILE(CONSTANT "scott_dir1", fname))
データ・ファイル(sample.dat)
1,Mercury,mercury.jpeg, 2,Venus,venus.jpeg, 3,Earth,earth.jpeg,
制御ファイルの内容
LOAD DATA INFILE sample.dat INTO TABLE planets FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' (pl_id NUMBER(4), pl_name CHAR(20), fname FILLER CHAR(30), 1 dname FILLER CHAR(20), pl_pict BFILE(dname, fname) )
データ・ファイル(sample.dat)
1, Mercury, mercury.jpeg, scott_dir1, 2, Venus, venus.jpeg, scott_dir1, 3, Earth, earth.jpeg, scott_dir2,
LOBと同様、コレクションも、プライマリ・データ・ファイル(データ・インライン)またはSDF(データ・アウトライン)のいずれかからロードできます。SDFの詳細は、「セカンダリ・データ・ファイル(SDF)」を参照してください。
コレクション・データをロードする場合、コレクションに属するデータのインスタンスが終了したことをSQL*Loaderに伝える機能が必要です。これには、2つの方法があります。
VARRAY
インスタンスにロードされる行または要素の数を指定するには、DDL構文のCOUNT
関数を使用します。COUNT
に指定する値は、数字または数字を含む文字列のいずれかで、制御ファイルでCOUNT
句よりも先に記述する必要があります。この位置の依存性は、COUNT
句に固有です。COUNT(0)
またはCOUNT(cnt_field)
を指定して、カレント行のcnt_field
が0の場合は、NULLIF
句によって上書きされないかぎり、空のコレクション(NULLではない)になります。詳細は、「count_spec」を参照してください。制御ファイルでCOUNT
句によってフィールドが指定され、そのフィールドがカレント行でNULLに設定されている場合、そのカウントを使用するコレクションは、カレント行でも空に設定されます。
TERMINATED
BY
およびENCLOSED
BY
句を使用して、一意のコレクション・デリミタを指定します。SDF
句が使用されている場合、この方法は使用できません。
制御ファイルでは、コレクションは、列オブジェクトと同様に記述します。詳細は、「列オブジェクトのロード」を参照してください。一部、次のような相違点があります。
NULLIF
またはDEFAULTIF
句ではSDFのフィールドを参照できません。
VARRAY
が列オブジェクトのVARRAY
の場合、列オブジェクトの属性は、ネストしたフィールド・リストに記述されます。
ネストした表およびVARRAY
には次の制限事項があります。
field_list
には、collection_fld_spec
を含めることはできません。
VARRAY
内にネストしたcol_obj_spec
には、collection_fld_spec
を含めることはできません。
field_list
の一部として指定したcolumn_name
は、VARRAY
パラメータを前に付けたcolumn_name
と同一である必要があります。
また、ネストした表を含む表にロードする場合、複数のロードへの細分化およびSIDの生成は自動的に行われないため注意してください。
例10-24に、VARRAY
およびネストした表のロード例を示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' "str '\n' " INTO TABLE dept REPLACE FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ( dept_no CHAR(3), dname CHAR(25) NULLIF dname=BLANKS, 1 emps VARRAY TERMINATED BY ':' ( emps COLUMN OBJECT ( name CHAR(30), age INTEGER EXTERNAL(3), 2 emp_id CHAR(7) NULLIF emps.emps.emp_id=BLANKS ) ), 3 proj_cnt FILLER CHAR(3), 4 projects NESTED TABLE SDF (CONSTANT "pr.txt" "fix 57") COUNT (proj_cnt) ( projects COLUMN OBJECT ( project_id POSITION (1:5) INTEGER EXTERNAL(5), project_name POSITION (7:30) CHAR NULLIF projects.projects.project_name = BLANKS ) ) )
データ・ファイル(sample.dat)
101,MATH,"Napier",28,2828,"Euclid", 123,9999:0 210,"Topological Transforms",:2
セカンダリ・データ・ファイル(SDF)(pr.txt)
21034 Topological Transforms 77777 Impossible Proof
TERMINATED
BY
句では、VARRAY
のインスタンス終了記号(COUNT
句は使用されていないことに注意)を指定します。
proj_cnt
は、COUNT
句に対する引数として使用するFILLERフィールドです。
SDFとプライマリ・データ・ファイルの概念は類似しています。プライマリ・データ・ファイルと同様に、SDFは、レコードおよびフィールドで構成されたレコードの集まりです。SDFは、制御ファイルごとに指定されます。SDFは、大きいネストした表およびVARRAY
をロードする場合に有効です。
SDFを指定するには、SDF
パラメータを使用します。SDF
パラメータの後に、ファイル指定文字列、または1つ以上のファイル指定文字列を含むデータ・フィールドにマップされたFILLER
フィールドを指定します。
プライマリ・データ・ファイルについては、各SDFに対して次の指定ができます。
CHARACTERSET
句を使用した、SDFのキャラクタ・セットの指定(「異なる文字コード体系の処理」を参照)。
SDFについては、次のことにも注意してください。
READSIZE
パラメータを使用してより大きな物理レコード・サイズを指定できます。コマンドラインからでも、OPTIONS
句の一部としてでもREADSIZE
パラメータを指定できます。SDFを静的に指定(実際のファイル名を指定)するか、または動的に指定(FILLER
フィールドをファイル名のソースとして使用)できます。いずれの場合も、SDFのEOFに到達するとファイルはクローズされ、そのファイルからさらにデータを読み込む場合は、空のフィールドからデータを読み込むことになります。
動的セカンダリ・ファイル指定では、動作は多少異なります。参照ファイルの指定が変更されると、常に、古いファイルはクローズされ、データは新しい参照先ファイルの最初から読み込まれます。
このようなデータ・ソース・ファイルの動的な切替えは、リセットの効果があります。たとえば、SQL*Loaderを使用して、現行のファイルから前回オープンしていたファイルに切り替える場合、前回オープンしていたファイルを再オープンし、そのファイルの最初からデータが読み込まれます。
同じSDFを、2つの異なるフィールドのソースとして指定しないでください。指定すると、通常、2つのフィールドは、データを別々に読み込みます。
ネストした表の列を含む表をロードする場合、親表を子表から分割してロードする場合があります。SIDがロード時にわかっている場合(SIDがデータとともにデータ・ファイルにある場合)、親表と子表を別々にロードできます。
例10-25に、ユーザー定義SIDを使用した親表のロード方法を示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' "str '|\n' " INTO TABLE dept FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS ( dept_no CHAR(3), dname CHAR(20) NULLIF dname=BLANKS , mysid FILLER CHAR(32), 1 projects SID(mysid))
データ・ファイル(sample.dat)
101,Math,21E978407D4441FCE03400400B403BC3,| 210,"Topology",21E978408D4441FCE03400400B403BC3,|
例10-26に、ユーザー定義SIDを使用した子表(ネストした表の記憶表)のロード方法を示します。
制御ファイルの内容
LOAD DATA INFILE 'sample.dat' INTO TABLE dept FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS 1 SID(sidsrc) (project_id INTEGER EXTERNAL(5), project_name CHAR(20) NULLIF project_name=BLANKS, sidsrc FILLER CHAR(32))
データ・ファイル(sample.dat)
21034, "Topological Transforms", 21E978407D4441FCE03400400B403BC3, 77777, "Impossible Proof", 21E978408D4441FCE03400400B403BC3,
次に、VARRAY
列をロードする場合の注意事項を示します。
VARRAY
は、データベースにロードされる前にクライアント・メモリーに作成されます。VARRAY
の各要素には、データベースにロードする前に、4バイトのクライアント・メモリーが必要です。そのため、1000個の要素を持つVARRAY
をロードする場合は、VARRAY
をデータベースにロードする前に、それぞれのVARRAY
インスタンスに、4000バイト以上のクライアント・メモリーが必要です。多くの場合、SQL*Loaderでは、VARRAY
の構築やロードに、2〜3倍のメモリー量を必要とします。
BINDSIZE
パラメータを使用して、SQL*Loaderでレコードのロードに割り当てるメモリーの量を指定します。BINDSIZE
に指定された値に応じて、SQL*Loaderで、ロード中の各フィールドのサイズを考慮し、1回のトランザクションでロードできる行数を判断します。行数が多ければトランザクションは少なくなり、パフォーマンスは向上します。ただし、システムのメモリー量に制限がある場合、パフォーマンスを優先せず、SQL*Loaderで算出した値より低い値をROWS
に指定できます。
VARRAY
または多数の小さいVARRAY
が原因で、ロード中にメモリーが不足する場合があります。この場合は、BINDSIZE
またはROWS
により小さい値を指定し、再ロードします。
|
![]() Copyright © 2007 Oracle Corporation. All Rights Reserved. |
|