execute immediate
一次通话中不能有多个语句;你需要在循环内调用它:
for C in Cursor
LOOP
ViewName := 'View_'|| C.ID;
DropViewSQL := 'DROP VIEW ' || ViewName ;
CreateViewSQL := 'CREATE VIEW ' || ViewName || ' AS SELECT * from xyz';
DBMS_OUTPUT.PUT_LINE(DropViewSQL);
DBMS_OUTPUT.PUT_LINE(CreateViewSQL);
EXECUTE IMMEDIATE DropViewSQL;
EXECUTE IMMEDIATE CreateViewSQL;
END LOOP;
请注意,动态 SQL 语句末尾没有分号。您也可能不需要执行单独的drop
步骤;create or replace view
可能更合适,因为这保留了赠款。
如果没有关于“在删除和创建视图之前要执行的一些语句”部分的任何进一步信息,目前还不清楚这些语句适用于何处。
但这并不能解释 PLS-00382。你还没有展示什么Cursor
是,我怀疑它不喜欢那样。因为cursor
是一个保留字,你的(希望)不会被称为,但不知道它是先前声明的显式游标还是带有就地查询的隐式游标。无论哪种方式,您都需要展示那是什么以及它在做什么。如果没问题,那么您删除的其他语句之一可能会导致错误。如果没有所有相关代码和错误的行号,很难猜测。
如果您真的必须一起生成命令,那么在执行它们之前执行其他操作,您可以将它们存储在 PL/SQL 表中:
DECLARE
cursor cur is select view_name as id from user_views;
/* or whatever your real cursor is */
type sqltab is table of varchar2(200);
dropsqltab sqltab;
createsqltab sqltab;
viewname varchar2(30);
BEGIN
dropsqltab := sqltab();
createsqltab := sqltab();
for C in cur
LOOP
ViewName := 'View_'|| C.ID;
dropsqltab.extend();
dropsqltab(dropsqltab.count) := 'DROP VIEW ' || ViewName ;
createsqltab.extend();
createsqltab(createsqltab.count) := 'CREATE VIEW ' || ViewName
|| ' AS SELECT * from xyz';
END LOOP;
/* other commands */
FOR i IN 1 .. dropsqltab.count LOOP
DBMS_OUTPUT.PUT_LINE(dropsqltab(i));
DBMS_OUTPUT.PUT_LINE(createsqltab(i));
EXECUTE IMMEDIATE dropsqltab(i);
EXECUTE IMMEDIATE createsqltab(i);
END LOOP;
END;
/
您还没有说 drop/create 语句和 insert/update 语句之间有什么关系(如果有的话)。如果它们是相关的,您可以多次从 PL/SQL 表中提取值。如果不是,那么,我不明白对事情完成顺序的限制。