oracle存储过程执行时,如何获得详细的错误信息

[复制链接]
查看11 | 回复9 | 2007-4-25 04:02:08 | 显示全部楼层 |阅读模式
存储过程示例如下:
create or replace procedure proc_test( strAge in string, strName in string, ret_code out string, v_error_message out string) is
begin
declare
strsql varcchar(1024);
begin
strsql :='select name from student where age=100';
execute immediate strsql using strAge ;
strsql :='select age from teacher where name=jill';
execute immediate strsql using strName ;
ret_code:=0;
v_error_message:='OK';
EXCEPTION
WHEN OTHERS THEN
ret_code := sqlcode;
v_error_message := sqlerrm;
rollback;
end;
end proc_cancel_digital_id;
上面的存储过程是例子。
上面有两个select,任何一个查不到数据都会抛异常。数据库返回码是100,找不到数据。
但是我想获得详细的错误信息,到底是上面的student找不到记录,还是teacher表找不到记录,请问这里要怎么做?谢谢
回复

使用道具 举报

千问 | 2007-4-25 04:02:08 | 显示全部楼层
你的语句不会报异常的,你要多详细??定位到行行吗?dbms_utility.format_error_backtrace
回复

使用道具 举报

千问 | 2007-4-25 04:02:08 | 显示全部楼层
dbms_utility.format_error_backtrace足够了。要按我的习惯,程序一进去会把所有参数的值存在SESSION里面,一旦出错这些也写到日志表。
如果WHEN OTHERS里面不带RAISE或RAISE_APPLICATION_ERROR,大多数情况下可以认为是个BUG.
回复

使用道具 举报

千问 | 2007-4-25 04:02:08 | 显示全部楼层
你的个段几行的代码,出现了N多的漏洞,不想打击你,你肯定刚学PLSQL没多久。。。
因为代码太希乱了。。。
回复

使用道具 举报

千问 | 2007-4-25 04:02:08 | 显示全部楼层
原帖由 solomon_007 于 2011-4-2 09:59 发表
你的个段几行的代码,出现了N多的漏洞,不想打击你,你肯定刚学PLSQL没多久。。。
因为代码太希乱了。。。

strsql :='select name from student where age=100';
execute immediate strsql using strAge ;
比如这个,根本没有啥用,不存在报异常的问题,都不会获取数据
回复

使用道具 举报

千问 | 2007-4-25 04:02:08 | 显示全部楼层
原帖由 notags 于 2011-4-2 10:00 发表
strsql :='select name from student where age=100';
execute immediate strsql using strAge ;
比如这个,根本没有啥用,不存在报异常的问题,都不会获取数据

表或字段名被别人改了,不就报错了。
回复

使用道具 举报

千问 | 2007-4-25 04:02:08 | 显示全部楼层
错误:
1. a.非匿名的PLSQL块,is/as后面直接跟变量定义
b.只是匿名的PLSQL块才以declare开头
c.在任何的PLSQL块内部可以在BEGIN 。。。END之间再定义PLSQL块嵌套,嵌套的PLSQL块可以带DECLARE
进行定义
所以你的代码中的
begin
declare

end proc_cancel_digital_id;
这三行可以不要。

2. EXCEPTION部分的rollback也可以不用要
因为你的PLSQL块内部只有SELECT,而不是DELETE,INSERT ,UPDATE。

3. 输出参数strAge,strName,ret_code,v_error_message
a.完全没有规范可言,真希乱
b.string 数据类型是sys.STANDARD 包中定义的子类型 subtype STRING is VARCHAR2;
所以直接用标量类型更好,减少一道转换
(另外一看就知这是搞比如java 之类的 定义习惯)

可参考如下:

create or replace procedure proc_test( p_age INNUMBER,

p_nameINVARCHAR2,

P_ret_codeOUT VARCHAR2,

p_error_msg OUT VARCHAR2

)
as
...


4. EXECUTE IMMEDIATE动态语句

strsql :='select name from student where age=100';
execute immediate strsql using strAge ;
strsql :='select age from teacher where name=jill';
execute immediate strsql using strName ;
a. bind variables 使用错误应该是

strsql :='select name from student where age=:1';
execute immediate strsql using strAge ;

strsql :='select age from teacher where name=:2';
execute immediate strsql using strName ;

b. 没有象你这样用execute immediate strsql
而strsql又只是select的。
一般会带return or returning,如果是select的话
execute immediate strsql return v_ageusing p_age
execute immediate strsql return v_name using p_name

5.变量定义部分
strsql varcchar(1024);
KAO,还写错了varcchar 应该是VARCHAR 或 VARCHAR2

其实在系统的包sys.STANDARD中已定义如下:

subtype VARCHAR is VARCHAR2;
subtype STRING is VARCHAR2;

6. 业务处理
"上面有两个select,任何一个查不到数据都会抛异常"

没有定义子块,出了异常,也只是最外层的EXCEPTION捕捉
无法分辨

应该:

BEGIN


BEGIN

strsql :='select name from student where age=:1';

execute immediate strsql return v_name using p_age;

EXCEPTION when ...

....

END;



...


END;


7.

BEGIN

strsql :='select name from student where age=:1';

execute immediate strsql return v_name using p_age;

EXCEPTION when ...

....

END;

直接用,根本不需要用动态SQL

BEGIN

SELECT name

INTO v_name

FROM student
WHERE age = p_age;
EXCEPTION WHEN NO_DATA_FOUND THEN
p_ret_code:= sqlcode;
p_error_message := sqlerrm;
END;

...

8。唉,就是个希乱。。。。。。


(无意冒犯你)
要用好,就要从头学SQL/PLSQL。。。。。。
回复

使用道具 举报

千问 | 2007-4-25 04:02:08 | 显示全部楼层
谁不是从采鸟开始,都是从实战中积累的,就是把书本背下来也没用的
回复

使用道具 举报

千问 | 2007-4-25 04:02:08 | 显示全部楼层
原帖由 xxxyyy 于 2011-4-2 11:24 发表
谁不是从采鸟开始,都是从实战中积累的,就是把书本背下来也没用的


恩,你说的是。 我是很随性的说说,在论坛上习惯了:见到好贴就赞两句,见到不好的就骂两句
还真的希望LZ不要计较。言词有冒犯之处还敬请原谅!
回复

使用道具 举报

千问 | 2007-4-25 04:02:08 | 显示全部楼层
ls的基础知识很扎实,值得学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行