通过 DB2OLEDB 执行存储过程时收到 -379 的 SQLCode

Posted

技术标签:

【中文标题】通过 DB2OLEDB 执行存储过程时收到 -379 的 SQLCode【英文标题】:Receiving an SQLCode of -379 when executing a stored procedure through DB2OLEDB 【发布时间】:2019-03-29 16:43:07 【问题描述】:

我正在尝试使用 C# 中的 Dd2OleDb 版本 6 驱动程序调用 DB2 中的存储过程。调用 cmd.ExecuteNonQuery 时,会抛出 SQLCode 为 -379 的 OleDbException。完整信息如下。

我对另一个运行良好的存储过程有类似的调用。

在使用 IBM DB2 客户端时,两个存储过程都可以正常工作,但是我们正在尝试采用使用 OleDB 的标准。所有参数值的类型和范围都正确。

操作系统:Windows 8.1

.Net Framework 4.6.1 Visual Studio 2017

C# 客户端

const string storedProc = @"T99XXX.CI419UPDATE";

using (var conn = GetCisDBConnection())
using (var cmCommand = new OleDbCommand(storedProc, conn))

       cmCommand.CommandType = System.Data.CommandType.StoredProcedure;

       var pCustNbr = new OleDbParameter("P_CUST_NBR", customerNbr);
       var pPremNbr = new OleDbParameter("P_PREM_NBR", premiseNbr);
       var pCmsgType = new OleDbParameter("P_CMSG_TYPE", cmsgType);
       var pCmsgText = new OleDbParameter("P_CMSG_TEXT", cmsgText);
       var pStatus = new OleDbParameter("O_STATUS", OleDbType.Integer, 10, System.Data.ParameterDirection.Output, true, 0, 0, null, System.Data.DataRowVersion.Current, null);
       var pSqlCode = new OleDbParameter("O_SQLCODE", OleDbType.Integer, 10, System.Data.ParameterDirection.Output, true, 0, 0, null, System.Data.DataRowVersion.Current, null);

       cmCommand.Parameters.Add(pCustNbr);
       cmCommand.Parameters.Add(pPremNbr);
       cmCommand.Parameters.Add(pCmsgType);
       cmCommand.Parameters.Add(pCmsgText);
       cmCommand.Parameters.Add(pStatus);
       cmCommand.Parameters.Add(pSqlCode);

       conn.Open();
       cmCommand.ExecuteNonQuery(); // Returns -379

存储过程头:

CREATE PROCEDURE T14TOPS.CI419UPDATE (
    IN P_CUST_NBR DECIMAL(7,0),
    IN P_PREM_NBR DECIMAL(7,0),
    IN P_CMSG_TYPE DECIMAL(3,0),
    IN P_CMSG_TEXT VARCHAR(980),
    OUT O_STATUS INTEGER,
    OUT O_SQLCODE INTEGER)

完整的错误信息是

System.Data.OleDb.OleDbException HResult=0x80040E14 Message=发生内部网络库错误。发生网络级语法错误。 SQLSTATE:HY000,SQLCODE:-379 Source=System.Data

堆栈跟踪:

在 System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr) 在 System.Data.OleDb.OleDbCommand.ExecuteCommandTextForMultpleResults(tagDBPARAMS dbParams,对象和 executeResult) 在 System.Data.OleDb.OleDbCommand.ExecuteCommandText(对象和执行结果) 在 System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior 行为,对象和 executeResult) 在 System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior 行为,字符串方法) 在 System.Data.OleDb.OleDbCommand.ExecuteNonQuery() 在 C:\TFS\MSServer\Source\Main\DataAccess\CisDataAccess.cs: 103 中的 CustomerCare.DataAccess.CisDataAccess.UpdateLog(Decimal customerNbr, Decimal premiseNbr, Decimal cmsgType, String cmsgText) 在 C:\TFS\MSServer\Source\Main\DataAccessTest\CisDataAccessTest.cs:line 30 中的 DataAccessTest.CisDataAccessTest.UpdateLog_Test() 处

System.IndexOutOfRangeException HResult=0x80131508 消息=此 OleDbParameterCollection 的无效索引 -1,Count=6。 Source=System.Data

【问题讨论】:

尝试设置参数类型。看起来你混合了小数和字符串。确保参数的顺序与它们在存储过程中出现的顺序相同,因为 OleDb 会忽略参数的名称并依赖于索引位置。由于您收到Invalid index -1 for this OleDbParameterCollection 消息,因此这些参数有些愚蠢。 【参考方案1】:

在基于值识别数据类型时,显然 OleDBParameter 构造函数不是 100%。使用接受数据类型并随后分配值的构造函数解决了该问题。

var pCustNbr = new OleDbParameter("P_CUSTNBR", OleDbType.Decimal)  Value = customerNbr ; 
var pPremNbr = new OleDbParameter("P_PREM_NBR", OleDbType.Decimal)  Value = premiseNbr ;
var pCmsgType = new OleDbParameter("P_CMSG_TYPE", OleDbType.Decimal)  Value = cmsgType ;
var pCmsgText = new OleDbParameter("P_CMSG_TEXT", OleDbType.VarChar)  Value = cmsgText ;
var pStatus = new OleDbParameter("O_STATUS", OleDbType.Integer, 10, System.Data.ParameterDirection.Output, true, 0, 0, null, System.Data.DataRowVersion.Current, null);
var pSqlCode = new OleDbParameter("O_SQLCODE", OleDbType.Integer, 10, System.Data.ParameterDirection.Output, true, 0, 0, null, System.Data.DataRowVersion.Current, null);

【讨论】:

以上是关于通过 DB2OLEDB 执行存储过程时收到 -379 的 SQLCode的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在从 Java 批量执行 PostgreSQL 存储过程时收到错误消息,提示“未预期结果”?

尝试执行存储过程时收到“com.microsoft.sqlserver.jdbc.SQLServerException:索引1超出范围。”

ASP.NET MVC - 存储过程执行返回无效对象

从 php 执行时 SQL Server 存储过程错误

Oracle 11g 代码上的 PL/SQL 是在执行存储过程时

通过jdbc执行的存储过程