2

I am trying to follow this guide for creating pl/sql blocks and I am getting an ORA-00922:missing or invalid option on the SET orderNumberSEQ.... What am I doing wrong?

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;
/
mnky9800n
  • 1,113
  • 2
  • 15
  • 33

2 Answers2

5

You don't need to use SET. Just

SELECT orderNum_seq.CURRVAL INTO orderNumberSEQ FROM DUAL;

will do the trick. Or if you use oracle11:

orderNumberSEQ := orderNum_seq.CURRVAL;
zerkms
  • 249,484
  • 69
  • 436
  • 539
4

There are several problems with your initial approach. While the selected answer correctly provides a way to determine the current value of the sequence is does not address these problems:

  1. The value of the sequence might have changed between the call to NEXTVAL and CURRVAL. This will lead to a hard to detect bug and there is a possibility that you will get a value used by a different session. Use the returning clause in the insert statement to retrieve the actual inserted value.
  2. Your variable names are the same as your column names. This will lead to hard to detect bugs in queries embedded inside PL/SQL blocks. Make sure your variables are named differently - you can prefix them from the type name like v_userid instead of userid.
  3. SELECT statement inside an Oracle PL/SQL block requires an INTO clause. Example:

    SELECT userid INTO v_userid FROM bs_orders WHERE ono = orderNumberSEQ;

  4. The sub-query for current_timestamp is redundant. You can use plain CURRENT_TIMESTAMP in place of the sub-query to achieve the same result.

  5. Instead of manually providing the column type. Anchor it to the exact table type using %type notation.

    v_userid bs_orders.userid%type;

The following code addresses all 5 issues.

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;
/
mulander
  • 196
  • 4