2008-10-23 6 views
41

Je sais que je peux insérer plusieurs lignes en utilisant une seule instruction, si j'utilise la syntaxe dans this answer.Comment puis-je insérer plusieurs lignes dans Oracle avec une valeur de séquence?

Cependant, l'une des valeurs que je suis d'insertion est prise d'une séquence, à savoir

insert into TABLE_NAME 
(COL1,COL2) 
select MY_SEQ.nextval,'some value' from dual 
union all 
select MY_SEQ.nextval,'another value' from dual 
; 

Si je tente de l'exécuter, je reçois une erreur ORA-02287. Y at-il un moyen de contourner cela, ou devrais-je simplement utiliser beaucoup d'instructions INSERT?

EDIT:
Si je dois spécifier des noms de colonne pour toutes les autres colonnes autres que la séquence, je perds la brièveté d'origine, donc cela ne vaut pas la peine. Dans ce cas, je vais simplement utiliser plusieurs instructions INSERT.

+1

Voir aussi http: // stackoverflow.com/questions/8292199/requête-plusieurs-nextval-de-séquence-dans-un-satement si vous êtes ici et que vous voulez simplement sélectionner plusieurs séquences uniques différentes nextval dans la même requête ... – rogerdpack

Répondre

39

Cela fonctionne:

insert into TABLE_NAME (COL1,COL2) 
select my_seq.nextval, a 
from 
(SELECT 'SOME VALUE' as a FROM DUAL 
UNION ALL 
SELECT 'ANOTHER VALUE' FROM DUAL) 
+0

Obtention de l'erreur suivante: 'java.sql.BatchUpdateException: ORA-02287: numéro de séquence non autorisé ici' – beckah

+0

@beckah poser une nouvelle question montrant votre version SQL et Oracle? –

+0

compris! structurer la valeur de la séquence insérée non pas comme une requête mais simplement comme «sequencer.nextval» comme une valeur d'insertion a bien fonctionné :) @WW – beckah

1

Une possibilité consiste à créer un déclencheur sur insertion pour ajouter le numéro de séquence correct.

2

De Oracle Wiki, l'erreur 02287 est

An ORA-02287 occurs when you use a sequence where it is not allowed.

Parmi les endroits où les séquences ne peuvent pas être utilisés, vous semblez essayer:

In a sub-query

il semble donc vous ne pouvez pas faire des multiples dans la même déclaration.

La solution qu'ils offrent est:

If you want the sequence value to be inserted into the column for every row created, then create a before insert trigger and fetch the sequence value in the trigger and assign it to the column

+0

J'ai déjà fait cela auparavant. C'est une douleur, mais cela semble être le seul moyen de contourner le problème. – madlep

+0

-1 S'il vous plaît vérifier la réponse par WW, cela a fonctionné pour moi! –

4
insert into TABLE_NAME 
(COL1,COL2) 
WITH 
data AS 
(
    select 'some value' x from dual 
    union all 
    select 'another value' x from dual 
) 
SELECT my_seq.NEXTVAL, x 
FROM data 
; 

Je pense que c'est ce que vous voulez, mais je n'ai pas accès à l'oracle pour le tester maintenant.

+0

Quelle version d'Oracle cela nécessite-t-il? –

+0

avec est disponible en 9i – EvilTeach

24

Il ne fonctionne pas parce que la séquence ne fonctionne pas dans les scénarios suivants:

  • Dans une clause WHERE
  • Dans un PAR GROUPE ou clause ORDER BY
  • Dans une clause DISTINCT
  • Avec UNION une ou INTERSECT ou MINUS
  • Dans une sous-requête

Source: http://www.orafaq.com/wiki/ORA-02287

Cependant, cela fonctionne:

insert into table_name 
      (col1, col2) 
    select my_seq.nextval, inner_view.* 
    from (select 'some value' someval 
      from dual 
      union all 
      select 'another value' someval 
      from dual) inner_view; 

Essayez-:

create table table_name(col1 varchar2(100), col2 varchar2(100)); 

create sequence vcert.my_seq 
start with 1 
increment by 1 
minvalue 0; 

select * from table_name; 
+0

Upvote pour fournir des références sur pourquoi. – cbeuker

0

cela fonctionne et il n'y a pas besoin d'utiliser tous les syndicats.

Insert into BARCODECHANGEHISTORY (IDENTIFIER,MESSAGETYPE,FORMERBARCODE,NEWBARCODE,REPLACEMENTDATETIME,OPERATORID,REASON) 
select SEQ_BARCODECHANGEHISTORY.nextval, MESSAGETYPE, FORMERBARCODE, NEWBARCODE, REPLACEMENTDATETIME, OPERATORID, REASON 
from (
    SELECT 
    'BAR' MESSAGETYPE, 
    '1234567890' FORMERBARCODE, 
    '1234567899' NEWBARCODE, 
    to_timestamp('20/07/12','DD/MM/RR HH24:MI:SSXFF') REPLACEMENTDATETIME, 
    'PIMATD' OPERATORID, 
    'CORRECTION' REASON 
    FROM dual 
); 
+2

vraiment? Comment insérer plus d'une ligne dans une seule instruction sans utiliser union? – Ovesh

Questions connexes