10.2 リモートLOBでのデータ・インタフェースの使用
データ・インタフェースを使用すると、CLOB
列に対してCHARACTER
バッファをバインドおよび定義し、BLOB
列に対してRAW
バッファをバインドおよび定義できます。このインタフェースは、リモートLOB列でもサポートされます。
LOBロケータを使用するよりもデータ・インタフェースを使用する利点は、LOBデータをフェッチするためにリモート・サーバーへのラウンドトリップを1回のみ行うことです。配列のバインドまたは定義の一部として使用する場合、配列操作全体に対して1回のラウンドトリップのみが使用されます。
このマニュアルで説明されている例では、dbs1
スキーマとdbs2
スキーマで作成されたprint_media
表を使用します。例で使用されているprint_media
表のCLOB
列は、ad_finaltext
です。次の各項のPL/SQL、OCIおよびJavaの例では、この列のバインドおよび定義を使用していますが、複数の列にアクセスすることもできます。サポートされる機能は次のとおりです。
-
CLOB
をVARCHAR2
として、BLOB
をRAW
としてバインドおよび定義できます。 - 配列のバインドおよび定義はサポートされています。
この項では、PL/SQLでLOBとリモート・データ・インタフェースを使用する方法について説明します。
PL/SQLにおけるデータ・インタフェースでは、サイズが32KB未満のデータのみがサポートされています。次にPL/SQLの例を示します。
CONNECT pm/pm declare my_ad varchar(6000) := lpad('b', 6000, 'b'); BEGIN INSERT INTO print_media@dbs2(product_id, ad_id, ad_finaltext) VALUES (10000, 10, my_ad); -- Reset the buffer value my_ad := 'a'; SELECT ad_finaltext INTO my_ad FROM print_media@dbs2 WHERE product_id = 10000; END; /
ad_finaltext
がCLOB
ではなくBLOB
列である場合、my_ad
はRAW
型である必要があります。LOBのサイズが32KB - 1を超えている場合、PL/SQLでは切捨てエラーが発生し、バッファの内容は未定義になります。
この項では、JDBCでLOBと一緒にリモート・データ・インタフェースを使用する方法を示します。
次のコード・スニペットは、すべてのJDBCドライバで機能します。
バインド:
非ストリーミング・モードの場合:
... String sql = "insert into print_media@dbs2 (product_id, ad_id, ad_final_text)" + " values (:1, :2, :3)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt( 1, 2 ); pstmt.setInt( 2, 20); pstmt.setString( 3, "Java string" ); int rows = pstmt.executeUpdate(); ...
ノート: Oracleでは、最大2GBのサイズの文字列に対して非ストリーミング・モードがサポートされます。ただし、コンピュータのメモリー・サイズが制限要因になる場合があります。
ストリーミング・モードの場合、前述と同じコードが機能しますが、setString()
文は次のいずれかで置き換えられます。
pstmt.setCharacterStream( 3, new LabeledReader(), 1000000 ); pstmt.setAsciiStream( 3, new LabeledAsciiInputStream(), 1000000 );
ノート: ストリーミング・インタフェースを使用して、ギガバイト・サイズの文字およびバイナリ・データをLOB列に挿入できます。
ここで、LabeledReader()
およびLabeledAsciiInputStream()
により、それぞれ文字ストリームおよびASCIIストリームが生成されます。ad_finaltext
がCLOB
ではなくBLOB
列である場合、前述の例は、バインドがRAW
型である場合に機能します。
pstmt.setBytes( 3, <some byte[] array> ); pstmt.setBinaryStream( 3, new LabeledInputStream(), 1000000 );
ここで、LabeledInputStream()
によってバイナリ・ストリームが生成されます。
定義:
非ストリーミング・モードの場合:
OracleStatement stmt = (OracleStatement)(conn.createStatement());
stmt.defineColumnType( 1, Types.VARCHAR );
ResultSet rst = stmt.executeQuery("select ad_finaltext from print_media@dbs2" );
while( rst.next() )
{
String s = rst.getString( 1 );
System.out.println( s );
}
ノート: LOBサイズが32767バイトより大きい場合、データは切り捨てられ、エラーはスローされません。
ストリーミング・モードの場合:
OracleStatement stmt = (OracleStatement)(conn.createStatement());
stmt.defineColumnType( 1, Types.LONGVARCHAR );
ResultSet rs = stmt.executeQuery("select ad_finaltext from print_media@dbs2" );
while(rs.next()) {
Reader reader = rs.getCharacterStream( 1 );
int data = 0;
data = reader.read();
while( -1 != data ){
System.out.print( (char)(data) );
data = reader.read();
}
reader.close();
}
ノート: データ型をLONGVARCHAR
として指定すると、LOB全体を選択できます。定義タイプがLONGVARCHAR
ではなくVARCHAR
に設定されている場合、データは32kで切り捨てられます。
ad_finaltext
がCLOB
ではなくBLOB
列である場合、前述の例は、定義がLONGVARBINARY
型である場合に機能します。
... OracleStatement stmt = (OracleStatement)conn.createStatement(); stmt.defineColumnType( 1, Types.INTEGER ); stmt.defineColumnType( 2, Types.LONGVARBINARY ); ResultSet rset = stmt.executeQuery("SELECT ID, LOBCOL FROM LOBTAB@MYSELF"); while(rset.next()) { /* using getBytes() */ /* byte[] b = rset.getBytes("LOBCOL"); System.out.println("ID: " + rset.getInt("ID") + " length: " + b.length); */ /* using getBinaryStream() */ InputStream byte_stream = rset.getBinaryStream("LOBCOL"); byte [] b = new byte [100000]; int b_len = byte_stream.read(b); System.out.println("ID: " + rset.getInt("ID") + " length: " + b_len); byte_stream.close(); } ...
この項では、OCIでLOBと一緒にリモート・データ・インタフェースを使用する方法を示します。
OCIにおけるデータ・インタフェースでは、サイズが2 GB未満(sb4
として宣言された変数の可能な最大値)のデータのみがサポートされます。次の疑似コードは、OCIプログラムの一部として拡張できます。
... text *sql = (text *)"insert into print_media@dbs2 (product_id, ad_id, ad_finaltext) values (:1, :2, :3)"; OCIStmtPrepare(...); OCIBindByPos(...); /* Bind data for positions 1 and 2 * which are independent of LOB */ OCIBindByPos(stmthp, &bndhp[2], errhp, (ub4) 3, (dvoid *) charbuf1, (sb4) len_charbuf1, SQLT_CHR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, 0, 0, OCI_DEFAULT); OCIStmtExecute(...); ... text *sql = (text *)"select ad_finaltext from print_media@dbs2 where product_id = 10000"; OCIStmtPrepare(...); OCIDefineByPos(stmthp, &dfnhp[2], errhp, (ub4) 1, (dvoid *) charbuf2, (sb4) len_charbuf2, SQLT_CHR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT); OCIStmtExecute(...); ...
BLOB
列には、SQLT_BIN
型を使用する必要があります。たとえば、ad_finaltext
列をCLOB
列ではなくBLOB
列として定義する場合、SQLT_BIN
型を使用して列データをバインドおよび定義する必要があります。LOBのサイズが2GB - 1
バイトを超えている場合、OCIでは切捨てエラーが発生し、バッファの内容は未定義になります。
この項では、リモートLOBでのデータ・インタフェースの使用に関する制限事項について説明します。
特定の構文はリモートLOBではサポートされていません。
-
複数のデータベースを使用する問合せはサポートされていません。
SELECT t1.lobcol, a2.lobcol FROM t1, t2.lobcol@dbs2 a2 WHERE LENGTH(t1.lobcol) = LENGTH(a2.lobcol);
次の問合せもサポートされていません(PL/SQLブロック内)。
SELECT t1.lobcol INTO varchar_buf1 FROM t1@dbs1 UNION ALL SELECT t2.lobcol INTO varchar_buf2 FROM t2@dbs2;
-
リモートの永続LOB列に移動するデータに対するバインドおよび定義のみがサポートされているため、リモートLOBに対して
CHAR
データがバインドまたは定義されているPL/SQLで渡されるパラメータは、サポートされていないリモートの一時LOBが発生する可能性があるので許可されません。次の文ではすべて、エラーが生成されます。SELECT foo() INTO varchar_buf FROM table1@dbs2; -- foo returns a LOB SELECT foo()@dbs INTO char_val FROM DUAL; -- foo returns a LOB SELECT XMLType().getclobval INTO varchar_buf FROM table1@dbs2;
-
リモート・オブジェクトが次のようなビューである場合。
CREATE VIEW v AS SELECT foo() a FROM ... ; -- foo returns a LOB /* The local database then tries to get the CLOB data and returns an error */ SELECT a INTO varchar_buf FROM v@dbs2;
これによってサポートされていないリモートの一時LOBが発生するため、エラーが戻されます。
-
RETURNING
INTO
では、CHAR
とCLOB
の間の暗黙的な変換はサポートされていません。 -
実引数がLOB型であり、リモート引数が
VARCHAR2
、NVARCHAR2
、CHAR
、NCHAR
またはRAW
である場合、PL/SQLパラメータの受渡しは許可されません。
- PL/SQLにおけるリモート・データ・インタフェースの例
この項では、PL/SQLのLOBでリモート・データ・インタフェースを使用する方法について説明します。 - JDBCにおけるリモート・データ・インタフェースの例
この項では、JDBCにおけるLOBでリモート・データ・インタフェースを使用する方法を示します。 - OCIにおけるリモート・データ・インタフェースの例
この項では、OCIにおけるLOBでのリモート・データ・インタフェースの使用方法を示します。 - リモートLOBでのデータ・インタフェースに関する制限事項
この項では、リモートLOBでのデータ・インタフェースの使用に関する制限事項について説明します。
親トピック: 分散LOB
10.2.1 PL/SQLにおけるリモート・データ・インタフェースの例
この項では、PL/SQLでLOBとリモート・データ・インタフェースを使用する方法について説明します。
PL/SQLにおけるデータ・インタフェースでは、サイズが32KB未満のデータのみがサポートされています。次にPL/SQLの例を示します。
CONNECT pm/pm declare my_ad varchar(6000) := lpad('b', 6000, 'b'); BEGIN INSERT INTO print_media@dbs2(product_id, ad_id, ad_finaltext) VALUES (10000, 10, my_ad); -- Reset the buffer value my_ad := 'a'; SELECT ad_finaltext INTO my_ad FROM print_media@dbs2 WHERE product_id = 10000; END; /
ad_finaltext
がCLOB
ではなくBLOB
列である場合、my_ad
はRAW
型である必要があります。LOBのサイズが32KB - 1を超えている場合、PL/SQLでは切捨てエラーが発生し、バッファの内容は未定義になります。
親トピック: リモートLOBでのデータ・インタフェースの使用
10.2.2 JDBCにおけるリモート・データ・インタフェースの例
この項では、JDBCでLOBと一緒にリモート・データ・インタフェースを使用する方法を示します。
次のコード・スニペットは、すべてのJDBCドライバで機能します。
バインド:
非ストリーミング・モードの場合:
... String sql = "insert into print_media@dbs2 (product_id, ad_id, ad_final_text)" + " values (:1, :2, :3)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt( 1, 2 ); pstmt.setInt( 2, 20); pstmt.setString( 3, "Java string" ); int rows = pstmt.executeUpdate(); ...
ノート:
Oracleでは、最大2 GBのサイズの文字列に対して非ストリーミング・モードがサポートされます。ただし、コンピュータのメモリー・サイズが制限要因になる場合があります。ストリーミング・モードの場合、前述と同じコードが機能しますが、setString()
文は次のいずれかで置き換えられます。
pstmt.setCharacterStream( 3, new LabeledReader(), 1000000 ); pstmt.setAsciiStream( 3, new LabeledAsciiInputStream(), 1000000 );
ノート:
ストリーミング・インタフェースを使用して、ギガバイト・サイズの文字およびバイナリ・データをLOB列に挿入できます。ここで、LabeledReader()
およびLabeledAsciiInputStream()
により、それぞれ文字ストリームおよびASCIIストリームが生成されます。ad_finaltext
がCLOB
ではなくBLOB
列である場合、前述の例は、バインドがRAW
型である場合に機能します。
pstmt.setBytes( 3, <some byte[] array> ); pstmt.setBinaryStream( 3, new LabeledInputStream(), 1000000 );
ここで、LabeledInputStream()
によってバイナリ・ストリームが生成されます。
定義:
非ストリーミング・モードの場合:
OracleStatement stmt = (OracleStatement)(conn.createStatement());
stmt.defineColumnType( 1, Types.VARCHAR );
ResultSet rst = stmt.executeQuery("select ad_finaltext from print_media@dbs2" );
while( rst.next() )
{
String s = rst.getString( 1 );
System.out.println( s );
}
ノート:
LOBサイズが32767バイトより大きい場合、データは切り捨てられ、エラーはスローされません。ストリーミング・モードの場合:
OracleStatement stmt = (OracleStatement)(conn.createStatement());
stmt.defineColumnType( 1, Types.LONGVARCHAR );
ResultSet rs = stmt.executeQuery("select ad_finaltext from print_media@dbs2" );
while(rs.next()) {
Reader reader = rs.getCharacterStream( 1 );
int data = 0;
data = reader.read();
while( -1 != data ){
System.out.print( (char)(data) );
data = reader.read();
}
reader.close();
}
ノート:
データ型をLONGVARCHAR
として指定すると、LOB全体を選択できます。定義タイプがLONGVARCHAR
ではなくVARCHAR
に設定されている場合、データは32kで切り捨てられます。
ad_finaltext
がCLOB
ではなくBLOB
列である場合、前述の例は、定義がLONGVARBINARY
型である場合に機能します。
... OracleStatement stmt = (OracleStatement)conn.createStatement(); stmt.defineColumnType( 1, Types.INTEGER ); stmt.defineColumnType( 2, Types.LONGVARBINARY ); ResultSet rset = stmt.executeQuery("SELECT ID, LOBCOL FROM LOBTAB@MYSELF"); while(rset.next()) { /* using getBytes() */ /* byte[] b = rset.getBytes("LOBCOL"); System.out.println("ID: " + rset.getInt("ID") + " length: " + b.length); */ /* using getBinaryStream() */ InputStream byte_stream = rset.getBinaryStream("LOBCOL"); byte [] b = new byte [100000]; int b_len = byte_stream.read(b); System.out.println("ID: " + rset.getInt("ID") + " length: " + b_len); byte_stream.close(); } ...
親トピック: リモートLOBでのデータ・インタフェースの使用
10.2.3 OCIにおけるリモート・データ・インタフェースの例
この項では、OCIでLOBと一緒にリモート・データ・インタフェースを使用する方法を示します。
OCIにおけるデータ・インタフェースでは、サイズが2 GB未満(sb4
として宣言された変数の可能な最大値)のデータのみがサポートされます。次の疑似コードは、OCIプログラムの一部として拡張できます。
... text *sql = (text *)"insert into print_media@dbs2 (product_id, ad_id, ad_finaltext) values (:1, :2, :3)"; OCIStmtPrepare(...); OCIBindByPos(...); /* Bind data for positions 1 and 2 * which are independent of LOB */ OCIBindByPos(stmthp, &bndhp[2], errhp, (ub4) 3, (dvoid *) charbuf1, (sb4) len_charbuf1, SQLT_CHR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, 0, 0, OCI_DEFAULT); OCIStmtExecute(...); ... text *sql = (text *)"select ad_finaltext from print_media@dbs2 where product_id = 10000"; OCIStmtPrepare(...); OCIDefineByPos(stmthp, &dfnhp[2], errhp, (ub4) 1, (dvoid *) charbuf2, (sb4) len_charbuf2, SQLT_CHR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT); OCIStmtExecute(...); ...
BLOB
列には、SQLT_BIN
型を使用する必要があります。たとえば、ad_finaltext
列をCLOB
列ではなくBLOB
列として定義する場合、SQLT_BIN
型を使用して列データをバインドおよび定義する必要があります。LOBのサイズが2GB - 1
バイトを超えている場合、OCIでは切捨てエラーが発生し、バッファの内容は未定義になります。
親トピック: リモートLOBでのデータ・インタフェースの使用
10.2.4 リモートLOBでのデータ・インタフェースに関する制限事項
この項では、リモートLOBでのデータ・インタフェースの使用に関する制限事項について説明します。
特定の構文はリモートLOBではサポートされていません。
-
複数のデータベースを使用する問合せはサポートされていません。
SELECT t1.lobcol, a2.lobcol FROM t1, t2.lobcol@dbs2 a2 WHERE LENGTH(t1.lobcol) = LENGTH(a2.lobcol);
次の問合せもサポートされていません(PL/SQLブロック内)。
SELECT t1.lobcol INTO varchar_buf1 FROM t1@dbs1 UNION ALL SELECT t2.lobcol INTO varchar_buf2 FROM t2@dbs2;
-
RETURNING
INTO
では、CHAR
とCLOB
の間の暗黙的な変換はサポートされていません。 -
実引数がLOB型であり、リモート引数が
VARCHAR2
、NVARCHAR2
、CHAR
、NCHAR
またはRAW
である場合、PL/SQLパラメータの受渡しは許可されません。
親トピック: リモートLOBでのデータ・インタフェースの使用