PL/SQLでVIEWをPROCEDURE内で使用する方法とは?

このQ&Aのポイント
  • PL/SQLの中でVIEWを使用する方法について解説します。
  • VIEWにパラメータを渡すことはできないため、代替案が必要です。
  • VIEWを動的に作成して処理する方法を考えましょう。
回答を見る
  • ベストアンサー

PL/SQLについて

以下のVIEWをPROCEDURE内で使用しています。 CREATE OR REPLACE VIEW VW_KAIIN (CODE,NAME,TEL,STARTYMD) AS SELECT * FROM KAIIN WHERE STARTYMD <= TO_CHAR(SYSDATE,'YYYYMMDD') ※STARTYMDには有効な開始日付が入ります。 条件部分でSYSDATEではまずいことになり、 特定の日付を指定しなければならなくなりました。 VIEW自体にパラメータ渡しはできないということで、 CREATE OR REPLACE PROCEDURE TABLE_B_UPDATE (I_YYYY IN TABLE_A.YYYYY%TYPE, I_MM IN TABLE_A.MM%TYPE, I_DD IN TABLE_A.DD%TYPE,) PROCEDURE内でI_YYYY、I_MM、I_DDを条件に変更した VIEWを動的に作成して、処理をしたいのですが、 こういった事は可能でしょうか? そのまま書いてみましたが、CREATE部分でエラーが出てしまい、コンパイルできませんでした。 もし不可能である場合は、代替案をご教授いただけるとありがたいです。 どうかよろしくお願いします。

  • Oracle
  • 回答数2
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.2

プロシージャ内でも動的SQLを使えばDDLの実行はできます。試してみてください。 set serveroutput on declare w_str varchar2(1000); begin --TABLE作成 execute immediate 'create table test_table(val varchar2(100))'; --データ投入 execute immediate 'insert into test_table values (:val)' using 'テスト'; --VIEW作成 execute immediate 'create view test_view as select * from test_table'; --VIEWからSELECT execute immediate 'select val from test_view' into w_str; --結果出力 dbms_output.put_line(w_str); --TABLE,VIEW削除 execute immediate 'drop table test_table purge'; execute immediate 'drop view test_view'; exception when others then raise; end; / set serveroutput off ただ、今回の質問はkouta77さんのおっしゃるとおりVIEW動的に作成する意味がよくわかりませんね。 やりたいこと、目的を明確にしてもらうと何かアドバイスできるかもしれません。

boooone
質問者

お礼

上記方法でやりたいことが作成できました。 VIEW作成以外もご紹介いただき感謝です。 ありがとうございました。

boooone
質問者

補足

元々、前任者が作っておったもので、 VIEW自体は、他のプログラムで呼び出したり、共通で使っているのは 間違いないと思います。 私自身、オラクルやPLSQLに触れるのが初めてなものですから、 VIEW自体でパラメータが使えたら一番よかったのですが。 プロシージャ内でVIEWの項目が基本軸として使用されており、 安易に、既存のVIEWのコピーを、プロシージャ内のパラメータを使用して、もうひとつ作ったら、いけるかなぁ、と思ってやってみたところ、ダメでしたので、質問させていただきました。 上記方法ためさせていただきます。 ありがとうございます。

その他の回答 (1)

  • kouta77
  • ベストアンサー率20% (185/896)
回答No.1

プロシージャ―内でCREATE文(DDL文)は記述できません。 そもそもVW_KAIINをどう使いたいのですか? いちいちVIEWにする必要はなくて、プロシージャ―内でデータをSELECTする時に条件文を付けるのでは 駄目なんですか? この質問文を見る限りではVIEWにする意図が分かりません。

boooone
質問者

補足

他のプロシージャや、プログラム内からも、共通で使いたいので、 VIEWにしております。 まだ、PLSQL自体、見始めて間もないもので、見当違いことを言ってたらすいません。

関連するQ&A

  • PL SQL のループ

    あるセレクト文のパフォーマンスを測定するためにループで複数回実行し時間を測定したいのですが、select 変数 into をしないとコンパイルできず実行できません。 同じセレクト文を複数回実行し時間を測定するのに良い方法は無いでしょうか? CREATE OR REPLACE PROCEDURE test IS BEGIN DBMS_OUTPUT.PUT_LINE(TO_CHAR(sysdate(),'YYYY/MM/DD HH24:MI:SS')); FOR i IN 1..100 LOOP SELECT a,b,c,d,e FROM tbl; END LOOP; DBMS_OUTPUT.PUT_LINE(TO_CHAR(sysdate(),'YYYY/MM/DD HH24:MI:SS')); END;

  • PL/SQLでエラー

    PL/SQLの使用方法を検討しており、下記のようにサンプルを作成しました。 //1. 宣言部 create or replace package Pac is procedure Pro1(p1 in varchar2); end; / パッケージが作成されました //2. 本体 create or replace package body Pac is procedure Pro1(p1 in varchar2) is tempdate DATE; begin select to_char(sysdate, 'yyyy/mm/dd') INTO tempdate from dual; DBMS_OUTPUT.PUT_LINE('引数は' || p1 || 'です。'); DBMS_OUTPUT.PUT_LINE('日付は' || tempdate || 'です。'); end; end; / パッケージ本体が作成されました //3. 実行 execute Pac.Pro1('a'); // エラー内容 行1でエラーが発生しました。: ORA-00900: invalid SQL statement SQLPlusより、上記の[1. 宣言部]でパッケージを作成し、[2. 本体]で本体部分を作成しました。 その後、[3. 実行]を実施しましたが、 エラーが出力されて実行されません。 何がいけないのかお気づきの点がございましたら、 よろしくお願いします。

  • PL/SQL パッケージでのプロンプト使用

    こんにちは。 独学でPL/SQLを学んでいるのですが、パッケージの使用でうまく処理が走らないので、 アドバイスを頂けたらと思い書き込みさせて頂くことにしました。 パッケージtestは、オーバーロードプロシージャSHOW_BIZDAYS(日付, 数値)とSHOW_BIZDAYS(日付)を含んでいます。パッケージコードは質問の下に書いております。 ■質問1 オーバーロードプロシージャSHOW_BIZDAYSの日付のみパラメータとする2つ目のプロシージャを EXECUTE test.SHOW_BIZDAYS('20-NOV-13') コマンドで実行したところ、『PLS-00307: このコールに一致する'string'が複数宣言されています。』というエラーが表示されてしまいます。 2つのオーバーロードプロシージャのパラメータ数が異なるよう指定しているので、このエラーに関する原因を見つけれておりません。 ■質問2: SHOW_BIZDAYS(日付)において、ユーザーに数値を入力するようプロンプトをしたいのですが、 PROCEDURE SHOW_BIZDAYS( v_start_date IN DATE := sysdate) IS ACCEPT tdays PROMPT 'Enter how many days are needed: ' v_bus_days NUMBER := &tdays; と記載するとACCEPT文が無効とのエラーが検出されます。パッケージ内ではACCEPTが使用できないということでしょうか。 ■パッケージ create or replace PACKAGE test IS PROCEDURE SHOW_BIZDAYS( v_start_date IN DATE := sysdate, v_bus_days IN NUMBER := 30); PROCEDURE SHOW_BIZDAYS( v_start_date IN DATE := sysdate); END test; ■パッケージ本体 create or replace PACKAGE BODY test IS PROCEDURE SHOW_BIZDAYS( v_start_date IN DATE := sysdate, v_bus_days IN NUMBER := 30) IS v_counter NUMBER(3) := 1; v_date DATE := v_start_date; BEGIN WHILE v_counter <= v_bus_days LOOP IF UPPER(TO_CHAR(v_date, 'D')) NOT IN (1, 7) THEN DBMS_OUTPUT.PUT_LINE('The index is : ' || v_counter || ' and the table value is: ' || v_date); v_counter := v_counter + 1; END IF; v_date := v_date + 1; END LOOP; END SHOW_BIZDAYS; PROCEDURE SHOW_BIZDAYS( v_start_date IN DATE := sysdate) IS ACCEPT tdays PROMPT 'Enter how many days are needed : '; v_bus_days NUMBER := &tdays; v_counter NUMBER(3) := 1; v_date DATE := v_start_date; BEGIN WHILE v_counter <= v_bus_days LOOP IF UPPER(TO_CHAR(v_date, 'D')) NOT IN (1, 7) THEN DBMS_OUTPUT.PUT_LINE('The index is : ' || v_counter || ' and the table value is: ' || v_date); v_counter := v_counter + 1; END IF; v_date := v_date + 1; END LOOP; END SHOW_BIZDAYS; END test; 初歩的な質問で申し訳ありませんが、下記につきアドバイスをお願いします。

  • 日付に関するSQL分で

    wonddows2000,Access2000 VBAで勤怠管理をしたいのですが日付に関するSQL分でDATEDIFFの使い方が今ひとつわかりません。 SELECT * ,DATEDIFF(day,入室日,退室日)  FROM TABLE WHERE 部署コード=700  WHERE後部分はどう表現したらいいでしょうか。 検査条件(1) 入室日(YYYY/MM/DD)=退室日(YYYY/MM/DD) 且つ入室時間(hh:mm:ss)が09:00:00より後且つ 入室日(YYYY/MM/DD)=退室日(YYYY/MM/DD)+1 且つ退室時間(hh:mm:ss)が09:00:00より前且つ 部署コードが700に対応するテーブルの全データを出力 検査条件(2)上記以外の全データ TABLE (文字型)  (文字型) (日付型) (日付型) (日付型) (日付型) 部署コード | 氏名  | 入室日  |入室時間 | 退室日  | 退室時間 | 1000 A 2000/12/01 8:16:30 2000/12/01 18:10:20 2000 B 2000/12/02 8:16:30 2000/12/03 8:10:20 700 C 2000/12/03 9:16:30 2000/12/03 18:10:20 3000 A 2000/12/04 8:16:30 2000/12/01 18:10:20 700 D 2000/12/04 8:16:30 2000/12/05 8:10:20 700 E 2000/12/04 8:16:30 2000/12/04 18:10:20 結果(1) 700 C 2000/12/03 9:16:30 2000/12/03 18:10:20 700 D 2000/12/04 8:16:30 2000/12/05 8:10:20 結果(2) 1000 A 2000/12/01 8:16:30 2000/12/01 18:10:20 2000 B 2000/12/02 8:16:30 2000/12/03 8:10:20 3000 A 2000/12/04 8:16:30 2000/12/01 18:10:20 700 E 2000/12/04 8:16:30 2000/12/04 18:10:20

  • PL/SQLのカーソルについて

    PL/SQLのカーソルについて お世話になります。 Oracle11gで開発しています。 初心者です。 下記ストアドプロシージャの「zokuseisyutoku」で取得した 値(入数、重量、才数、ロケーション)を受けて、別のストアドプロシージャ 「Hyouji」の変数(irisuu、jyuryou、saisuu、lokesyon)に代入して得られた 内容をGridviewに表示させたいと思っています。 現在は、別々のストアドプロシージャなのですが、 一つに出来るものなら一つのストアドプロシージャにまとめたいの ですが、どなたかご親切な方、ご教授頂きたく宜しくお願い致します。        記 (1)ストアドプロシージャ1つ目 create or replace procedure zokuseisyutoku ( sItemClass in コード表.品番%type, out_val out pls_integer, out_cursor out sys_refcursor ) as begin if sItemClass is null then open out_cursor for select 入数, 重量, 才数, ロケーション from コード表 ; else open out_cursor for select 入数, 重量, 才数, ロケーション from コード表 where 品番 = sItemClass ; end if; out_val := 1; (2)ストアドプロシージャ2つ目 create or replace procedure Hyouji ( irisuu in 部材表.入数%type, jyuryou in 部材表.重量%type, saisuu in 部材表.才数%type, lokesyon in 部材表.ロケーション%type, out_val out pls_integer, out_cursor out sys_refcursor ) as begin open out_cursor for select b.資材名,b.色,b.種類,b.サイズ,b.棚番号 FROM 部材表 a,資材項目 b WHERE a.ID = b.資材ID AND a.入数 = irisuu AND a.重量 = jyuryou AND a.才数 = saisuu AND ロケーション = lokesyon ; out_val := 1; end; end;

  • [PL/SQL]REFCURSORが戻り値のプロシージャについて

    [PL/SQL]REFCURSORが戻り値のプロシージャについて お世話になってます タイトルの内容について、親プロシージャより引数を受け取り 子プロシージャでカーソルをオープンして、そのカーソルを親に戻す。 というプロシージャなのですが、親から実行した場合には問題ないのですが 子をSI ObjectBrowserから実行すると[実行][デバッグ]共に 押した瞬間に止まってしまいます。 下記にソースを記述します --カーソル変数の定義 CREATE OR REPLACE PACKAGE LC7BDEV.PKG_TEST_CURSOR IS  TYPE TEST_TYPE IS RECORD  (COL1 TABLE1.COL1%TYPE ,   COL2 TABLE1.COL2%TYPE ); TYPE CUR_TEST IS REF CURSOR RETURN TEST_TYPE; END; --親プロシージャ CREATE OR REPLACE PROCEDURE PD_TEST  (   in_COL_KEY IN TABLE1.COL_KEY%TYPE  ) IS  TEST_REC  PKG_TEST_CURSOR.CUR_TEST;  TEMP_COL1 TABLE1.COL1%TYPE;  TEMP_COL2  TABLE1.COL1%TYPE; BEGIN  PD_TEST_KO(in_COL_KEY,TEST_REC);  loop   fetch TEST_REC into TEMP_COL1,TEMP_COL2;   exit when TEST_REC%notfound;   dbms_output.put_line(TEMP_COL1 || ',' || TEMP_COL2);  end loop;    close TEST_REC; END; --子プロシージャ CREATE OR REPLACE PROCEDURE PD_TEST_KO  (   in_COL_KEY  IN  TABLE1.COL_KEY%TYPE ,   in_TEST_REC OUT PKG_TEST_CURSOR.CUR_TEST ,  ) IS BEGIN  OPEN in_TEST_REC FOR   SELECT COL1,COL2   FROM TABLE1   WHERE COL_KEY = in_COL_KEY END;

  • Oracle9i プロシージャ内でのIF文の書き方について

    Oracle9iでプロシージャを作成しています。 テーブルの型はCHAR(10)で、 日付のデータ'YYYY/MM/DD'が入っているカラムがあります。 このMM/DDの部分が04/21~12/20なら○○○、 12/21~04/20なら△△△ というIF文を作りたいのですが、 どうしても思いつかなくて途方に暮れています。 どなたかアイデアがあれば教えてください。

  • oracle sqlについて

    お世話になります。 Oracle Sqlでの質問を致します。 Oracleのデータで重複データを削除したく 下記の構文を書いたのですが、 右括弧がありませんと言うエラーが出てしまいます。 見た目括弧はちゃんとあると思うのですが、 どこが悪いのか分かりません。 ご親切な方、ご教示くださいます様、 宜しくお願いいたします。          記 DELETE FROM D入庫データ WHERE ID NOT IN ( SELECT MIN(ID) FROM D入庫データ GROUP BY PPID,台車番号,入庫数量,ロット番号,TO_CHAR(登録日時,'yyyy,mm,dd') WHERE TO_CHAR(SYSDATE,'yyyy/mm/dd)=TO_CHAR(登録日時,'yyyy/mm/dd') );

  • PL/SQLのパフォーマンスについて

    PL/SQLで、元のプログラムから、部品プログラム(以下のTEST_BUHIN)を呼ぶ際の、 パフォーマンスについてお聞きしたいことがあります。 Oracle8i環境を使っています。 以下の2つをコンパイルすると考えてください。 -------------------------------------------------- CREATE OR REPLACE TYPE test_type as object (  COL1 NUMBER(11),  COL2 VARCHAR2(20),    (実際には、40項目くらいあります)   ); / -------------------------------------------------- CREATE OR REPLACE PACKAGE BODY TEST_BUHIN AS  PROCEDURE TESTINSERT(TESTDATA IN test_type)  AS  BEGIN   INSERT INTO TESTTABLE VALUES(    TESTDATA.COL1,TESTDATA.COL2, ・・・    (以下略) -------------------------------------------------- 今、TESTTABLEにINSERTするプログラムを作成したいのですが、 パフォーマンスを最優先に考えたいと思っています。 その場合、元のプログラム内にINSERT文を作るべきか、 部品(TEST_BUHIN)を使用すべきか迷っています。 パフォーマンスがほぼ同じであれば、部品(TEST_BUHIN)を使用したいと思っています。 部品を使うとパフォーマンスが極端に落ちるということであれば、 部品はコンパイルせずに、元のプログラム内にINSERT文を作成しようと思います。 オブジェクトタイプ型変数を引数として渡した場合、 パフォーマンスへの影響はあるのでしょうか? 自分でも調べてみたのですが、いまいち分かりませんでした。 あと、大きな引数を渡した場合に、メモリをたくさん使ってしまうのかどうかも気になります。 文章が分かりづらいと思いますので、みなさんのご意見などを見て補足させていただきます。 Oracle、PL/SQLに詳しい方、よろしくお願いいたします。

  • 指定日の?日 前後の求め方

    OS:windows2000pro VB:VB6.0sp5 1.システム日付(sysdate)から、xx 日後は、yy です 2.システム日付(sysdate)から、xx 日前は、yy です  ただし、sysdate,yy は[YYYY/MM/DD]      xx は3桁とする この場合の処理方法をご教示くださいますよう お願いいたします