最近在进行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.   

    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)你要先把这个sequence 值存到一个变量里,你这样用 第二次也就是比往items 表中插入时已经比orders表中增长了 1个步长 
      

  2.   

    1)
    errors:=1;
    这一句改成 errors number :=1;
    2)
    rollback mystart;
    这一句改成 rollback to savepoint mystart
      

  3.   

    我原本是想直接给输出变量errors赋值,难道这样写不行吗,非得重新定义个number类型的errors变量吗?
      

  4.   

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

  5.   

    errors是输出变量啊,那你把errors:=1;位置挪动到begin下面一行就好了。
      

  6.   

    这个就是一个保存点,如果有多个保存点,rollback的时候可以选择rollback到哪个保存点。
    对于你的这个过程,可以把savepoint mystart这句去掉,把最后的rollback语句直接写成rollback即可
      

  7.   

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

  8.   

    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的位置不正确