2010-03-31 36 views
27

Là một phần của quá trình xây dựng và phát triển cơ sở dữ liệu của chúng tôi, tôi đang cố tạo một tập lệnh sẽ xóa tất cả các bảng và trình tự cho người dùng. Tôi không muốn tạo lại người dùng vì điều này sẽ yêu cầu nhiều quyền hơn mức cho phép.Thả tất cả các bảng/chuỗi người dùng trong Oracle

Tập lệnh của tôi tạo một quy trình để xóa các bảng/trình tự, thực thi quy trình và sau đó giảm quy trình. Tôi đang thực hiện các tập tin từ 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; 
/

Thật không may, giảm các thủ tục gây ra một vấn đề. Dường như gây ra một tình trạng chủng tộc và thủ tục bị bỏ trước khi nó thực thi.
Ví dụ:

 
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 

Mọi ý tưởng về cách làm việc này?

Trả lời

69

Nếu bạn không có ý định vào việc giữ các thủ tục lưu trữ, tôi muốn sử dụng một 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 này. không cần phải tạo thủ tục –

+0

Điều này thực hiện thủ thuật. Thật kỳ lạ, tôi đã phải thêm một dấu/ở cuối kịch bản để thực sự thực thi khối PLSQL ẩn danh.Nếu sau này chúng ta tạo một nhiệm vụ MSBUILD tùy chỉnh để thực hiện các câu lệnh trong tập lệnh - thì các vấn đề/có gây ra không? – Ambience

+0

/nói với sqlplus rằng khối PLSQL của bạn được thực hiện và gửi nó đến cơ sở dữ liệu để xử lý. Vì vậy, nếu MSBUILD của bạn sử dụng sqlplus, nó sẽ cần /. –

2

Dường như nhắn dụ lỗi của bạn là nhận được một lỗi trên drop_all_user_tables nhưng ví dụ bạn đưa ra là dành cho drop_all_cdi_tables. Mã số drop_all_user_tables có khác nhau không?

Ngoài ra, bạn có cuộc gọi đến dbms_sql nhưng dường như không sử dụng tính năng này để thực hiện phân tích cú pháp.

+0

Các drop_all_cdi_tables là cùng một mã. Các dbms_sql đã được mượn từ một ví dụ khác - Tôi là một người mới sử dụng SQL P/L :) – Ambience

6

Đối với một câu lệnh SQL, dấu chấm phẩy ở cuối sẽ thực hiện câu lệnh. /sẽ thực thi câu lệnh trước. Như vậy, bạn kết thúc các dòng của

drop procedure drop_all_cdi_tables; 
/

sẽ thả quy trình, sau đó thử thả lại.

Nếu bạn nhìn vào đầu ra của mình, bạn sẽ thấy 'PROCEDURE CREATED', sau đó được thực thi, sau đó 'PROCEDURE CREATED' một lần nữa khi nó thực thi câu lệnh cuối cùng (EXECUTE là lệnh SQL * Plus, chứ không phải là câu lệnh không được buffered) sau đó "PROCEDURE DROPPED" và sau đó nó cố gắng (và thất bại) để thả nó lần thứ hai.

PS. Tôi đồng ý với Dougman về các cuộc gọi DBMS_SQL lẻ.

0

Bên cạnh những giải pháp được trình bày bởi OMG Ngựa Non, nếu bạn có trình tự với các không gian trống, bạn cần phải nâng cao PLSQL một chút:

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

Đối với một số lý do OMG Ngựa Non giải pháp đưa ra một thông báo lỗi "SQL lệnh không kết thúc đúng "trên PLSQL. Trong trường hợp người khác gặp phải vấn đề tương tự, dưới đây là cách tôi có thể xóa tất cả các bảng trong lược đồ hiện tại.

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; 
/

Điểm Uy Tín: Snippler

0

Chỉ cần chạy hai báo cáo và sau đó chạy tất cả các kết quả:

select 'drop table ' || table_name || ';' from user_tables; 
select 'drop sequence ' || sequence_name || ';' from user_sequences; 
Các vấn đề liên quan