【问题标题】:Problems converting an Oracle plsql stored procedure call to C# (invalid array bind size)将 Oracle plsql 存储过程调用转换为 C# 时出现问题(数组绑定大小无效)
【发布时间】:2016-01-25 22:22:01
【问题描述】:

我需要使用 odp.net12 将对我们在 PL/SQL 中使用的存储过程的调用转换为 c# 代码。

存储过程获取自定义类型的一些参数。

这是我的存储过程调用:

DECLARE
  P_SCODSERIE    VARCHAR2(3);
  P_SCODUSER     VARCHAR2(30);
  P_SMODACESS    VARCHAR2(8);
  P_SVETCODOBS   LINEUP.PCK_PIR_TYPES.VT_ARRAY_STRING;
  P_SVETDSCCOMPL LINEUP.PCK_PIR_TYPES.VT_ARRAY_FORMULA;
  P_NVETITEM     LINEUP.PCK_PIR_TYPES.VT_ARRAY_INT;
  R_NCODERROR    NUMBER;
BEGIN
  P_SCODSERIE := NULL;
  P_SCODUSER := 'TSR';
  P_SMODACESS := '00000001';
  P_SVETCODOBS(1) := '03';
  P_SVETDSCCOMPL(1) := 'comments about the item';
  P_NVETITEM(1) := 1;

  LINEUP.PCK_PIR_REQUEST_CMP.INSERTORDERCMP(
          P_SCODSERIE => P_SCODSERIE,
          P_SCODUSER => P_SCODUSER,
          P_SMODACESS => P_SMODACESS,
          P_SVETCODOBS => P_SVETCODOBS,
          P_SVETDSCCOMPL => P_SVETDSCCOMPL,
          P_NVETITEM => P_NVETITEM,
          R_NCODERROR => R_NCODERROR );
END;
/

当我们使用 odp.net 将此调用转换为 C# 代码时,出现错误

System.InvalidOperationException: OracleParameter.ArrayBindSize

但我在参数上找不到我的错误。

我的 C# 代码:

Oracle.DataAccess.Client.OracleCommand objCmd
    = new Oracle.DataAccess.Client.OracleCommand();

objCmd.Connection = (Oracle.DataAccess.Client.OracleConnection) conn;
objCmd.CommandText = "LINEUP.PCK_PIR_REQUEST_CMP.INSERTORDERCMP";
objCmd.CommandType = CommandType.StoredProcedure;
objCmd.BindByName = true;


objCmd.Parameters
      .Add("P_SCODSERIE", Oracle.DataAccess.Client.OracleDbType.Varchar2).Direction
      = ParameterDirection.Input;

objCmd.Parameters["P_SCODSERIE"].Value = null;


objCmd.Parameters
      .Add("P_SCODUSER ", Oracle.DataAccess.Client.OracleDbType.Varchar2).Direction
      = ParameterDirection.Input;

objCmd.Parameters["P_SCODUSER "].Value = "TSR";


objCmd.Parameters
      .Add("P_SMODACESS", Oracle.DataAccess.Client.OracleDbType.Varchar2).Direction
      = ParameterDirection.Input;

objCmd.Parameters["P_SMODACESS"].Value = "00000001";


Oracle.DataAccess.Client.OracleParameter strVetCodObs
    = new Oracle.DataAccess.Client.OracleParameter("P_SVETCODOBS", OracleDbType.Varchar2, ParameterDirection.Input);

strVetCodObs.CollectionType = OracleCollectionType.PLSQLAssociativeArray;

strVetCodObs.Value = new String[1] { "03" };

strVetCodObs.Size = 1;

strVetCodObs.UdtTypeName = "LINEUP.PCK_PIR_TYPES.VT_ARRAY_STRING";

objCmd.Parameters.Add(strVetCodObs);


Oracle.DataAccess.Client.OracleParameter strVetDescCompl
    = new Oracle.DataAccess.Client.OracleParameter("P_SVETDSCCOMPL", OracleDbType.Varchar2, ParameterDirection.Input);

strVetDescCompl.CollectionType = OracleCollectionType.PLSQLAssociativeArray;

strVetDescCompl.Value = new String[1] { "comments about the item" };

strVetDescCompl.Size = 1;

strVetDescCompl.UdtTypeName = "LINEUP.PCK_PIR_TYPES.VT_ARRAY_FORMULA";

objCmd.Parameters.Add(strVetDescCompl);


Oracle.DataAccess.Client.OracleParameter nVetItem
    = new Oracle.DataAccess.Client.OracleParameter("P_NVETITEM", OracleDbType.Decimal, ParameterDirection.Input);

nVetItem.CollectionType = OracleCollectionType.PLSQLAssociativeArray;

nVetItem.Value = new Int32[1] { 1 };

nVetItem.Size = 1;

nVetItem.UdtTypeName = "LINEUP.PCK_PIR_TYPES.VT_ARRAY_INT";

objCmd.Parameters.Add(nVetItem);

objCmd.Parameters
      .Add("R_NCODERRO", Oracle.DataAccess.Client.OracleDbType.Decimal).Direction
      = ParameterDirection.Output;


if (conn.State != ConnectionState.Open) {
   conn.Open();
}

objCmd.ExecuteNonQuery();

【问题讨论】:

    标签: c# .net oracle stored-procedures oracle11g


    【解决方案1】:

    你的问题(我认为)在这一行:

    objCmd.CommandText = "LINEUP.PCK_PIR_REQUEST_CMP.INSERTORDERCMP";
    

    在后面的代码行中,您通过名称将 C# 变量绑定到您在 CommandText 中定义的语句 - 您错过的部分是在其中定义绑定变量。您需要将该行更改为:

    objCmd.CommandText = "LINEUP.PCK_PIR_REQUEST_CMP.INSERTORDERCMP(
      P_SCODSERIE => :P_SCODSERIE,
      P_SCODUSER => :P_SCODUSER ,
      P_SMODACESS=> :P_SMODACESS,
      P_SVETCODOBS => :P_SVETCODOBS,
      P_SVETDSCCOMPL => :P_SVETDSCCOMPL,
      P_NVETITEM => :P_NVETITEM,
      R_NCODERROR => :R_NCODERROR 
    )";
    

    然后是代码:

    objCmd.Parameters["P_SCODSERIE"].Value = null;
    

    将看到将值“null”替换为名为“:P_SCODSERIE”的语句中的占位符。

    【讨论】:

    • 谢谢,斯蒂芬。但是不需要在调用 os C# 中声明过程参数,我有另一个带有单个 OracleDbType(例如 varchar2)的代码,我没有声明参数并且代码运行没有问题。不过我会根据你的建议做一个测试
    • 我做了一些谷歌搜索,我认为你是正确的。我以前从未见过任何 odp.net 代码 - 它与通常使用 JDBC 和我知道的其他语言进行数据库调用的方式不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 2020-09-27
    • 2013-10-10
    相关资源
    最近更新 更多