• 締切済み

【PL/SQL】IF文( EXIT WHEN )でプロシージャの実行結果から判断させたい

Oracleで動くPL/SQLを作成してます。 プロシージャの実行結果をIF文に入れて、 実行結果からさらに処理を走らせたいのですが エラーが出てしまいます。 例) CREATE PROCEDURE TEST1(id NUMBER) BEGIN select NAME from TBLA where DID = id and ROWNUM <= 1; END; CREATE PROCEDURE TEST2(id NUMBER) BEGIN LOOP EXIT WHEN ( TEST1(id) is not null );☆ここがうまくいかない。 id := id + 1; END LOOP; END; TEST2のCreate時にTEST1は関数として存在しないというエラーメッセージが表示されます。 IF(EXIT WHEN)文中からはずして TEST1(id)のみの実行では、エラーが起きず IF文に入れるとエラーが起きるところまでは分かりました。 例はかなり簡略しているのですが、 どうしたらうまく動くのか分かる方がいれば 教えてもらいたいです。

noname#245798
noname#245798
  • Oracle
  • 回答数2
  • ありがとう数2

みんなの回答

回答No.2

引数に"OUT"を付けることで対応可能 ---- CREATE OR REPLACE PROCEDURE TEST1(   id IN NUMBER,   NAME1 OUT VARCHAR2,--型は適当、実装にあわせて変更して   TYPE1 OUT VARCHAR2 )IS -- ↑これ BEGIN   SELECT NAME,TYPE INTO NAME1,TYPE1 FROM TBLA WHERE DID = id AND ROWNUM <= 1; END; / で、TEST1をこう呼ぶ CREATE OR REPLACE PROCEDURE TEST2(id IN NUMBER) IS   vNAME VARCHAR2(100);--これも適当なんで   vTYPE VARCHAR2(100); BEGIN   LOOP     TEST1(id,vNAME,vTYPE);--これ     EXIT WHEN ( vTYPE is not null );     id := id + 1;   END LOOP; END; /

回答No.1

そのエラーメッセージの通りです。 PROCEDUREは関数ではありません。関数はFUNCTIONで作ります。

noname#245798
質問者

補足

反応ありがとうございます。 例が悪かったので補足します。 プロシージャTEST1では複数の項目の値を返します。 ( select NAME,TYPE into NAME1, TYPE1 from TBLA where DID = id and ROWNUM <= 1;) FUNTIONでは1個の値しか返さないという理解なので PROCEDUREで作ろうとしています。 こういう場合の決まり文法などがあるようでしたら ご教授いただけないでしょうか?

関連するQ&A

  • 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: キーワードがありません。 のエラ-が出ます

  • 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]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 ストアドプロシージャが実行できません

    はじめまして、ほんの最近プログラムの世界に入ったキグと申します。 2週間、インターネットや参考書(ポケットリファレンス、PL/SQL入門)などで調べていたのですが分かりませんでしたので質問させていただきます。 ORACLE11gパーソナルエディションでやっています。 (CSEで作成実行しました。) **************************** 作ったSQL文 CREATE OR REPLACE PROCEDURE PRO_1 IS BEGIN (実行確認できたSELECT文) END ※試してみたこと、 SELECT文の列指定はアスタを使わずに書きました。 AUTHID CURRENT_USERをプロシージャ作成のときに入れてみました。  **************************** EXEC PRO_1 エラー→構文エラーまたはアクセス違反です。 BEGIN PRO_1; END; エラー→オブジェクト'PRO_1'が無効です。 上記エラーが出まして実行できていない状態です。 解決方法が分かる方いらっしゃいましたら、ぜひ回答を お願いしたいです。 以上よろしくお願い申し上げます。

  • プロシージャが実行されたかの有無の判断

    Sub test() ・・・・・ IF ・・・・ then Call マクロ1 End If ・・・・・ ・・・・・ If testと言う名のプロシージャーの中でマクロ1と言うプロシージャーが実行されたなら Then MsgBox "マクロ1は実行されました" End If End Sub ということを実行したいのですがどうすればいいのでしょうか? マクロ1の実行条件自体が複雑でIf ~Thenの中に書ききれないので 実行の有無を値で返したりすることは不可能でしょうか? よろしくお願い致します。

  • oracleのPL/SQLのEXIT戻りでエラーが

    PL/SQLを実行したのですが、EXITの終了でエラーがとなってしまいます。エラーがでます。 being~endを書いてしてPL/SQLを実行しているのですが、 being~endのPL/SQLでエラーとなった場合、EXITの終了時の戻りで以下のエラーがでます。 エラーとならないようにするにはどうしたらよいでしょうか。 SP2-0670: 内部数値変換が失敗しました。 使用方法: { EXIT | QUIT } [ SUCCESS | FAILURE | WARNING | n | 変数 | :バインド変数 ] [ COMMIT | ROLLBACK ] 実行したSQLは以下となります。 set serveroutput on exec utl_file.fremove('DATA_PUMP_DIR','hogehoge.txt'); VARIABLE rtn NUMBER DECLARE BEGIN :rtn := 0; select count(*) from d; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE||','||SQLERRM); :rtn := 16; END; / EXIT :rtn →ここでエラーがでる oracleは19cです。 よろしくお願いします。

  • ストアド実行時のエラー「参照しているコレクションは初期化されていません」

    以下のようなパッケージを作っています。 CREATE OR REPLACE PACKAGE "TEST"."TEST_P" as type test_type1 is table of TEST.TEST_TABLE%ROWTYPE; procedure test2 (ret OUT test_type1 ) ; end; ----------------------------------- 本体 ----------------------------------- CREATE OR REPLACE PACKAGE BODY "TEST"."TEST_P" as procedure test2( ret OUT test_type1 ) is cursor basic_cusor is select * from TEST.TEST_TABLE; BEGIN open basic_cusor; loop fetch basic_cusor into ret(0); exit when basic_cusor%notfound; END loop; END TEST3; end; ---------------------------------------- これをSQL Pluseから set serveroutput on; declare  arg1 TEST.TEST_P.test_type1; begin TEST.TEST_P.test2(arg1); dbms_output.put(arg1(0).coulm1); end; のように実行するとエラーが出ます。 初期化処理とはどのように行えばいいのでしょうか? 最終的にはSQLServerのストアドようにテーブル のような構造で値を返えせればいいです。

  • SQL*Plus内でPL/SQL、SQLを実行するシェルスクリプトを書

    SQL*Plus内でPL/SQL、SQLを実行するシェルスクリプトを書いています。 イメージ sqlplus scott/tiger << EOF   declare     aaa number;   begin     -- *1     select col1 into aaa from test1;   end;   /   -- *2   define a=1   define b=1   @test.sql EOF ここで*1にて例えば複数行が返ってくるなどのエラーが 発生した場合、*2以降のSQLを実行せずにSQL*Plusから抜けたいのですが どのようにすればよいかわかりますでしょうか。 whenever sqlerror exit 255 などはPL/SQL内の論理エラーはハンドリングしてくれないようです。 よろしくお願いします。 それかdefineや@マーク指定によるsqlファイルの取り込みを PL/SQLの中で実行できる方法を教えていただく方法でも 当方が実施したいことはできるのでそれでもかまいません。

  • ストアドについて質問

    質問をご覧いただきまして有難うございます。 初めてストアドプロシージャを作成しており、サンプルでいろいろと作ってみようと思い、作成コードを実行しようとしたんですが、以下のようなメッセージが表示され、正常に実行できません。 ORA-00001: 一意制約(OES4.PK_SITT_IKO_LOG)に反しています ORA-06512: "OES2.PRA002",行16 ORA-06512: 行4 以下はストアドです。 CREATE OR REPLACE PROCEDURE PRACTICE001 IS BEGIN DECLARE --ループ CNT NUMBER; BEGIN CNT := 0; LOOP EXIT WHEN CNT >= 10; CNT := CNT + 1; insert into LOG_TBL values(systimestamp,'test','comments are...'); END LOOP; END; END; テーブル(LOG_TBL)定義は次のようになっています。 LOG_TIME timestamp NOT NULL COMMENT1 varchar2(20) COMMENT2 varchar2(200) タイムスタンプであれば重複もないと思うんですが。。。 原因がよくわからないです。。。 宜しくお願い致します!

  • 関数内でのSQL文実行→エラー検知されない・・・。

    いつもお世話になってます。 sasakidと申します。 現在、ASPで開発を進めています。 エラーが発生したらエラーページに飛ぶように適所に 以下の文を入れています。 '------エラー処理-------- If Err.Number <> 0 Then  Call goto_ErrPage() ←…エラーページに飛ぶ関数 End If ほとんどの個所でエラーページに飛ぶことを確認しました。 今、困っていることはSQL文を実行する関数内で SQL文にエラーがあったとしてもどうやらエラーが検知されていないようなのです。 '=====SQL文実行関数=========== Function exeSql1(sql) exeSql1 = -1 'エラーセット sql = sql & "ORDER BY test" '←…エラーが出るように追加    Set rs = db.Execute(sql) If Err.Number <> 0 Then Set rs = Nothing Exit Function End If (中略) exeSql1 = 0 End Function '======本文================== (中略)   tmp = exeSql1(sql) If tmp <> 0 Then '戻り値がエラー(0以外)だったらエラー画面へ Call goto_ErrPage() ←…エラーページに飛ぶ関数 End If (後略) ------------------------- どんなに関数:exeSql1で実行されるSQL文にエラーを含めてもエラーページに飛びません。 本文中で実行しているSQL文にエラーが含んでいるとエラーページに飛ぶのですが・・・。 こんな現象の原因などわかる方がいらっしゃいましたら教えてください!!! よろしくお願いします。