PL/SQLでファンクション名に変数を使用する方法

このQ&Aのポイント
  • PL/SQLでファンクション名に変数を使用する方法について解説します。
  • ファンクション名を変数で指定することはできませんが、代わりにクエリの実行結果を使用してファンクションを呼び出す方法があります。
  • また、エラーメッセージ[PLS-00222: この有効範囲内に、名前'F_Neme'の関数は存在しません。]が表示される際には、変数のスコープが正しく設定されていない可能性があります。
回答を見る
  • ベストアンサー

PL/SQLでファンクション名に変数を使用するには

PL/SQLでファンクションの呼出を行いたいと思っています。 そこでファンクション名を変数で指定したいと思っているのですがうまくいきません。 ファンクション FUNCTION Check ( pi_Syori_No   IN NUMBER,  -- 処理No. po_Function_Name OUT VARCHAR2  -- ファンクション名 ) RETURN BOOLEAN IS TYPE Test_List IS VARRAY(100) OF VARCHAR2(10) NOT NULL; TYPE FcNameList IS VARRAY(100) OF VARCHAR2(10) NOT NULL; MmsCheckList Test_List := Test_List('○','×'); FcNameCheckList FcNameList := FcNameList('Check','Check'); BEGIN IF MmsCheckList(pi_Syori_No) = '○' THEN po_Function_Name :=FcNameCheckList(pi_Syori_No); ELSE po_Function_Name :=NULL; END IF; RETURN TRUE; EXCEPTION WHEN OTHERS THEN RETURN FALSE; END Check; メイン CREATE OR REPLACE PROCEDURE Test ( po_Out OUT VARCHAR2 ) IS Modoriti BOOLEAN :=TRUE; F_Neme VARCHAR2(2000) :=NULL; BEGIN IF Check(1,F_Neme) = TRUE THEN Modoriti := F_Neme(2,F_Neme); END IF; EXCEPTION WHEN OTHERS THEN po_Out := 'エラー'; END Test; この状態で実行すると下記のエラーが出てしまいます。 [PLS-00222: この有効範囲内に、名前'F_Neme'の関数は存在しません。] ファンクション名に変数を使うのは無理なのでしょうか? よろしくお願いいたします。

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

  • ベストアンサー
  • assault852
  • ベストアンサー率48% (1364/2797)
回答No.2

ファンクションをどのように使いたいのか、質問に明記された方が回答があるかも知れませんよ。 なるべく実例に近づけて。 質問を出しなおしてみては?

tomiono1
質問者

お礼

ご返事が遅くなり申し訳ありません。 assault852様の言われるとおり、ファンクションをどのように使いたいかなどを、しっかり明記していませんでした。 また、自分の中でも明確な使い方がしっかりしておりませんので一度締め切らせていただき、 再度まとまりましたら質問させていただきたいと思います。 本当にありがとうございました。

その他の回答 (1)

  • assault852
  • ベストアンサー率48% (1364/2797)
回答No.1

ちょっと聞いたことがないですね。 なぜ変数的扱いをしなければならなくなったのでしょうか。

tomiono1
質問者

補足

早速のご返答ありがとうございます。 なぜ変数的扱いをしなければならなくなったかというと、自分が初心者のため変数しか思いつかなかったからです。 これといって変数的扱にこだわっているわけではないです。 また、色々試していたのですが行き詰まり、今回質問させていただいたしだいです。

関連するQ&A

  • ストアドファンクションがうまく作成できない

    SQL Server 2005 にて、 以下のようなストアドファンクションを作成しようとしても、 「メッセージ 156、レベル 15、状態 1、プロシージャ TestKansu、行 30 キーワード 'end' 付近に不適切な構文があります。」 といったエラーメッセージが表示されてしまい、 うまく作成できません。。 文法など、いろいろ調べてみたところ、特に問題なさそうな 感じではあるのですが。。 どこに問題があるのか、どなたかご教授願えないでしょうか? なにとぞ、よろしくお願いいたします。 -------------------------------- use tempdb go -- 呼び出し形式 create function TestKansu ( @Date as datetime, @Type as varchar(1) ) returns @ReturnTable table ( StartDate varchar(8), EndDate varchar(8) ) as begin if @Type is null begin raiserror('正しいtypeを指定してください',-1,-1) end if @Date is null begin SET @Date = getdate() end if @Type = '0' begin insert into @ReturnTable select convert(varchar(8), dateadd(dd ,-2 ,@Date), 112) as StartDate, convert(varchar(8), dateadd(dd ,-2 ,@Date), 112) as EndDate, end if @Type = '1' begin insert into @ReturnTable select convert(varchar(8), @Date, 112) as StartDate, convert(varchar(8), @Date, 112) as EndDate end return 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; /

  • MYSQL ストアドプロシージャの記述方法

    MYSQLのストアドプロシージャについて分からないことがあり質問させて頂きます。 SQLのwhere句の部分を引数によって条件分で変更させたいと考えています。そこでORACLEの場合は変数にいれて最後に明示的にSQLを発行して いたので可能だったのですが、MYSQLの場合はどういった記述になる のかわかりません。やりたいことは下記のような感じです。 ORACLEの場合は procedure prctest(pc out refcur,a in varchar2,b in varchar2) is sqldata varchar2(1000); whereinfo varchar2(1000); begin sqldata := 'select ID , NAME from testTbl '; if (a IS NOT NULL) then   whereinfo := whereinfo || ' acol = a ' ; end if; if (b IS NOT NULL) then   if (whereinfo IS NOT NULL) then  whereinfo := whereinfo || ' and ';   end if;   whereinfo := whereinfo || ' acol = b ' ; end if; if (whereinfo IS NOT NULL) then  sqldata := sqldata || ' where ' || whereinfo ; end if; open pc for sqldata; (ここでSQLが入ったSQLを発行) end prctest; (抜粋) ストアドをあまり使用したことがなく良い説明ではないかも しれませんが、アドバイスの方頂けたらと思います。 よろしくお願いします。

  • [Oracle9i]PL/SQLでFETCHしても、%FOUND=TRUEにならない

    簡単なことだと思うのですが、はまってしまったので質問させてください。 以下のようなコードがあります。PL/SQLで書いてます。 SELECTした内容をFETCHして、IF文の%FOUNDで処理内容を変えているのですが、%FOUND=FALSEで必ず返ってきています。SELECT文自体でデータはひっぱって来ている(別で流しました)ようなので、理由が全然わからずまいってます。 -------------------------------------------------- FUNCTION get_siten_cd(siten_cd varchar2) RETURN varchar2 IS ret_siten_cd varchar(4); --4桁支店コード /*カーソル定義*/ CURSOR cs is SELECT SITEN_CD FROM MEI1.SITEN_MST WHERE SITEN_CD3 = siten_cd; /**カーソルに基づくレコードの定義**/ rs cs%ROWTYPE; BEGIN OPEN cs; FETCH cs INTO rs; IF cs%FOUND THEN --データが存在する場合 ret_siten_cd := rs.SITEN_CD; ELSE --データが存在しない場合 ret_siten_cd := NULL; END IF; CLOSE cs; RETURN ret_siten_cd; END; -------------------------------------------------- よろしくお願いします。

  • ストアドファンクションのエラーについて

    PostgreSQLでストアドファンクションを作成しました。 ファンクションの内容は下記の通りです。 CREATE FUNCTION getRenban (VARCHAR) RETURNS VARCHAR(7) AS ' DECLARE key ALIAS FOR $1; code VARCHAR(7); code2 VARCHAR(2); code5 VARCHAR(5); renban INTEGER; new_code VARCHAR(7); BEGIN SELECT MAX(code) INTO code FROM M_ITEM WHERE flg = TRIM($1); code2 := TRIM($1); IF code IS NULL THEN renban := 1; ELSE SELECT SUBSTR(code, 2) INTO code5; SELECT TO_NUMBER(code5, ''99999'') INTO renban; renban := renban + 1; END IF; code5 := ''''; SELECT TO_CHAR(renban, ''00000'') INTO code5; SELECT code2 || code5 INTO new_code; RETURN new_code; END; ' language 'plpgsql' ; コンソール上で下記のコマンドを実行したらエラーが出力されました。 SELECT getrenban('01'); 出力されたエラーの内容は下記の通りです。 ERROR: value too long for type character varying(5) CONTEXT: PL/pgSQL function "getrenban" line 19 at SQL statement お恥ずかしいですがいくらコードを見てもどこが原因なのかわかりません。 申し訳ありませんがご教授お願いできませんでしょうか。 昨日から悩んでいます。 どうか助けて下さい、宜しくお願いします。

  • テーブル名が可変の動的SQLをファンクションにしたい

    Oracle9iのWindowsXP環境です。 以下のようなPL/SQLを作成しましたが、同じようなselect文の繰り返しなので整理したいのと、レスポンスが悪いのでファンクションにしたいのですが、テーブル名が可変のため上手くいきません。「Table&1」は置換変数で、batファイルからパラメータが渡り、「Table200812」のように変更されます。 【***.bat】 set /p phara sqlplus -s ***/***@*** ***.sql %phara% 【***.sql】 省略 begin select aaa into a1 from Table&1 where code = 'AAAAA'; ・・ select aaa into a2 from Table&1 where code = 'BBBBB'; ・・ select aaa into a3 from Table&1 where code = 'CCCCC'; ・・ 省略 end; / 以下、試しに作成しようとしたファンクションですが、やはり予想どおりですが「表がありません」とコンパイルエラーになります。 create function Func_test(code IN varchar2, Table1 IN varchar2) return number is ret number; begin select aaa into ret from Table1 where code = 'code'; return ret; end; / ※コール側は、「a1 = Func_Test('AAAAA', Table&1);」 そもそもこれが実現できたとしてレスポンスが上がるものなのでしょうか?どちらにせよコードを整理する意味でもファンクションにはしたいのですが。。 宜しくお願い致します。

  • PL/SQL での判定(分岐?)の仕方を教えてください!

    PL/SQLで、以下の(1)の処理があった場合、 (2)はどのようにすればいいでしょうか? ※(2)は2つのどちらかの場合に処理をするような 判定をしたいのですが "OR" は使えないですよね? (1)個人IDを取得している場合(NULL以外) IF kojin_id NOT NULL THEN BEGIN SELECT KANRI_NO --管理NOを取得 FROM AAA WHERE KOJIN_ID = kojin_id; EXCEPTION WHEN NO_DATA_FOUND zero_check_flg := 1; --(2)で判定する用のチェックフラグ(※(2)の判定で使えるかなと思ったので) END; END IF; (2)個人IDがNULL、または、(1)で管理NOが取得できなかった場合   ↑   ここの判定文が作れません!!!!!

  • PL/SQLでフィルタ後のテーブルを返す関数

    環境:Oracle81740 タイトル通りの質問ですが、、、 以下のテーブルがあったとします。 CREATE TABLE PUBLIC.TEST_TABLE ( KEY1 CHAR(20) NOT NULL, KEY2 CHAR(20) NOT NULL, VALUE1 VARCHAR2(256), CONSTRAINT GENERAL_TABLE_PK PRIMARY KEY (KEY1, KEY2) ) そこで本題ですが、 (構文がめちゃくちゃだとは思いますが、読み取ってください^^;) FUNCTION TEST_GET ( IN_KEY TEST_TABLE.KEY1%TYPE ) RETURN TABLE IS retTbl TABLE; というイメージで、[KEY1]値を受け取り、該当するレコードをテーブルとして返す関数を組みたいのですが、調べがつきません。 どなたかよろしくお願いいたします。

  • 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

  • Function について

    これってどうやって使うのですか? 標準モジュールに Function test1(a As String) a = "abc" End Function を貼り付けて、F5を実行しても 何も起こらないのですが このサンプルはどうやって動かすことができるのでしょうか?

専門家に質問してみよう