2012-12-12 11 views
6

Dostaję ORA-00947: not enough values z poniższego zapytania:Oracle - SQL - wstawić z sub wybrać

insert into tableb 
(colA, colb, colc, cold) 
select 
(select max(rec_no)+1 from tableb) 
F2, 
F3, 
F4 
from tablea; 

Czy ktoś może wskazać mi właściwy sposób na to zapytanie sub dla Inser w/select?

Dzięki

+5

Mam nadzieję, że jesteś nie próbujemy stworzyć unikalnego identyfikatora za pomocą tej metody 'max()'. Ponieważ po prostu nie będzie działać. Lepiej użyj sekwencji –

+0

@a_horse_with_no_name, faktycznie to właśnie próbowałem. Czy możesz podać link do dyskusji na temat tego, jak to osiągnąć za pomocą sekwencji? Dzięki –

+1

Zobacz moją odpowiedź. Sekwencja nadal nie rozwiąże problemu, co zrobić, jeśli tablea jest pusta (jak wspomniał David Aldridge). –

Odpowiedz

13

Po prostu brakuje przecinka. Tak jak jest, Oracle uważa, że ​​F2 to nazwa twojego podwybicia.

insert into tableb 
(colA, colb, colc, cold) 
select 
(select max(rec_no)+1 from tableb) , -- comma here 
F2, 
F3, 
F4 
from tablea; 
+1

Dziękuję! Szaleję! –

+1

Nie zadziała, jeśli w tabeli nie ma żadnych wierszy, lub wiele sesji uruchamia ten kod w tym samym czasie. Niestety podejście jest zasadniczo wadliwe. –

+0

@David Aldridge tabele nie są puste, jestem jedynym, który uruchamia ten kod. Czy istnieje lepsza metoda? –

6

Jedynym niezawodnym, szybkim i skalowalnym sposobem generowania unikalnych identyfikatorów jest używanie sekwencji.

Powód, dla którego "rozwiązanie" max() nie zadziała, to transakcja nie zobaczy niezatwierdzonych zmian z innej transakcji. Zatem dwie równoczesne transakcje mogą zakończyć się przy użyciu tej samej wartości dla max(), która z kolei wygeneruje zduplikowane wartości id.

Aby utworzyć wartości z sekwencji w Twoim przypadku, to oczywiście trzeba najpierw utworzyć sekwencję:

create sequence seq_b; 

następnie wykorzystać tę sekwencję w select:

insert into tableb 
    (colA, colb, colc, cold) 
select seq_b.nextval, 
     F2, 
     F3, 
     F4 
from tablea; 
+0

Dzięki za eksplantację i pomoc. –