5.2 BFILEロケータ
BFILE
の場合、値はサーバー側のオペレーティング・システム・ファイルに格納されます。つまり、BFILE
はデータベースの外部にあります。ファイルを参照するBFILE
ロケータは、データベース行に格納されます。
BFILE
に対応付けるために、まずオペレーティング・システム・ファイルへのフルパス名の別名であるDIRECTORY
オブジェクトを作成する必要があります。その後、SQLまたはPL/SQLではBFILENAME
関数、OCIではOCILobFileSetName()
関数を使用して、BFILE
型のインスタンスを初期化できます。このBFILE
インスタンスは、次のいずれかの方法で使用できます。
- 特定の
BFILE
の必要性が一時的で、作業中のモジュール内で制限されている場合は、このBFILE
インスタンスをBFILE
型のPL/SQLまたはOCIローカル変数に割り当てることができます。その後、データベース内の列に関連付けることなく、この変数に対してBFILE
関連のAPIを使用できます。一時インスタンスに対するBFILE
API操作は、サーバーへのラウンドトリップなしでクライアント側で実行されます。 INSERT
文またはUPDATE
文を使用して、BFILE
列にBFILE
への永続参照を挿入できます。SQLを使用してBFILE
を持つ行を挿入または更新する前に、BFILE
変数をNULL
またはDIRECTORY
オブジェクト名とファイル名に初期化する必要があります。ノート:
OCISetAttr()
関数では、BFILE
ロケータをNULL
に設定できません。OCIにNULL BFILE
を挿入するには、バインド値をNULL
に設定する必要があります。
同じレコード内に複数のBFILE
列が存在する場合や、同じファイルを参照する異なるレコードが存在する場合があります。たとえば、次のUPDATE
文は、lob_table
内でkey_value = 21
を持つ行を持つBFILE
列が、key_value = 22
を持つ行と同じファイルを参照するように設定します。
UPDATE lob_table SET f_lob = (SELECT f_lob FROM lob_table WHERE key_value = 22) WHERE
key_value = 21;
オブジェクト内のBFILE
オブジェクトでBFILE
を使用している場合は、まずBFILE
値を設定し、次にオブジェクトをデータベースにフラッシュする必要があります。したがって、最初にOCIObjectNew()
関数をコールし、次にOCILobFileSetName()
関数とOCIObjectFlush()
関数をそれぞれコールする必要があります。
共有サーバー(マルチスレッド・サーバー)・モードのBFILE
データベースでは、共有サーバー(マルチスレッド・サーバー)・モードでのBFILE
データ型のセッション移行がサポートされません。これは、共有サーバー・セッションでは、BFILE
操作がある共有サーバーにバインドされ、あるサーバーから別のサーバーに移行することはできず、オープンしているBFILE
インスタンスは、共有サーバーへのコールの終了後も存続できることを意味します。
ディレクトリ・オブジェクトおよびBFILEロケータの作成例
次の各項の例の多くでは、print_media
表を使用します。表の構造は次のとおりです。
図5-1 print_media表

例5-1 SQLおよびPL/SQLでのBFILEの挿入
conn system/manager
-- The DBA creates DIRECTORY object and grants READ to the user
create or replace directory MYDIR as '/your/directory/path/here';
GRANT read ON DIRECTORY MYDIR TO pm;
conn pm/pm
-- Use BFILENAME to create a BFILE locator for INSERT
INSERT INTO print_media
(product_id, ad_id, ad_composite, ad_sourcetext, ad_graphic)
VALUES
(1, 1, empty_blob(), empty_clob(), BFILENAME('MYDIR','file1.txt'));
-- After this statement, 2 rows point to the same BFILE
INSERT INTO print_media
(product_id, ad_id, ad_composite, ad_sourcetext, ad_graphic)
select 2, ad_id, ad_composite, ad_sourcetext, ad_graphic from print_media;
-- Update the 2nd row to point to a different file
UPDATE print_media SET ad_graphic = BFILENAME('MYDIR','file2.txt') WHERE product_id =2;
-- Insert a 3rd row with invalid file name
INSERT INTO print_media
(product_id, ad_id, ad_composite, ad_sourcetext, ad_graphic)
VALUES
(3, 3, empty_blob(), empty_clob(), BFILENAME('MYDIR','file_does_not_exist.txt'));
-- Insert a NULL for BFILE
INSERT INTO print_media
(product_id, ad_id, ad_composite, ad_sourcetext, ad_graphic)
VALUES
(4, 4, empty_blob(), empty_clob(), NULL);
-- Inserting in PLSQL using a BFILE variable
DECLARE
f BFILE;
BEGIN
f := BFILENAME('MYDIR','file5.txt');
INSERT INTO print_media (product_id, ad_id, ad_composite, ad_sourcetext, ad_graphic)
VALUES (5, 5, NULL, NULL, f);
END;
/
SELECT product_id, ad_id, ad_graphic FROM print_media ORDER BY 1,2;
例5-2 OCIでのBFILEの挿入
STATIC TEXT *insstmt = "INSERT INTO print_media (product_id, ad_id, ad_graphic) VALUES (:1, :1, :2)";
sword insert_bfile()
{
OCILobLocator *f = (OCILobLocator *)0;
OCIStmt *stmthp;
OCIBind *bndp1 = (OCIBind *) 0;
OCIBind *bndp2 = (OCIBind *) 0;
ub4 id;
CHECK_ERROR (OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmthp,
OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));
/*************** Allocate descriptor ***********************/
CHECK_ERROR (OCIDescriptorAlloc((dvoid *) envhp, (dvoid **) &f,
(ub4)OCI_DTYPE_FILE, (size_t) 0,
(dvoid **) 0));
/********** Execute insstmt to insert f ********************/
id = 6;
CHECK_ERROR (OCILobFileSetName(envhp, errhp, &f,
(text*)"MYDIR", sizeof("MYDIR") -1,
(text*)"file6.txt",
sizeof("file6.txt") -1));
CHECK_ERROR (OCIStmtPrepare(stmthp, errhp, insstmt,
(ub4) strlen((char *) insstmt),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
CHECK_ERROR (OCIBindByPos(stmthp, &bndp1, errhp, (ub4) 1, (dvoid *) &id,
(sb4) sizeof(id), SQLT_INT, (dvoid *) 0, (ub2 *) 0,
(ub2 *)0, (ub4) 0, (ub4*) 0, (ub4) OCI_DEFAULT));
CHECK_ERROR (OCIBindByPos(stmthp, &bndp2, errhp, (ub4) 2, (dvoid *) &f4,
(sb4) -1, SQLT_BFILE, (dvoid *) 0, (ub2 *) 0,
(ub2 *)0, (ub4) 0, (ub4*) 0, (ub4) OCI_DEFAULT));
CHECK_ERROR (OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL,
OCI_DEFAULT));
/********** Execute insstmt to insert NULL ********************/
id = 7;
CHECK_ERROR (OCIStmtPrepare(stmthp, errhp, insstmt,
(ub4) strlen((char *) insstmt),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));
CHECK_ERROR (OCIBindByPos(stmthp, &bndp1, errhp, (ub4) 1, (dvoid *) &id,
(sb4) sizeof(id), SQLT_INT, (dvoid *) 0, (ub2 *) 0,
(ub2 *)0, (ub4) 0, (ub4*) 0, (ub4) OCI_DEFAULT));
CHECK_ERROR (OCIBindByPos(stmthp, &bndp2, errhp, (ub4) 2, (dvoid *) NULL,
(sb4) -1, SQLT_BFILE, (dvoid *) 0, (ub2 *) 0,
(ub2 *)0, (ub4) 0, (ub4*) 0, (ub4) OCI_DEFAULT));
CHECK_ERROR (OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL,
OCI_DEFAULT));
}
親トピック: BFILE