declare variables in a pl/sql block

走远了吗. 提交于 2019-12-24 00:24:09

问题


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;
/

回答1:


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;



回答2:


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;
/


来源:https://stackoverflow.com/questions/8469301/declare-variables-in-a-pl-sql-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!