2 Stimmen

Variablen in einem pl/sql-Block deklarieren

Ich versuche, dies zu befolgen Leitfaden zur Erstellung pl/sql Blöcken und ich erhalte eine ORA-00922:fehlende oder ungültige Option auf der SET orderNumberSEQ... . Was mache ich falsch?

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

5voto

zerkms Punkte 239362

Sie brauchen nicht zu verwenden SET . Einfach

SELECT orderNum_seq.CURRVAL INTO orderNumberSEQ FROM DUAL;

reicht aus. Oder wenn Sie oracle11 :

orderNumberSEQ := orderNum_seq.CURRVAL;

4voto

mulander Punkte 196

Ihr ursprünglicher Ansatz birgt mehrere Probleme. Die gewählte Antwort bietet zwar eine korrekte Möglichkeit, den aktuellen Wert der Sequenz zu bestimmen, geht aber nicht auf diese Probleme ein:

  1. Der Wert der Sequenz könnte sich zwischen dem Aufruf von NEXTVAL und CURRVAL geändert haben. Dies führt zu einem schwer zu erkennenden Fehler und es besteht die Möglichkeit, dass Sie einen Wert erhalten, der von einer anderen Sitzung verwendet wird. Verwenden Sie die Rückgabeklausel in der Einfügeanweisung, um den tatsächlich eingefügten Wert abzurufen.

  2. Ihre Variablennamen sind die gleichen wie die Namen Ihrer Spalten. Dies führt zu schwer zu erkennenden Fehlern in Abfragen, die in PL/SQL-Blöcke eingebettet sind. Vergewissern Sie sich, dass Ihre Variablen anders benannt sind - Sie können sie dem Typnamen voranstellen, z. B. v_userid anstelle von userid.

  3. SELECT-Anweisung innerhalb eines Oracle PL/SQL-Blocks erfordert eine INTO-Klausel. Ejemplo:

    SELECT userid INTO v_userid FROM bs_orders WHERE ono = orderNumberSEQ;

  4. Die Unterabfrage für current_timestamp ist redundant. Sie können anstelle der Unterabfrage einfach CURRENT_TIMESTAMP verwenden, um das gleiche Ergebnis zu erzielen.

  5. Anstatt den Spaltentyp manuell anzugeben. Verankern Sie ihn mit dem genauen Tabellentyp, indem Sie die Notation %type verwenden.

    v_userid bs_orders.userid%type;

Der folgende Code behandelt alle 5 Punkte.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X