在pl / sql块中声明变量

时间:2011-12-12 02:27:50

标签: sql variables plsql declare

我正在尝试关注此guide来创建pl/sql块,并且我在SET orderNumberSEQ...上收到了ORA-00922:缺失或无效的选项。我做错了什么?

declare
orderNumberSEQ number(5);
userid varchar(20);

begin
insert into bs_orders (userid, ono, timepurchased)
values('lilith', orderNum_seq.NEXTVAL,(SELECT current_timestamp FROM dual));

SET orderNumberSEQ := orderNum_seq.CURRVAL;

SELECT userid FROM bs_orders
where ono = orderNumberSEQ;
end;
/

2 个答案:

答案 0 :(得分:4)

您无需使用SET。刚

SELECT orderNum_seq.CURRVAL INTO orderNumberSEQ FROM DUAL;

会做到这一点。或者,如果您使用oracle11

orderNumberSEQ := orderNum_seq.CURRVAL;

答案 1 :(得分:3)

您的初始方法存在一些问题。 虽然所选答案正确提供了确定序列当前值的方法,但并未解决这些问题:

  1. 序列的值可能在对NEXTVAL和CURRVAL的调用之间发生了变化。这将导致难以检测到的错误,并且您可能会获得其他会话使用的值。 使用insert语句中的returns子句检索实际插入的值。
  2. 您的变量名称与列名称相同。这将导致难以检测嵌入PL / SQL块内的查询中的错误。 确保您的变量的名称不同 - 您可以使用类型名称(如v_userid而非userid)为它们添加前缀。
  3. Oracle PL / SQL块中的SELECT语句需要INTO子句。 示例:

    SELECT userid INTO v_userid FROM bs_orders WHERE ono = orderNumberSEQ;

  4. current_timestamp的子查询是多余的。 您可以使用普通的CURRENT_TIMESTAMP代替子查询来获得相同的结果。

  5. 而不是手动提供列类型。 使用%type notation将其锚定到确切的表格类型。

    v_userid bs_orders.userid%type;

  6. 以下代码解决了所有5个问题。

    DECLARE
     v_userid bs_orders.userid%type; -- anchoring the type
    BEGIN
      INSERT INTO bs_orders(userid  , ono                 , timepurchased)
                     VALUES('lilith', orderNum_seq.NEXTVAL, CURRENT_TIMESTAMP)
      RETURNING userid INTO v_userid; -- instead of currval and an additional select
      -- do whatever you want with v_userid here
    END;
    /