我们正在使用C#部署多个与Oracle数据库相关的项目。我希望将所有的数据库逻辑都实现在Oracle存储过程中,因为这样做有以下好处:
我的问题是 - 有没有办法在存储过程的返回类型中定义正确的类型,并在我的C#代码中正确地安全绑定到该类型?
例如,我的PL/SQL存储过程如下所示 - 返回部分不是类型安全的 - 它可以是任何类型。如果我想要从另一个Oracle包中重用它,则不会具有正确的类型检查。
- 将所有的数据库逻辑保留在数据库中
- 当数据库结构发生变化时,更容易维护
- 更容易地在不同的编程语言中重用存储过程
我的问题是 - 有没有办法在存储过程的返回类型中定义正确的类型,并在我的C#代码中正确地安全绑定到该类型?
例如,我的PL/SQL存储过程如下所示 - 返回部分不是类型安全的 - 它可以是任何类型。如果我想要从另一个Oracle包中重用它,则不会具有正确的类型检查。
PROCEDURE get_risk (p_process_id IN NUMBER, p_risk OUT sys_refcursor);
我的C#代码大致如下。我从几个类中拼凑了这些代码,所以希望它们是有意义的。当我从数据库调用中提取数据时,我手动定义数据类型-我需要在C#代码中知道Oracle的数据类型。
// setup procedure call
_oracleCommand = new OracleCommand("risk_pkg.get_risk", _conn.OracleConnection);
_oracleCommand.Parameters.Add(new OracleParameter("p_process_id", OracleDbType.Int64, processId, ParameterDirection.Input));
_oracleCommand.Parameters.Add(new OracleParameter("p_risk", OracleDbType.RefCursor, null, ParameterDirection.Output));
_oracleDataAdapter = new OracleDataAdapter(_oracleCommand);
_dataSet = new DataSet();
// call Oracle
_oracleDataAdapter.Fill(_dataSet);
// extract data - hand coded binding
Int64 dbRiskId = (Int64)_dataSet.Tables[0].Rows[0][_dataSet.Tables[0].Columns["risk_id"]];
Int64 dbClientId = (Int64)_dataSet.Tables[0].Rows[0][_dataSet.Tables[0].Columns["client_id"]];
return new Risk(dbRiskId, dbClientId);
这并不一定是个问题 - 我只是想知道是否有更好的方法来使我的PL/SQL返回结果更加明显,让我的C#代码不必知道Oracle数据类型 - 使我免受数据库结构变化的影响。
被接受的解决方案:这似乎是实际的解决方案。我仍然稍微感到不满意的是我的Oracle过程没有明确定义其返回类型,但这就是生活。
TYPE resc IS REF CURSOR;
和Procedure foo(bla in varchar2, bla2 in char, pResult IN OUT resc)
是不可能使用Sys_refcursor的。如果我没记错的话,因为我们必须支持不支持它的Oracle 8。但我不确定。你认为这有什么区别吗? - John Smithers