PL/SQLで作成したプログラムを、C#で作ったプログラムから利用するために呼び出しをしようとしたときに遭遇したこのエラー。
PL/SQLには疎いせいか、解決に時間が掛かったので記事にして残しておこうと思います。
まずはエラーの内容で「未定義」という部分が気になったので、
そんなはずはない・・・と思い、一応パッケージの状態を調べると、
もちろんvalidなので有効。
問題なさそうなので、SQLで呼び出しをしてみる。
すると、ちゃんと呼び出せるし、
やっぱりパッケージの方には問題は無いようだった。
作成したのはFANCTION
パッケージ内に作成したのは、ファンクション。
よくファンクションとプロシージャの違いを忘れてしまいますが、
一言で言うと、
戻り値を返すのがファンクションで、
戻り値を返さないのがプロシージャだそうです。
ファンクションはプロシージャの機能を内包している。プロシージャ自体に戻り値をもたせたものがファンクションであると言ってよい。
参考:ストアドプロシージャとは
今回の場合で行くと、呼び出す対象はファンクションなので、
戻り値を受け取る必要があります。
呼び出しのための一連の処理の中で、戻り値に関しても処理を入れていたので問題はないだろうと思っていましたが、
C#からPL/SQLのファンクションを実行する場合は戻り値を最初にParametersにAddしないといけないようです。
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "PACKAGENAME.FANCTION_NAME"; // ファンクション名
OracleParameter param1 = new OracleParameter("param1", OracleDbType.Varchar2);
OracleParameter returnValue = new OracleParameter("param1", OracleDbType.Int32);
// パラメータの設定
param1.Direction = ParameterDirection.Input;
param1.value = "ひつようなパラメータを設定する"
returnValue.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(returnValue); // ←この順番!!! 戻り値が先
command.Parameters.Add(param1); // ←この順番!!! 引数は後
command.ExecuteNonQuery(); // 実行
var ret = returnValue.Value; // 後は適当にキャスト
引数の数、型を合わせるだけではエラーの解消はできず、パラメータ指定の順番が重要なようです。(これはなかなか分からない)
ヒントはこちらのサイトから頂きました。
先人の知恵でした。
この順番で処理することでうまく動作しましたが、なぜうまくいっているのかは分からず。詳しい人、教えてください。
↓↓↓よかったらクリックお願いします!