日期:2014-05-17  浏览次数:21403 次

oracle中创建存储过程出现已编译,但出现警告
最近在进行jsp开发,用到了oracle中的存储过程。现在自己写了一个存储过程,具体需求如下:数据库中有userinfo(用户表),books(书籍表),items(订单详细表),orders(订单表有如下字段oid,username【username是引用的userinfo中的】)表。现在要购买一本书籍,需要更新图书库存数量,添加订单和订单详细信息。
以下是自己写的存储过程:
CREATE OR REPLACE PROCEDURE update_order(bid IN NUMBER,uname in varchar2,counts int number,price in varchar2,errors OUT NUMBER)
 AS
 errors:=1;
 oids int;--订单ID
 BEGIN
 savepoint mystart; --→注意:这段代码没写也是出现相同问题
  insert into orders values(swq_que.nextval,uname);--插入订单表
  select oid into oids from orders where username=uname;--订单ID赋值
  update books set stock=stock-10 where bid=bid;--更新库存
  insert into items values(swq_que.nextval,oids,bid,sysdate,counts,price,counts*price);--插入订单
  commit;
 EXCEPTION
  WHEN others THEN
  errors:=0;
  rollback mystart; --→注意:(mystart)这段代码没写也是出现相同问题
 END;
环境抛出异常如下:

【PROCEDURE update_order 已编译 Warning: 执行完毕, 但带有警告】


调用上述存储过程为:
 DECLARE
errors NUMBER;
BEGIN
  update_order(11,'luckytoms',1,'12',errors);
  DBMS_OUTPUT.PUT_LINE(errors);
END;

异常如下:
【错误报告:
ORA-06550: 第 4 行, 第 3 列:
PLS-00905: 对象 QUE.UPDATE_ORDER 无效
ORA-06550: 第 4 行, 第 3 列:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:



最后我使用show error,查看具体错误信息,提示如下:

1/67 PLS-00103: 出现符号 "NUMBER"在需要下列之一时:
:= . ) , @ % default
character
符号 ":=" 被替换为 "NUMBER" 后继续。

3/8 PLS-00103: 出现符号 "="在需要下列之一时:
constant exception
<an identifier> <a double-quoted delimited-identifier> table
LONG_ double ref char time timestamp interval date binary
national character nchar
符号 "<an identifier>" 被替换为 "=" 后继续。

15/15 PLS-00103: 出现符号 "MYSTART"在需要下列之一时:
; comment to work
<a SQL statement>
符号 ";" 被替换为 "MYSTART" 后继续。


------解决方案--------------------
1)
errors:=1;
这一句改成 errors number :=1;
2)
rollback mystart;
这一句改成 rollback to savepoint mystart


------解决方案--------------------
探讨
还有就是这个savepoint mystart具体是什么意思,为什么网上有些人写的存储过程也不用这个,请赐教!!

------解决方案--------------------
探讨
我以前学过sql server,里面的存储过程是只要执行了它就保存在sql server系统中,下次后台C#程序只要直接调用存储过程就可以,而在oracle中存储过程编译之后,它也会想sql server一样自动保存,下次使用不用重新编译?还是要重新再次运行存储过程,然后在调用?

------解决方案--------------------
errors:=1;--这个要放在BEGIN之后,AS之后BEGIN之前是声明变量的,不能直接给参数赋值

下面这段会出现逻辑问题,LZ稍微测试下就知道。假设swq_que初始值=0
insert into orders values(swq_que.nextval,uname);--插入订单表--这里的订单ID=1
select oid into oids from orders where username=uname;--订单ID赋值
update books set stock=stock-10 where bid=bid;--更新库存
insert into items values(swq_que.nextval,oids,bid,sysdate,counts,price,counts*price);--插入订单--但是这里的订单ID=2

调用上述存储过程为:
 DECLARE
errors NUMBER;
BEGIN
update_order(11,'luckytoms',1,'12',errors);
DBMS_OUTPUT.PUT_LINE(errors);
END;

异常如下:
【错误报告:
ORA-06550: 第 4 行, 第 3 列: 
PLS-00905: 对象 QUE.UPDATE_ORDER 无效 --说明你的存储过程编译未通过。。。对象无效,因为errors:=1的位置不正确。。。



我的异常网推荐解决方案:oracle存储过程,http://www.aiyiweb.com/oracle-develop/17