如何修复“数字或值错误”信息?
我整个早上都被这个问题困扰了。我实际上在这里看到了这段代码,并决定将其用于我们的目的。
我遇到的问题是,当我们执行代码时,有时它会将文件从 db 写入文件夹。
其他时候,我们会收到“数字或值错误”
任何专家可以帮我修复它吗?
这是我正在使用的代码:
create or replace
PROCEDURE getfile(pfname VARCHAR2, display_name IN VARCHAR2)
IS
vblob BLOB;
vstart NUMBER := 1;
bytelen NUMBER := 32000;
len NUMBER;
my_vr RAW(32000);
x NUMBER;
v_name VARCHAR2(32760);
lv_str_len NUMBER;
l_output utl_file.file_type;
BEGIN
-- define output directory
--lv_str_len := Length(pfname);
--v_name := display_name||upper(substr(pfname,lv_str_len-3,lv_str_len));
v_name := display_name;
l_output := utl_file.Fopen('My_DIR', v_name, 'w', 32760);
-- get length of blob
SELECT dbms_lob.Getlength(FILENAME)
INTO len
FROM GENERAL.GUBFILE
WHERE gubfile_name = pfname;
-- dbms_output.put_line('Length: '||len);
-- save blob length
x := len;
-- select blob into variable
SELECT BLOBVALUE
INTO vblob
FROM FILES
WHERE filename = pfname;
-- if small enough for a single write
IF len < 32760 THEN
-- dbms_output.put_line('Single write ');
utl_file.Put_raw(l_output, vblob);
utl_file.Fflush(l_output);
ELSE -- write in pieces
-- dbms_output.put_line('multi write '||vstart);
vstart := 1;
WHILE vstart < len LOOP
dbms_lob.READ(vblob, bytelen, vstart, my_vr);
utl_file.Put_raw(l_output, my_vr);
utl_file.Fflush(l_output);
-- set the start position for the next cut
vstart := vstart + bytelen;
-- set the end position if less than 32000 bytes
x := x - bytelen;
IF x < 32000 THEN
bytelen := x;
END IF;
END LOOP;
END IF;
dbms_output.Put_line('End');
utl_file.Fclose(l_output);
END getfile;
确切的错误是:
ORA-06502: PL/SQL: numeric or value error ORA-06512: 在“USER.GETFILE”,第 40 行 ORA-06512: 在第 8 行
I have been stuck with this issue now all morning. I actually saw this code here and decide to use it for our purpose here.
The issue that I am running into is that when we execute the code, sometimes it writes a file from db to the folder.
Other times, we get "numeric or value error"
Can any expert please help me fix it?
Here is the code I am using:
create or replace
PROCEDURE getfile(pfname VARCHAR2, display_name IN VARCHAR2)
IS
vblob BLOB;
vstart NUMBER := 1;
bytelen NUMBER := 32000;
len NUMBER;
my_vr RAW(32000);
x NUMBER;
v_name VARCHAR2(32760);
lv_str_len NUMBER;
l_output utl_file.file_type;
BEGIN
-- define output directory
--lv_str_len := Length(pfname);
--v_name := display_name||upper(substr(pfname,lv_str_len-3,lv_str_len));
v_name := display_name;
l_output := utl_file.Fopen('My_DIR', v_name, 'w', 32760);
-- get length of blob
SELECT dbms_lob.Getlength(FILENAME)
INTO len
FROM GENERAL.GUBFILE
WHERE gubfile_name = pfname;
-- dbms_output.put_line('Length: '||len);
-- save blob length
x := len;
-- select blob into variable
SELECT BLOBVALUE
INTO vblob
FROM FILES
WHERE filename = pfname;
-- if small enough for a single write
IF len < 32760 THEN
-- dbms_output.put_line('Single write ');
utl_file.Put_raw(l_output, vblob);
utl_file.Fflush(l_output);
ELSE -- write in pieces
-- dbms_output.put_line('multi write '||vstart);
vstart := 1;
WHILE vstart < len LOOP
dbms_lob.READ(vblob, bytelen, vstart, my_vr);
utl_file.Put_raw(l_output, my_vr);
utl_file.Fflush(l_output);
-- set the start position for the next cut
vstart := vstart + bytelen;
-- set the end position if less than 32000 bytes
x := x - bytelen;
IF x < 32000 THEN
bytelen := x;
END IF;
END LOOP;
END IF;
dbms_output.Put_line('End');
utl_file.Fclose(l_output);
END getfile;
The exact error is:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "USER.GETFILE", line 40
ORA-06512: at line 8
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该错误来自
utl_file.put_raw
。缓冲区参数的最大大小为 32767 字节。
您检查
IF len < 32760 THEN
,但是,我在您的代码中看不到保证len
变量实际上保存vblob
变量的长度,该变量是vblob
中的缓冲区code>put_raw 调用。所以我认为 vblob 变量的实际长度比 32767 长,这就是错误的原因。
因此,我建议删除这段代码:
当然还有
END IF;
,并且始终选择“分段写入”分支。我现在明白了,您已经根据 Burleson 示例完成了此操作,该示例很好 http://www. dba-oracle.com/t_writing_blob_clob_os_file.htm
但你看,与你不同的是,Burleson 从同一个变量中获取 len 变量和 vblob 变量表和相同的字段。
编辑
因此,另一个选择是修复选择以获得长度。这意味着您必须将此 select: 替换
为:
The error comes from
utl_file.put_raw
.The maximum size of the buffer parameter is 32767 bytes.
You check for
IF len < 32760 THEN
, however, I see no guarantee in your code, that thelen
variable actually holds the length of thevblob
variable that is the buffer in theput_raw
call.So I suppose the
vblob
variable's actual length is longer then 32767 and that is the reason for the error.Hence I suggest to delete this piece of code:
also the
END IF;
of course, and always go for the 'write in pieces' branch.I see now, you've done this based on the Burleson example which is good http://www.dba-oracle.com/t_writing_blob_clob_os_file.htm
but you see, unlike you, Burleson gets the len variable and the vblob variable from the same table and the same field.
EDIT
So an other option would be to fix the select for getting length. This means you'll have to replace this select:
with this: