在oracle中形成动态查询并执行

时间:2013-08-08 11:07:30

标签: oracle oracle10g

我想为drop创建一个动态查询并创建视图并执行它。

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:表达式类型错误

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

解决方案:

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

1 个答案:

答案 0 :(得分: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表中提取值。如果他们不是,那么,我不明白对订单的限制。