déclarer des variables dans un bloc pl/sql

j'essaie de suivre ce guide pour créer des blocs pl/sql et je reçois un ORA-00922:option manquante ou invalide sur le SET orderNumberSEQ... . Ce que je fais mal?

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;
/
2
demandé sur mnky9800n 2011-12-12 06:27:50

2 réponses

Vous n'avez pas besoin d'utiliser SET . Juste

SELECT orderNum_seq.CURRVAL INTO orderNumberSEQ FROM DUAL;

fera l'affaire. Ou si vous utilisez oracle11 :

orderNumberSEQ := orderNum_seq.CURRVAL;
4
répondu zerkms 2011-12-12 02:30:42

Il y a plusieurs problèmes avec votre approche initiale. Alors que la réponse choisie fournit correctement un moyen de déterminer la valeur actuelle de la séquence si ne règle pas ces problèmes:

  1. la valeur de la séquence peut avoir changé entre L'appel à NEXTVAL et CURRVAL. Cela conduira à un bug difficile à détecter et il est possible que vous obteniez une valeur utilisée par une session différente. utiliser la clause de retour dans le insert statement pour récupérer la valeur insérée réelle.
  2. vos noms de variables sont les mêmes que ceux de vos colonnes. Cela conduira à des bogues difficiles à détecter dans les requêtes intégrées à L'intérieur des blocs PL/SQL. assurez - vous que vos variables sont nommées différemment-vous pouvez les préfixer à partir du nom de type comme v_userid au lieu de userid.
  3. instruction SELECT à l'intérieur d'un Oracle PL/SQL bloc nécessite une clause INTO. exemple:

    sélectionner userid dans v_userid à partir de bs_orders où ono = orderNumberSEQ;

  4. La sous-requête pour current_timestamp est redondante. vous pouvez utiliser CURRENT_TIMESTAMP à la place de la sous-requête pour obtenir le même résultat.

  5. au lieu de fournir manuellement le type de colonne. L'ancrer au type de table exact en utilisant la notation de type%.

    v_userid bs_orders.userid%type;

le code suivant traite des cinq questions.

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;
/
3
répondu mulander 2011-12-12 08:17:39