2

我正在尝试按照本指南创建pl/sql块,但在SET orderNumberSEQ.... 我究竟做错了什么?

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

2 回答 2

5

你不需要使用SET. 只是

SELECT orderNum_seq.CURRVAL INTO orderNumberSEQ FROM DUAL;

会成功的。或者,如果您使用oracle11

orderNumberSEQ := orderNum_seq.CURRVAL;
于 2011-12-12T02:30:42.383 回答
4

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

  1. 在调用 NEXTVAL 和 CURRVAL 之间,序列的值可能已经改变。这将导致难以检测的错误,并且您可能会获得不同会话使用的值。使用插入语句中的返回子句来检索实际插入的值。
  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 表示法将其锚定到确切的表类型。

    v_userid bs_orders.userid%type;

以下代码解决了所有 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;
/
于 2011-12-12T08:09:32.280 回答