0

我想为 drop 和 create view 形成一个动态查询并执行它。

for C in Cursor  
LOOP 
ViewName :='View_'|| ID; 
DropViewSQL := DropViewSQL || 'DROP VIEW '||ViewName ||';' ; 
CreateViewSQL := CreateViewSQL || 'CREATE VIEW '|| ViewName ||' AS SELECT * from xyz;';                    
END LOOP; 

//在删除和创建视图之前要执行的一些插入和更新语句基本上我想在这些插入和更新语句之后创建一个新视图

DBMS_OUTPUT.PUT_LINE(DropViewSQL);
DBMS_OUTPUT.PUT_LINE(CreateViewSQL);

EXECUTE IMMEDIATE DropViewSQL;
EXECUTE IMMEDIATE CreateViewSQL;

这会产生错误 - PLS-00382:表达式类型错误

我想执行这个动态形成的查询。

解决方案:

我使用数组而不是游标来存储结果集。执行插入更新,然后在数组上循环。谢谢你的建议。。

4

1 回答 1

1

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 表中提取值。如果不是,那么,我不明白对事情完成顺序的限制。

于 2013-08-08T11:22:58.100 回答