Вы близки - как заметил кто-то другой, вам нужно "EXECUTE IMMEDIATE" для инструкции. Вы должны учитывать:
Вместо того, чтобы создавать процедуру для этого, запустите ее как анонимный блок PL / SQL, чтобы у вас не было проблемы с попыткой отбросить выполняющуюся процедуру.
Добавьте тест для объектный тип TABLE и для этого случая измените оператор drop, чтобы включить каскадную опцию для обработки таблиц, которые являются «родителями» других таблиц через ограничения внешнего ключа. Помните, что вы, вероятно, будете создавать список курсоров в порядке, отличном от t учитывать зависимости, которые будут блокировать перетаскивание.
Кроме того, что касается зависимостей, вероятно, лучше всего сначала отбросить таблицы (добавьте DECODE в свой курсор, который присваивает меньшее числовое значение этому типу объекта, и порядок выбора курсора это значение). Если у вас есть объекты Oracle типа TYPE, которые используются в качестве типов столбцов в определении таблицы, таблица должна быть удалена первой.
Если вы используете Oracle Advanced Queuing, объекты, связанные с этим, ДОЛЖНЫ быть отброшены с помощью вызовов API пакета AQ. Хотя вы можете отбросить сгенерированные Oracle таблицы для поддержки очередей с помощью обычной DROP TABLE, вы окажетесь в положении «уловка 22», когда не сможете ни отбросить связанные очереди, ни добавить их обратно. По крайней мере, до версии 10g вы не могли t даже отбросить содержащую схему, не переводя базу данных в специальный режим, когда такая ситуация существует
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;
Если пользователю не сложно повторно применить разрешения, вероятно, проще просто удалить пользователя и воссоздать его.
То, что у вас есть, является хорошим началом.
Вот остальное:
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;
Создайте указанную выше функцию (автономную, чтобы DDL можно было вызывать через функцию) тогда вы можете просто:
select DROP_ALL_SCHEMA_OBJECTS from dual;
когда вы хотите отбросить все свои объекты, убедитесь, что вы не пытаетесь сбросить процесс, который вы выполняете (я не забочусь о процессах, поэтому у меня нет процедур или функций в списке object_type)
, если вы хотите удалить все, что вам нужно, анонимный блок
, но мне нужно было сделать это с помощью инструмента, который разрешал только ansi sql (не plsql), следовательно, сохраненную процедуру.
Наслаждайтесь.