2011-12-12 79 views
2

我正在嘗試關注此guide以創建pl/sql塊,我在SET orderNumberSEQ...上得到ORA-00922:缺失或無效選項。我究竟做錯了什麼?在pl/sql塊中聲明變量

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

您不需要使用SET。只是

SELECT orderNum_seq.CURRVAL INTO orderNumberSEQ FROM DUAL; 

將做的伎倆。或者如果您使用oracle11

orderNumberSEQ := orderNum_seq.CURRVAL; 
3

您的初始方法有幾個問題。 雖然選擇正確的答案提供了一種方法來確定序列的當前值是不解決這些問題:

  1. 序列的價值可能會調用NEXTVAL和CURRVAL之間變化。這會導致很難檢測到錯誤,並且有可能會得到不同會話使用的值。 在insert語句中使用返回子句檢索實際插入的值。
  2. 您的變量名稱與您的列名稱相同。這將導致很難檢測PL/SQL塊中嵌入的查詢中的錯誤。 確保您的變量名稱不同 - 您可以從類型名稱(如v_userid而不是userid)中爲它們加前綴。
  3. Oracle PL/SQL塊中的SELECT語句需要INTO子句。 示例:

    SELECT userid INTO v_userid FROM bs_orders WHERE on = orderNumberSEQ;

  4. current_timestamp的子查詢是多餘的。 您可以使用普通的CURRENT_TIMESTAMP代替子查詢來獲得相同的結果。

  5. 而不是手動提供列類型。 使用%類型表示法將其錨定到精確的表類型。

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

對每個通知+1 – zerkms