2010-09-23 10 views
27

Podczas mojej pracy zazwyczaj muszę skopiować wiersze podczas zmiany klucza podstawowego i nadać im nowy znaczek, a może zmienić klucz obcy.Kopiowanie wiersza w tej samej tabeli bez konieczności wpisywania nazw kolumn 50+ (podczas zmiany 2 kolumn)

Problem polega na tym, że nie chcę wpisywać wszystkich nazw kolumn podczas wykonywania;

insert into table_name 
select pk_seq.nextval, 
     'foreign-key', 
     col3, 
     col4...col51 
    from table_name 
where pk_id = "original_primary_key" 

A jeśli robię * w SELECT i nie będzie w stanie zaktualizować pierwszych 2 kolumny ...

Czy istnieje jakiś sposób, aby zrobić jak chcę to zrobić?

Odpowiedz

40

No to nie może być o wiele mniej gadatliwy, ale PL/SQL jest opcja:

begin 
    for r in (select * 
       from table_name 
      where pk_id = 'original_primary_key') 
    loop 
    r.pk := pk_seq.nextval; 
    r.fk := 'foreign-key'; 
    insert into table_name values r; 
    end loop; 
end; 
+2

+1: niejawny kursor, nice! –

+0

Czy jest inny rodzaj? ;-) –

+6

+1 Nicea. Uwaga dla osób spoza Oracle 11g, wiersz 'r.pk: = pk_seq.nextval;' powinien zostać zamieniony przez 'wybierz pk_seq.nextval na r.pk z dual;' –

2

Przepraszam - to wszystko lub nic.
Nie ma nic pomiędzy SELECT * i lista konkretnych kolumn, to jedna lub druga.

0

Można zrobić prostą procedurę przechowywaną, które mają nazwę tabeli i przy użyciu słownika danych zapisuje select tekst dla ciebie (tekst zaznaczenia). Następnie skopiuj, wklej i zmodyfikuj.

15

podstawie Tony's answer:

Wiemy, że co najwyżej jednym rzędzie zostaną zwrócone, ponieważ szukamy na klucz podstawowy. Zakładając, że określona jest poprawna wartość klucza, zostanie zwrócony co najmniej jeden wiersz. Więc nie potrzebujemy pętli:

declare 
    r table_name%ROWTYPE; 
begin 
    select * 
    into r 
    from table_name 
    where pk_id = "original_primary_key"; 
-- 
    select pk_seq.nextval into r.pk_id from dual; 
    -- For 11g can use instead: r.pk_id := pk_seq.nextval; 
    r.fk_id := "new_foreign_key"; 
    insert into table_name values r; 
end; 
3

Można po prostu zapytać słownik danych, aby wygenerować SQL dla ciebie.

SELECT 'tbl.' || column_name || ',' 
FROM user_tab_columns 
WHERE table_name = 'MYTABLE' 
ORDER BY column_id; 

Uzyskaj wynik tego zapytania, wklej do instrukcji SQL, dostosuj w razie potrzeby i voila.

1

Można utworzyć tabelę "temp", zaktualizować dwie kolumny i wykonać wstawienie-wybrać z tabeli "Temp".

Eaxmple:

create table temptemp as 
select * 
    from table_name 
where pk_id = "original_primary_key" 

update temptemp 
set col1 = ... 
, col2 =.... 

insert into table2 
select * from temptemp; 
+0

Ta metoda jest pomocna w przypadku dużych zbiorów danych. Zużycie pamięci nie jest znaczące. –

Powiązane problemy