在C#中键入安全绑定到Oracle存储过程?

时间:2009-09-01 10:30:38

标签: c# oracle stored-procedures

我们正在使用Oracle数据库在C#中部署多个项目。我想在Oracle存储过程中实现所有数据库逻辑,因为这个

  • 将所有数据库逻辑保留在数据库中
  • 使数据库结构更改时更容易维护
  • 允许跨编程语言更轻松地重用存储过程

我运行的测试代码使用SYS_REFCURSOR返回行,我在结果上手动执行数据绑定,因为SYS_REFCURSOR可以返回任何内容 - 即它不是类型安全的

我的问题是 - 有什么方法可以在存储过程返回类型中定义正确的类型,并在我的C#代码中安全地正确绑定到该类型?

e.g。我的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程序没有明确定义它的返回类型,而是生命

2 个答案:

答案 0 :(得分:2)

(你应该发布你的测试代码样本。因为我不确定,如果我理解你的问题。)

返回的类型为Object,用于提供任何可能的返回值。你必须手动转换它。但是您可以为转换生成代码。使用此元信息定义表或文件:哪个存储过程返回哪些类型以及将转换的.Net类型。使用此元信息来创建C#代码。

我们将RefCursors填入DataTable。将表字段分配给适当的成员变量的代码是从我们的元表中生成的。

答案 1 :(得分:1)

我使用T4文本模板与SQL服务器一起执行此操作。工作非常好。