• 締切済み

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; 初歩的な質問で申し訳ありませんが、下記につきアドバイスをお願いします。

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

みんなの回答

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

質問1について。 >2つのオーバーロードプロシージャのパラメータ数が異なるよう指定しているので、このエラーに関する原因を見つけれておりません。 とありますが、 >PROCEDURE SHOW_BIZDAYS( >v_start_date IN DATE := sysdate, >v_bus_days IN NUMBER := 30); と、v_bus_daysのデフォルト値を設定しているため、 >EXECUTE test.SHOW_BIZDAYS('20-NOV-13') この呼び出しは、EXECUTE test.SHOW_BIZDAYS('20-NOV-13', 30); と同じことになります。 ですので、デフォルト値の設定を消さなければいけません。

maple0823
質問者

補足

yamada_gさん 回答ありがとうございます。 この問題のインストラクションに『パラメータはそれぞれシステム日付と30をデフォルト値として設定すること』と 記載されているので、デフォルト値の設定を消す以外の解決策はないでしょうか?

  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.1

こんにちわ。 先ず、オーバーロードの件はパラメータをDATE 型に変換 していない事が原因です。 EXECUTE test.SHOW_BIZDAYS(TO_DATE('20-NOV-13', 'DD-MON-YY')) としてみて下さい。 次に、プロンプトの件ですがACCEPT はSQL*Plus のコマンドなので PL/SQL から使用する事はできません。 PL/SQL のパッケージにも、そのような機能は無いようですので SQL*Plus で処理させる事になると思います。

maple0823
質問者

補足

muyoshidさん 回答ありがとうございます。 1つ目のプロシージャをEXECUTE Lab5.SHOW_BIZDAYS('20-NOV-11', 30)で呼び出す際、 エラーが発生せず正常に処理されます。アドバイス頂いた通りTO_CHARを使用してみましたが、 結果は変わりませんでした。。 ACCEPTはEXECUTEの直前で処理するよう試してみようと思います。

関連するQ&A

  • 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 のループ

    あるセレクト文のパフォーマンスを測定するためにループで複数回実行し時間を測定したいのですが、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-プロシージャ

    プロシージャBはテスト実行のため、プロシージャAを真似て作成しています。 --最後のIF文で、プロシージャAかBのどちらかに走らせたいと思っています。 DECLARE --プロシージャA--------------------------------------- PROCEDURE A IS fno1 utl_file.file_type; dnm1 varchar(200) :='XXX'; fnm1 varchar2(200) :='BBB.txt'; CURSOR cu1 is select XYZ as ABC from CCC; BEGIN fno1 := utl_file.fopen(dnm1,fnm1,'w'); FOR CU1_REC1 in CU1 loop utl_file_put_line(fno1,' '|| CU1_REC1.XYZ END LOOP; utl_file.fclose(fno1); end; --プロシージャB------------------------------------- プロシージャAと似たような処理 --プロシージャAかBかを判定するIF文------------------------------ BEGIN IF CCC.ABC = '0'; THEN A; ELSE B; ENDIF; END; /

  • PL/SQLのエラーについて

    こんばんは。PL/SQLのエラーについて質問させて頂きます。 現在、Oracle8.1.7のデータベースを使用したオラクルのE-business Suiteという人事系システムで開発をしています。 そこで、SQL*Plusを使用してPL/SQLのパッケージをコンパイルしたところ、パッケージ仕様部も本体部もコンパイルのエラーは出なかったのですが、E-business SuiteにPL/SQLを設定し、動作させようとしたら、下記のようなエラーが発生しました。 -------------------------------------------------------------------- FDPSTP 内のOracleエラー 6550 原因: ORA-06550: 行 1、列 7: PLS-00221: 'ZT_TYOUHYOU_HENSEI_PKG'がプロシージャではないか、または未定義です。 ORA-06550: 行 1、列 7: PL/SQL: Statement ignored が原因で FDPSTP に失敗しました。 --------------------------------------------------------------------- また、作成したPL/SQLパッケージの仕様部は下記のとおりです。 -------------------------------------------------------------------- CREATE OR REPLACE PACKAGE APPS.ZT_TYOUHYOU_HENSEI_PKG AS FUNCTION get_henseihyo_kbn (i_grade IN VARCHAR2,o_hensei_kbn OUT VARCHAR2) RETURN NUMBER; <・・・・・中間部分は省略・・・・・> PROCEDURE main_shori (p_process_date IN VARCHAR2, p_location IN VARCHAR2); END ZT_TYOUHYOU_HENSEI_PKG; -------------------------------------------------------------------- 原因だと思われる心当たりの部分も探してみたのですが、このエラーの意味は何なのか、原因はどこにあるのか分かりません。 どなたかお判りの方、御回答よろしくお願い致します。

  • Oracle: PACKAGE BODY の分割

    業務用に10個以上作成したストアドプロシージャ/ファンクションをパッケージとしてまとめようとしています。保守性の観点から、PACKAGE BODY内の各ストアドを、以下のようなイメージで別々のファイルで管理したいと思っています。 が、PACKAGEとBODYの分割はできたものの、BODY内のストアドを別々にすると、エラーとなってしまいます。 そういうことはできないのでしょうか? [xxx_pkg.SQL] CREATE OR REPLACE PACKAGE xxx_pkg IS PROCEDURE procedure_a; PROCEDURE procedure_b; PROCEDURE procedure_c; END xxx_pkg; [xxx_pkg.procedure_a.SQL] PROCEDURE procedure_a IS -- aの処理 END procedure_a; [xxx_pkg.procedure_b.SQL] PROCEDURE procedure_b IS -- aの処理 END procedure_a; [xxx_pkg.procedure_c.SQL] PROCEDURE procedure_c IS -- aの処理 END procedure_c;

  • [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;

  • PL/SQLで変数へ値の代入

    PROCEDURE TEST(PI_ABC IN A_TABLE.A_CODE%TYPE) IS CURSOR CUR IS SELECT A_CODE FROM A_TABLE; BEGIN --抽出したデータを代入 FOR REC_CUR IN CUR LOOP PI_ABC := REC_CUR.A_CODE; END LOOP; 上記のコードを実行すると ORA-06502:数値または値のエラー PL/SQL: 文字列バッファが小さすぎます。 とエラーが出ます。 このプロシージャを呼び出す時にも同じテーブル同じ項目を渡しています。 同パッケージ内で同じ事をやっているのに特定のプロシージャだけ 上記のエラーが出てしまいます。 環境:Windows2003Server oracle9i

  • PL/SQLのプロシージャが動かない

    テキストファイル(test.txt)から文字列を一行ずつ読み込んでDBMS_OUTPUTで表示を最後の行まで繰り返すプロシージャを作りたいのですが、declareで実行する時は何の問題も出ないのにプロシージャを作ろうとするとエラーが発生します。 原因が理解できないのですが返答をお願いします。 create or replase procedure TXT_R as FH UTL_FILE.FILE_TYPE; V_LINE VARCHAR2(32767); BEGIN FH := UTL_FILE.FOPEN('DATA_PUMP_DIR','test.txt','R'); LOOP UTL_FILE.GET_LINE(FH,V_LINE); DBMS_OUTPUT.PUT_LINE(V_LINE); END LOOP; EXCEPTION WHEN NO_DATA_FOUND THEN UTL_FILE.FCLOSE(FH); END; 実行すると ORA-00905: キーワードがありません。 のエラ-が出ます

  • ストアドで別スキーマのテーブルを参照したい

    Oracleのストアドで以下のことを実行したいです。 1.aユーザのaテーブルにあるユーザ情報(=スキーマ名になっています)を取得 2.取得したユーザ情報(=スキーマ名)を元にスキーマ.テーブル名で  テーブルの情報を参照する 3.スキーマ.テーブル名で参照したテーブルの情報を元に  他のテーブルのデータを参照する 1については取得できたのですが、2以降を別ストアドで作成して スキーマ名を引き渡そうかと思ったのですが、実行すると 「表またはビューが存在しません」と表示されます。 実現できる方法をご教授ください。 CREATE OR REPLACE PROCEDURE del_datatbl(con_user IN VARCHAR2, del_date IN DATE) IS TYPE cur_typ IS REF CURSOR; v_inv_cursor cur_typ; -- Declare a cursor variable v_inv_query VARCHAR2(200); v_inv_num NUMBER; v_inv_cust VARCHAR2(20); v_inv_amt NUMBER; w_date DATE; BEGIN IF(del_date IS NULL) THEN w_date := ADD_MONTHS(SYSDATE,-18); ELSE w_date := del_date; END IF; v_inv_query := 'SELECT clm_mjres_MSEQ FROM ' || con_user || '.T_MNGJRES' || ' WHERE TO_CHAR(CLM_MJRES_DATE,'|| 'YYYY/MM/DD' || ') <= TO_CHAR(w_date,' || 'YYYY/MM/DD' || ')'; DBMS_OUTPUT.PUT(v_inv_query); OPEN v_inv_cursor FOR v_inv_query USING v_inv_num; LOOP FETCH v_inv_cursor INTO v_inv_num; DBMS_OUTPUT.PUT(v_inv_num); EXIT WHEN v_inv_cursor%NOTFOUND; END LOOP; CLOSE v_inv_cursor; END; . run show errors

  • PL/SQL 実行中のSID

    自作のストアドプロシージャのどの関数がいつ呼ばれたかを記録したいと思いました。 例えば FUNC_A という関数があって、その関数の先頭で、その関数を実行しているセッションのSIDと関数名を取得できないものでしょうか。 そのようなパッケージ DBMS_**** みたいなものがあって、下記のような感じで使えたらなあと考えています。 ------------------ FUNC_A IS sid NUMBER; funcName VARCHAR2(30); BEGIN SELECT DBMS_****.GET_EXECUTING_SID INTO sid FROM DUAL; SELECT DBMS_****.GET_CURRENT_FUNC INTO funcName FROM DUAL; ... (sid と funcName を現時刻とともに記録) END; ------------------ このような目的に合致したパッケージ、あるいはこの目的を実現する方法などありますでしょうか。 よろしくお願いします