2010-03-31 14 views
27

W ramach procesu budowania i rozwijania bazy danych próbuję utworzyć skrypt, który usunie wszystkie tabele i sekwencje dla użytkownika. Nie chcę odtwarzać użytkownika, ponieważ będzie to wymagało więcej uprawnień, niż jest to dozwolone.Zrzucanie wszystkich tabel/sekwencji użytkowników w Oracle

Mój skrypt tworzy procedurę upuszczania tabel/sekwencji, wykonuje procedurę, a następnie zrzuca procedurę. Ja uruchomieniu pliku z sqlplus:

drop.sql:


create or replace procedure drop_all_cdi_tables 
is 
cur integer; 
begin 
cur:= dbms_sql.OPEN_CURSOR(); 
for t in (select table_name from user_tables) loop 
execute immediate 'drop table ' ||t.table_name|| ' cascade constraints'; 
end loop; 
dbms_sql.close_cursor(cur); 

cur:= dbms_sql.OPEN_CURSOR(); 
for t in (select sequence_name from user_sequences) loop 
execute immediate 'drop sequence ' ||t.sequence_name; 
end loop; 
dbms_sql.close_cursor(cur); 
end; 
/
execute drop_all_cdi_tables; 
/
drop procedure drop_all_cdi_tables; 
/

Niestety, upuszczenie procedury powoduje problem. Wydaje się, że powoduje to wyścig, a procedura zostaje przerwana, zanim zostanie wykonana.
Np .:

 
SQL*Plus: Release 11.1.0.7.0 - Production on Tue Mar 30 18:45:42 2010 

Copyright (c) 1982, 2008, Oracle. All rights reserved. 


Connected to: 
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production 
With the Partitioning, OLAP, Data Mining and Real Application Testing options 


Procedure created. 


PL/SQL procedure successfully completed. 


Procedure created. 


Procedure dropped. 

drop procedure drop_all_user_tables 
* 
ERROR at line 1: 
ORA-04043: object DROP_ALL_USER_TABLES does not exist 


SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64 
With the Partitioning, OLAP, Data Mining and Real Application Testing options 

Wszelkie pomysły, w jaki sposób uzyskać tej pracy?

Odpowiedz

69

Jeśli nie zamierzając się na zachowaniu procedury przechowywanej, chciałbym użyć anonymous PLSQL block:

BEGIN 

    --Bye Sequences! 
    FOR i IN (SELECT us.sequence_name 
       FROM USER_SEQUENCES us) LOOP 
    EXECUTE IMMEDIATE 'drop sequence '|| i.sequence_name ||''; 
    END LOOP; 

    --Bye Tables! 
    FOR i IN (SELECT ut.table_name 
       FROM USER_TABLES ut) LOOP 
    EXECUTE IMMEDIATE 'drop table '|| i.table_name ||' CASCADE CONSTRAINTS '; 
    END LOOP; 

END; 
+0

+1 to. nie ma potrzeby tworzenia procedury –

+0

To robi lewę. Dziwne, musiałem dodać koniec/koniec skryptu, aby faktycznie wykonać anonimowy blok PLSQL.Jeśli później utworzymy niestandardowe zadanie MSBUILD w celu wykonania instrukcji w skrypcie - czy/spowoduje to problemy? – Ambience

+0

/mówi sqlplus, że twój blok PLSQL jest zrobiony, i przesyła go do bazy danych w celu przetworzenia. Więc jeśli twój MSBUILD używa sqlplus to będzie potrzebował /. –

2

Wygląda wiadomości przykładem błędu jest coraz błąd na drop_all_user_tables ale przykład dałeś jest dla drop_all_cdi_tables. Czy kod drop_all_user_tables wygląda inaczej?

Również masz wywołania dbms_sql, ale nie wydaje się, aby używać go do jakiejkolwiek analizy składniowej.

+0

Drop_all_cdi_tables jest tym samym kodem. Baza danych dbms_sql została zapożyczona z innego przykładu - jestem początkującym SQL P/L :) – Ambience

6

W przypadku instrukcji SQL średnik na końcu spowoduje wykonanie instrukcji. Przycisk/wykona poprzednią instrukcję. Jako takie, skończy linie

drop procedure drop_all_cdi_tables; 
/

spadnie procedurę, a następnie spróbuj upuścić go ponownie.

Jeśli spojrzysz na swoje wyniki, zobaczysz "PROCEDURE CREATED", następnie wykonasz, następnie "PROCEDURE CREATED" ponownie, gdy ponownie wykona ostatnią instrukcję (EXECUTE jest poleceniem SQL * Plus, a nie instrukcją, nie jest buforowany), a następnie "PROCEDURE DROPPED", a następnie próbuje (i nie powiedzie się), aby upuścić go po raz drugi.

PS. Zgadzam się z Dougmanem na nieparzyste połączenia DBMS_SQL.

0

Oprócz rozwiązania przedstawionego przez OMG Ponies, jeśli masz sekwencji ze spacjami, trzeba zwiększyć plsql trochę:

BEGIN 
    FOR i IN (SELECT sequence_name FROM user_sequences) 
    Loop 
     EXECUTE IMMEDIATE('"DROP SEQUENCE ' || user || '"."' || i.sequence_name || '"'); 
    End Loop; 
End; 
/
0

jakiegoś powodu rozwiązanie OMG Ponies dał błąd polecenia SQL” niepoprawnie zakończone "na PLSQL. Jeśli ktoś inny natknie się na ten sam problem, oto, w jaki sposób udało mi się usunąć wszystkie tabele w bieżącym schemacie.

DECLARE 
    table_name VARCHAR2(30); 
    CURSOR usertables IS SELECT * FROM user_tables WHERE table_name NOT LIKE 'BIN$%'; 
BEGIN 
    FOR i IN usertables 
    LOOP 
    EXECUTE IMMEDIATE 'drop table ' || i.table_name || ' cascade constraints'; 
    END LOOP; 
END; 
/

Kredyty: Snippler

0

Wystarczy uruchomić te dwa oświadczenia, a następnie uruchomić wszystkie wyniki:

select 'drop table ' || table_name || ';' from user_tables; 
select 'drop sequence ' || sequence_name || ';' from user_sequences; 
Powiązane problemy