ODP.NETでC#コードを記述して、パッケージ内の関数を呼び出そうとしました。以下の2つのエラーが発生します。
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to INSERT_FUNC'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06550: line 1, column 7:
PLS-00221: 'INSERT_FUNC' is not a procedure or is undefined
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
私のOracleCommand
は次のように設定されています:
cmd.CommandText = "PKG_NAME.INSERT_FUNC";
cmd.CommandType = CommandType.StoredProcedure;
ReturnValue
パラメータを追加する必要がありますか? ReturnValue
オブジェクトの最初のOracleParameter
としてOracleCommand
パラメータを追加する必要があることを議論する多くのフォーラムを見てきました。私はどんな提案もいただければ幸いです。
CREATE OR REPLACE
PACKAGE BODY pkg_name IS
FUNCTION insert_func (
i_description IN tableName.description%TYPE,
i_theme IN tableName.theme%TYPE,
o_id OUT tableName.id%TYPE,
o_error_msg OUT VARCHAR2 )
RETURN NUMBER
IS
l_program VARCHAR2(100) := 'PKG_NAME.INSERT_FUNC';
BEGIN
INSERT INTO tablea ( event_id, id, description, theme, lock_version )
VALUES ( rms12.tablea_seq.NEXTVAL, rms12.tablea_id_seq.NEXTVAL, i_description, i_theme, NULL );
INSERT INTO tableb ( id, description, theme )
VALUES ( rms12.id_seq.CURRVAL, i_description, i_theme );
SELECT rms12.id_seq.CURRVAL
INTO o_id
FROM dual;
RETURN 1;
EXCEPTION
WHEN OTHERS THEN
o_error_msg := sql_lib.create_msg(
'PACKAGE_ERROR', SQLERRM, l_program, TO_CHAR( SQLCODE ) );
RETURN 0;
END insert_func;
END pkg_name;
これはこのフォーラムでの最初の質問であり、自分の回答に投稿できることを嬉しく思います。
CommandType.StoredProcedure
を設定すると、ODP.NETを使用してOracleパッケージ関数を呼び出すことができます。
ORA-06550: line 1, column 7:
PLS-00221: 'INSERT_FUNC' is not a procedure or is undefined
ORA-06550: line 1, column 7: PL/SQL: Statement ignored
このエラーが発生した場合は、次の行をコマンドオブジェクトの最初のパラメーターとして追加してください。
cmd.Parameters.Add("Return_Value", OracleDbType.Int16,
ParameterDirection.ReturnValue);
ここに作業コードがあります:
using (var conn = new OracleConnection(oradb))
using (var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "PKG_NAME.INSERT_FUNC";
cmd.BindByName = true;
cmd.Parameters.Add("Return_Value", OracleDbType.Int16,
ParameterDirection.ReturnValue);
cmd.Parameters.Add("i_description", OracleDbType.Varchar2, 1000,
promotionEventSetupDetails.PromotionDescription,
ParameterDirection.Input);
cmd.Parameters.Add("i_theme", OracleDbType.Varchar2, 80,
promotionEventSetupDetails.PromotionTheme,
ParameterDirection.Input);
cmd.Parameters.Add("o_id", OracleDbType.Varchar2,
ParameterDirection.Output);
cmd.Parameters.Add("o_error_msg", OracleDbType.Varchar2,
ParameterDirection.Output);
conn.Open();
using (var dr = cmd.ExecuteReader())
{
// do some work here
}
}
これは、より新しいバージョンのOracleで新しくなければなりません。以前は、C#コードのすべての入力パラメーターの後にリストされた戻り値パラメーターでこれを行うことができましたが、これを12cで実行した後、この正確な問題が発生しました。
関数の結果を取得するのに役立つジェネリックメソッドを作成しました
var result = await
dbManager.ExecuteFunctionResultAsync<Oracle.ManagedDataAccess.Types.OracleDecimal>(
functionName, parameters.List);
public async Task<T> ExecuteFunctionResultAsync<T>(string spName, IEnumerable<OracleParameter> paramaters)
{
using (OracleConnection connection = new OracleConnection(this.connectionString))
{
connection.Open();
using (OracleCommand comm = new OracleCommand(spName, connection))
{
comm.CommandType = CommandType.StoredProcedure;
comm.BindByName = true;
string returnParam = "return_value";
comm.Parameters.Add(new OracleParameter() {
ParameterName = returnParam,
Direction = ParameterDirection.ReturnValue,
OracleDbType = OracleDbType.Int16,
});
this.SetCommandParameters(comm, paramaters);
await comm.ExecuteNonQueryAsync();
var result = (T)comm.Parameters[returnParam].Value;
return result;
}
}
}
private void SetCommandParameters(OracleCommand command, IEnumerable<OracleParameter> paramaters)
{
if (paramaters != null)
{
foreach (OracleParameter p in paramaters)
{
command.Parameters.Add(p);
}
}
}