2009-05-09 8 views
17

Tôi đang cố gắng sử dụng một thủ tục (không có tham số) để thả tất cả các đối tượng cơ sở dữ liệu do người dùng tạo trong sơ đồ từ nơi thủ tục được khởi chạy. không chắc chắn về cách đi về điều này. Đây là những gì tôi có cho đến nay, nhưng tôi nghĩ rằng tôi đang đi về điều này một cách sai lầm.PLSQL - Thả tất cả các đối tượng cơ sở dữ liệu của người dùng

 

create or replace procedure CLEAN_SCHEMA is 
cursor schema_cur is 
select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS;',';') 
from user_objects; 
schema_rec schema_cur%rowtype; 
begin 
select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS;',';') 
into schema_rec 
from user_objects; 
end; 
/
 
+0

Oops !!! Bạn không tự bắn mình à? CLEAN_SCHEMA có thể được chọn trong con trỏ để xóa. – Guru

Trả lời

2

Trừ khi người dùng khó đăng ký lại quyền, có thể dễ dàng hơn khi bỏ người dùng và tạo lại chúng.

+0

Việc bỏ người dùng không phải là một tùy chọn ngay bây giờ. – NMan

1

Điều bạn đã có là một khởi đầu tốt.

Dưới đây là phần còn lại:

  • Bạn có một con trỏ VÀ một tuyên bố chọn. Bạn chỉ cần con trỏ.
  • Bước tiếp theo của bạn là gọi câu lệnh thả bằng cách sử dụng PLSQL động. Tôi muốn sử dụng câu lệnh EXECUTE IMMEDIATE. Của nó thanh lịch hơn và preformance thân thiện để chỉ cần chọn tên của điều bạn đang rơi và gửi nó như là một biến ràng buộc để thực hiện IMMEDIATE.
  • Để thả các đối tượng của giản đồ gọi phương thức chứ không phải lược đồ sở hữu phương pháp bạn phải sử dụng "AUTHID CURRENT_USER". Xem the Oracle documentation để biết thêm thông tin.
  • Những điều khác để thả: bao bì, chức năng, thủ tục (hệ thống có khả năng sẽ treo thì thời gian chờ nếu bạn cố gắng thả phương pháp này trong khi nó đang chạy), các lớp Java, gây nên, quan điểm, các loại

Cuối cùng, điều này rõ ràng là một phương pháp rất nguy hiểm, do đó bạn có thể muốn xem xét việc đặt nó trong một kịch bản thay vì một thủ tục được lưu trữ để nó không còn trong cơ sở dữ liệu cho bất cứ ai chạy.

1

Bạn thân thiết - như một người nào khác đã lưu ý rằng bạn cần một "NGAY LẬP TỨC THỰC HIỆN" cho tuyên bố. Bạn nên cân nhắc:

  • Thay vì tạo ra một thủ tục để thực hiện điều này, hãy chạy này như là một khối ẩn danh PL/SQL, do đó bạn không có vấn đề cố gắng để thả một thủ tục đang chạy.

  • Thêm thử nghiệm cho loại đối tượng TABLE và trường hợp đó sửa đổi lệnh thả để bao gồm tùy chọn xếp tầng để xử lý các bảng là "cha mẹ" của các bảng khác thông qua các ràng buộc khóa ngoài. Hãy nhớ rằng bạn có thể sẽ tạo danh sách con trỏ theo thứ tự không xem xét các phụ thuộc sẽ chặn thả. Ngoài ra, đối với chủ đề phụ thuộc, tốt nhất nên bỏ bảng đầu tiên (thêm DECODE vào con trỏ gán giá trị số thấp hơn cho loại đối tượng này và đặt con trỏ theo giá trị này). Nếu bạn có đối tượng Oracle kiểu TYPE được sử dụng làm kiểu cột trong định nghĩa bảng thì bảng phải được loại bỏ trước tiên.

  • Nếu bạn sử dụng Oracle Advanced Queuing, các đối tượng liên quan đến PHẢI bị loại bỏ này với các cuộc gọi API gói AQ. Mặc dù bạn có thể thả các bảng do Oracle tạo ra để hỗ trợ hàng đợi bằng một DROP TABLE thông thường, bạn sẽ thấy mình ở vị trí bắt-22 sau đó không thể thả các hàng đợi liên quan cũng như không thêm chúng trở lại.Tính đến phiên bản 10g ít nhất bạn có thể thậm chí không thả các schema chứa mà không đặt cơ sở dữ liệu trong một chế độ đặc biệt khi tình trạng này tồn tại

13
declare 
    cursor ix is 
    select * 
     from user_objects 
    where object_type in ('TABLE', 'VIEW', 'FUNCTION', 'SEQUENCE'); 
begin 
for x in ix loop 
    execute immediate('drop '||x.object_type||' '||x.object_name); 
end loop; 
end; 
+0

này làm việc cho tôi – Ewerton

+0

rror báo cáo: ORA-00.933: lệnh SQL không đúng cách kết thúc ORA-06.512: tại dòng 8 00933. 00000 - "SQL lệnh không đúng cách kết thúc" – Suyash

+0

Chỉ cần một nhận xét: Để làm cho nó làm việc với Loại 'JAVA SOURCE', người ta phải báo giá kép object_name, vì chúng có thể chứa các ký tự đặc biệt cần trích dẫn (ví dụ:/2bbec77c_JsonEncoding). Bên cạnh sửa đổi nhỏ (nhưng cần thiết) này, nó hoạt động rất tốt. Cảm ơn! – ddevienne

18
create or replace 
FUNCTION    DROP_ALL_SCHEMA_OBJECTS RETURN NUMBER AS 
PRAGMA AUTONOMOUS_TRANSACTION; 
cursor c_get_objects is 
    select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name 
    from user_objects 
    where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM', 'MATERIALIZED VIEW') 
    order by object_type; 
cursor c_get_objects_type is 
    select object_type, '"'||object_name||'"' obj_name 
    from user_objects 
    where object_type in ('TYPE'); 
BEGIN 
    begin 
    for object_rec in c_get_objects loop 
     execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name); 
    end loop; 
    for object_rec in c_get_objects_type loop 
     begin 
     execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name); 
     end; 
    end loop; 
    end; 
    RETURN 0; 
END DROP_ALL_SCHEMA_OBJECTS; 

Tạo chức năng trên (tự trị nên DDL có thể gọi thông qua một chức năng) sau đó bạn có thể chỉ:

select DROP_ALL_SCHEMA_OBJECTS from dual; 

khi bạn muốn thả tất cả các đối tượng của bạn, hãy chắc chắn bạn không cố gắng thả các proc chạy của bạn (tôi không chăm sóc về proc s Đó là lý do tôi không có procs hoặc các chức năng trong danh sách object_type)

nếu bạn muốn thả tất cả mọi thứ bạn cần một khối ẩn danh

nhưng tôi cần để có thể làm điều này từ một công cụ mà chỉ được phép ansi sql (not plsql) do đó một proc được lưu trữ.

Tận hưởng.

+0

Hoạt động tốt - được thực hiện tốt. –

+0

Tôi đã tìm hiểu về cách xóa ** một ** chức năng. Tôi sẽ chỉ lặp lại những gì tôi đã học được vì không ai nói cách xóa bỏ hoạt động. 'thực hiện ngay lập tức (chuỗi)' ví dụ 'thực hiện ngay lập tức ('hàm thả myStupidFunction')' ~ kiểm tra dấu cách. – Bitterblue

2

Cảm ơn Martin Brambley,

Tôi cảm thấy chúng tôi có thể đơn giản hóa câu trả lời của bạn theo cách sau.

CREATE OR REPLACE 
procedure DROP_ALL_SCHEMA_OBJECTS AS 
PRAGMA AUTONOMOUS_TRANSACTION; 
cursor c_get_objects is 
    select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name 
    FROM USER_OBJECTS 
    where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM', 'MATERIALIZED VIEW', 'TYPE') 
    order by object_type; 
BEGIN 
    begin 
    for object_rec in c_get_objects loop 
     execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name); 
    end loop; 
    end; 
END DROP_ALL_SCHEMA_OBJECTS; 

/

execute DROP_ALL_SCHEMA_OBJECTS; 
1

Cảm ơn Martin BrambleyVijayan Srinivasan!

phiên bản

Nhưng Vijayan Srinivasan là không đúng, bởi vì đối tượng phụ thuộc của loại 'TYPE' đôi khi tạo ra sai sót trong quá thả chúng:

ORA-02.303: không thể thả hoặc thay thế một loại với loại hoặc bảng phụ thuộc

phiên bản My thả TẤT CẢ các đối tượng từ Schema với thêm:

  • thủ tục thả và chức năng (mong đợi 'DROP_ALL_SCHEMA_OBJECTS')
  • thả tất cả các công ăn việc làm và dbms_jobs
  • thả tất cả db_links
  • không thả các bảng lồng nhau, vì droping các bảng lồng nhau không được hỗ trợ
 
CREATE OR REPLACE 
procedure DROP_ALL_SCHEMA_OBJECTS AS 
PRAGMA AUTONOMOUS_TRANSACTION; 
cursor c_get_objects is 
    select uo.object_type object_type_2,'"'||uo.object_name||'"'||decode(uo.object_type,'TABLE' ,' cascade constraints',null) obj_name2 
    FROM USER_OBJECTS uo 
    where uo.object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM', 'MATERIALIZED VIEW', 'FUNCTION', 'PROCEDURE') 
     and not (uo.object_type = 'TABLE' and exists (select 1 from user_nested_tables unt where uo.object_name = unt.table_name)) 
     and not (uo.object_type = 'PROCEDURE' and uo.object_name = 'DROP_ALL_SCHEMA_OBJECTS') 
    order by uo.object_type; 
cursor c_get_objects_type is 
    select object_type, '"'||object_name||'"' obj_name 
    from user_objects 
    where object_type in ('TYPE'); 
cursor c_get_dblinks is 
    select '"'||db_link||'"' obj_name 
    from user_db_links; 
cursor c_get_jobs is 
    select '"'||object_name||'"' obj_name 
    from user_objects 
    where object_type = 'JOB'; 
cursor c_get_dbms_jobs is 
    select job obj_number_id 
    from user_jobs 
    where schema_user != 'SYSMAN'; 
BEGIN 
    begin 
    for object_rec in c_get_objects loop 
     execute immediate ('drop '||object_rec.object_type_2||' ' ||object_rec.obj_name2); 
    end loop; 
    for object_rec in c_get_objects_type loop 
     begin 
     execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name); 
     end; 
    end loop; 
    for object_rec in c_get_dblinks loop 
     execute immediate ('drop database link '||object_rec.obj_name); 
    end loop; 
    for object_rec in c_get_jobs loop 
     DBMS_SCHEDULER.DROP_JOB(job_name => object_rec.obj_name); 
    end loop; 
    commit; 
    for object_rec in c_get_dbms_jobs loop 
     dbms_job.remove(object_rec.obj_number_id); 
    end loop; 
    commit; 
    end; 
END DROP_ALL_SCHEMA_OBJECTS; 

/

execute DROP_ALL_SCHEMA_OBJECTS; 
drop procedure DROP_ALL_SCHEMA_OBJECTS; 

exit;