【问题标题】:Type safe binding to an Oracle Stored Procedure in C#?类型安全绑定到 C# 中的 Oracle 存储过程?
【发布时间】:2010-11-24 14:32:55
【问题描述】:

我们正在使用 C# 部署多个项目,后面是 Oracle 数据库。我想在 Oracle 存储过程中实现所有的数据库逻辑,就像这样

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

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

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

例如我的 PL/SQL 过程看起来像这样——返回部分不是类型安全的——它可以是任何东西。如果我想从另一个 Oracle 包中重用它,那么它将没有正确的类型检查

PROCEDURE get_risk (p_process_id IN NUMBER, p_risk OUT sys_refcursor);

我的 C# 代码如下所示。我已经从几个课程中将它聚集在一起,所以希望它是有道理的。当我从 DB 调用中提取数据时,我手动定义数据类型 - 我需要在 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 过程没有明确定义它的返回类型,但是生活

【问题讨论】:

    标签: c# oracle stored-procedures


    【解决方案1】:

    (您应该发布您的测试代码示例。因为我不确定我是否正确理解了您的问题。)

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

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

    【讨论】:

    • 这可能是要走的路——我一直在寻找可以在 Oracle 过程中完全定义返回类型的方法。这将使与过程类型对话的任何其他代码也安全。我想我的问题是我没有完全定义接口 - 当我知道数据类型实际上是什么时,我通常不会编写函数并返回一个对象
    • 是的,定义那个接口。我们支持 Oracle 和 SQL Server。我们有一类关心数据库特定的东西。两者都实现了相同的接口。
    • 您是否将数据作为 SYS_REFCURSOR 从 Oracle 返回?
    • 否,作为 Ref 光标:TYPE resc IS REF CURSOR;Procedure foo(bla in varchar2, bla2 in char, pResult IN OUT resc) 无法使用 Sys_refcursor。 IIRC 因为我们必须支持不支持他的 Oracle 8。但我不确定。你认为这有什么不同吗?
    【解决方案2】:

    我使用 T4 文本模板在 SQL Server 上执行此操作。效果非常好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-22
      • 1970-01-01
      • 2021-09-19
      • 2015-10-31
      • 2010-11-02
      • 2011-05-05
      • 2016-08-24
      • 1970-01-01
      相关资源
      最近更新 更多