Oracle DBMS_LOB:在 PLSQL 块中多次使用 DBMS_LOB.convertToBlob
Oracle DBMS_LOB: Using DBMS_LOB.convertToBlob multiple times in PLSQL block
当我尝试在同一个 PLSQL 块中多次使用 DBMS_LOB.convertToBlob
过程时,只有第一次执行按预期工作。所有额外的执行都会产生空的 blob。这是一个例子:
DECLARE
v_temp1 varchar2(32767) := 'absd';
V_temp1_blob BLOB;
V_temp2 varchar2(32767) := 'efghi';
V_temp2_blob BLOB;
v_in integer := 1;
v_out integer := 1;
v_lang integer := 0;
v_warning integer := 0;
BEGIN
DBMS_LOB.createTemporary (V_temp1_blob, TRUE);
DBMS_LOB.convertToBlob(V_temp1_blob, V_temp1, DBMS_LOB.LOBMAXSIZE, v_in, v_out, DBMS_LOB.DEFAULT_CSID, v_lang, v_warning);
dbms_output.put_line('V_temp1_blob: ' || dbms_lob.getlength(V_temp1_blob));
DBMS_LOB.createTemporary (V_temp2_blob, TRUE);
DBMS_LOB.convertToBlob(V_temp2_blob, V_temp2, DBMS_LOB.LOBMAXSIZE, v_in, v_out, DBMS_LOB.DEFAULT_CSID, v_lang, v_warning);
dbms_output.put_line('V_temp2_blob: ' || dbms_lob.getlength(V_temp2_blob));
END;
输出:
V_temp1_blob: 4
V_temp2_blob: 0
我的预期输出是:
V_temp1_blob: 4
V_temp2_blob: 5
我在这里错过了什么?
您的 v_in
和 v_out
局部变量作为 convertToBlob
过程的 dest_offset
和 src_offset
参数传入。这些是 in out
个参数,因此它们会被调用修改。
dest_offset
,也就是您传递 v_in
的目的,被定义为
(IN)Offset in bytes in the destination LOB for the start of the write.
Specify a value of 1 to start at the beginning of the LOB.
(OUT)The new offset in bytes after the end of the write.
而 src_offset
,即您传递 v_out
的目的,被定义为
(IN)Offset in characters in the source LOB for the start of the read.
(OUT)Offset in characters in the source LOB right after the end of the
read.
对于第一次调用,您在这两种情况下都传递了 1。对于第二个调用,您将传入第一个 LOB 的偏移量。在进行第二次调用之前,您需要将两个参数重新初始化为 1。
我还建议您为这些变量选择比 v_in
和 v_out
更好的变量名。如果将它们命名为 v_src_offset
和 v_dest_offset
,通常会使您的代码更清晰,并可能使错误更容易发现。
当我尝试在同一个 PLSQL 块中多次使用 DBMS_LOB.convertToBlob
过程时,只有第一次执行按预期工作。所有额外的执行都会产生空的 blob。这是一个例子:
DECLARE
v_temp1 varchar2(32767) := 'absd';
V_temp1_blob BLOB;
V_temp2 varchar2(32767) := 'efghi';
V_temp2_blob BLOB;
v_in integer := 1;
v_out integer := 1;
v_lang integer := 0;
v_warning integer := 0;
BEGIN
DBMS_LOB.createTemporary (V_temp1_blob, TRUE);
DBMS_LOB.convertToBlob(V_temp1_blob, V_temp1, DBMS_LOB.LOBMAXSIZE, v_in, v_out, DBMS_LOB.DEFAULT_CSID, v_lang, v_warning);
dbms_output.put_line('V_temp1_blob: ' || dbms_lob.getlength(V_temp1_blob));
DBMS_LOB.createTemporary (V_temp2_blob, TRUE);
DBMS_LOB.convertToBlob(V_temp2_blob, V_temp2, DBMS_LOB.LOBMAXSIZE, v_in, v_out, DBMS_LOB.DEFAULT_CSID, v_lang, v_warning);
dbms_output.put_line('V_temp2_blob: ' || dbms_lob.getlength(V_temp2_blob));
END;
输出:
V_temp1_blob: 4
V_temp2_blob: 0
我的预期输出是:
V_temp1_blob: 4
V_temp2_blob: 5
我在这里错过了什么?
您的 v_in
和 v_out
局部变量作为 convertToBlob
过程的 dest_offset
和 src_offset
参数传入。这些是 in out
个参数,因此它们会被调用修改。
dest_offset
,也就是您传递 v_in
的目的,被定义为
(IN)Offset in bytes in the destination LOB for the start of the write. Specify a value of 1 to start at the beginning of the LOB.
(OUT)The new offset in bytes after the end of the write.
而 src_offset
,即您传递 v_out
的目的,被定义为
(IN)Offset in characters in the source LOB for the start of the read.
(OUT)Offset in characters in the source LOB right after the end of the read.
对于第一次调用,您在这两种情况下都传递了 1。对于第二个调用,您将传入第一个 LOB 的偏移量。在进行第二次调用之前,您需要将两个参数重新初始化为 1。
我还建议您为这些变量选择比 v_in
和 v_out
更好的变量名。如果将它们命名为 v_src_offset
和 v_dest_offset
,通常会使您的代码更清晰,并可能使错误更容易发现。