0

ビューをドロップして作成し、それを実行するための動的クエリを作成したいと考えています。

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 immediate1 回の呼び出しで複数のステートメントを使用することはできません。ループ内でそれを呼び出す必要があります:

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、(うまくいけば)それは呼び出されませんが、それが以前に宣言された明示的なカーソルなのか、ここにクエリが配置された暗黙のカーソルなのかはわかりません。いずれにせよ、それが何であり、何をしているのかを示す必要があります。それで問題ない場合は、削除した他のステートメントの 1 つがエラーの原因である可能性があります。関連するすべてのコードとエラーの行番号がなければ、推測するのは困難です。


コマンドを一緒に生成する必要があり、それらを実行する前に別のことを行う必要がある場合は、それらを 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 に答える