OracleDataAdapter错误

时间:2014-08-28 08:38:06

标签: c# winforms oracle plsql odp.net

用途:Oracle9i标准版,ODAC 11.2.0.4,Oracle Instant Client 11.2.0.4

我将我的项目从Microsoft的Oracle提供商转换为Oracle的ODP.NET

错误

  

无法转换类型' Oracle.DataAccess.Types.OracleDecimal'的对象   键入' System.IConvertible' .Couldn&tt存储< 145982>在RECEIPTID栏目中。   预期的类型是Int64。

当我的存储过程具有返回参数时,此错误会加速。返回的类型为Oracle中的Number。使用Microsoft的Oracle Provider时没有遇到任何困难。

最初我的命令参数设置为System.Data.OracleClient.OracleType.NumberRECEIPTID;在包含ODP.NET之后,我将其转换为Oracle.DataAccess.Client.OraclDbType.Double。然后错误抛出了。如错误所示,更改为Oracle.DataAccess.Client.OracleDbType.Int64,但似乎没有任何方法可以保持错误。

我正在使用OracleDataAdapter执行。

OracleCommand的初始化

public class ReceiptAccountBusinessTable : EquityBroker32.APP_DATA.config.GenericBusinessTable
    {
        OracleCommand[] nCommandCollection;

        public ReceiptAccountBusinessTable()
        {
            this.Tablename = "JKSBSCHEMA.RECEIPTACCOUNT";
            this.KeyDBField = "RECEIPTID";
            this.DefaultSql = string.Format("SELECT * FROM {0} WHERE {1}= (SELECT MAX({1}) FROM {0} )", this.Tablename, this.KeyDBField);

            //select command
            this.nCommandCollection = new Oracle.DataAccess.Client.OracleCommand[4];

            this.nCommandCollection[0] = new OracleCommand();
            this.nCommandCollection[0].Connection = this.DataConnection;
            this.nCommandCollection[0].CommandText = this.DefaultSql;
            this.nCommandCollection[0].CommandType = System.Data.CommandType.Text;

            //update command
            this.nCommandCollection[1] = new OracleCommand();
            this.nCommandCollection[1].Connection = this.DataConnection;
            this.nCommandCollection[1].CommandText = "JKSBSCHEMA.RECEIPTACCOUNT_ADDCHG_PROC";
            this.nCommandCollection[1].BindByName = true;
            this.nCommandCollection[1].CommandType = System.Data.CommandType.StoredProcedure;
            this.nCommandCollection[1].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PRECEIPTID", Oracle.DataAccess.Client.OracleDbType.Int64, 10, System.Data.ParameterDirection.InputOutput, false, 10, 0, "RECEIPTID", System.Data.DataRowVersion.Current, null));
            this.nCommandCollection[1].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PACCOUNTID_NEW", Oracle.DataAccess.Client.OracleDbType.Char, 13, System.Data.ParameterDirection.Input, false, 0, 0, "CLIENTACCOUNTID", System.Data.DataRowVersion.Current, null));
            this.nCommandCollection[1].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PACCOUNTID_OLD", Oracle.DataAccess.Client.OracleDbType.Char, 13, System.Data.ParameterDirection.Input, false, 0, 0, "CLIENTACCOUNTID", System.Data.DataRowVersion.Original, null));
            this.nCommandCollection[1].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PXSACTVALUE", Oracle.DataAccess.Client.OracleDbType.Double, 22, System.Data.ParameterDirection.Input, false, 0, 0, "XSACTVALUE", System.Data.DataRowVersion.Current, null));
            this.nCommandCollection[1].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PXSACTDESC", Oracle.DataAccess.Client.OracleDbType.Varchar2, 255, System.Data.ParameterDirection.Input, false, 0, 0, "XSACTDESC", System.Data.DataRowVersion.Current, null));
            this.nCommandCollection[1].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PPAGEBREAK", Oracle.DataAccess.Client.OracleDbType.Int32, 22, System.Data.ParameterDirection.Input, false, 0, 0, "PAGEBREAK", System.Data.DataRowVersion.Current, null));

            //insert command
            this.nCommandCollection[2] = new OracleCommand();
            this.nCommandCollection[2].Connection = this.DataConnection;
            this.nCommandCollection[2].CommandText = "JKSBSCHEMA.RECEIPTACCOUNT_ADDCHG_PROC";
            this.nCommandCollection[2].CommandType = System.Data.CommandType.StoredProcedure;
            this.nCommandCollection[2].BindByName = true;
            this.nCommandCollection[2].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PRECEIPTID", Oracle.DataAccess.Client.OracleDbType.Int64, 10, System.Data.ParameterDirection.InputOutput, false, 10, 0, "RECEIPTID", System.Data.DataRowVersion.Proposed, null));
            this.nCommandCollection[2].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PACCOUNTID_NEW", Oracle.DataAccess.Client.OracleDbType.Char, 13, System.Data.ParameterDirection.Input, false, 0, 0, "CLIENTACCOUNTID", System.Data.DataRowVersion.Current, null));
            this.nCommandCollection[2].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PACCOUNTID_OLD", Oracle.DataAccess.Client.OracleDbType.Char, 13, System.Data.ParameterDirection.Input, false, 0, 0, "CLIENTACCOUNTID", System.Data.DataRowVersion.Original, null));
            this.nCommandCollection[2].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PXSACTVALUE", Oracle.DataAccess.Client.OracleDbType.Double, 22, System.Data.ParameterDirection.Input, false, 0, 0, "XSACTVALUE", System.Data.DataRowVersion.Current, null));
            this.nCommandCollection[2].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PXSACTDESC", Oracle.DataAccess.Client.OracleDbType.Varchar2, 255, System.Data.ParameterDirection.Input, false, 0, 0, "XSACTDESC", System.Data.DataRowVersion.Current, null));
            this.nCommandCollection[2].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PPAGEBREAK", Oracle.DataAccess.Client.OracleDbType.Int32, 22, System.Data.ParameterDirection.Input, false, 0, 0, "PAGEBREAK", System.Data.DataRowVersion.Current, null));

            //delete command
            this.nCommandCollection[3] = new OracleCommand();
            this.nCommandCollection[3].Connection = this.DataConnection;
            this.nCommandCollection[3].CommandText = "DELETE FROM " + this.Tablename + " WHERE RECEIPTID=:p1 AND ACCOUNTID=RPAD(:p2,15)";
            this.nCommandCollection[3].CommandType = System.Data.CommandType.Text;
            this.nCommandCollection[3].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("p1", Oracle.DataAccess.Client.OracleDbType.Int64, 22, System.Data.ParameterDirection.Input, false, 0, 0, "RECEIPTID", System.Data.DataRowVersion.Current, null));
            this.nCommandCollection[3].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("p2", Oracle.DataAccess.Client.OracleDbType.Char, 15, System.Data.ParameterDirection.Input, false, 0, 0, "ACCOUNTID", System.Data.DataRowVersion.Current, null));

            this.CommandCollection = this.nCommandCollection;
        }
    }

存储过程的一瞥

PROCEDURE RECEIPT_ADDCHG_PROC
(
preceiptid IN OUT NUMBER,
preceiptmode IN CHAR,
pxsactdate IN DATE,
pxsactvalue IN NUMBER,
pbankaccountid IN VARCHAR2,
pchequeno IN VARCHAR2,
pclientbankid IN VARCHAR2,
pdescription IN VARCHAR2,
pstatementno in varchar2 default null,
pcustodypayment IN NUMBER)
is
nrow number;
begin

--check if posted
SELECT COUNT(*) INTO nrow from accountledger
WHERE receiptid = preceiptid;

IF nrow > 0 THEN
  RAISE_APPLICATION_ERROR(-20001, 'Record Already Posted');
END IF;

UPDATE Receipt
  Set pmodeid = preceiptmode,
  xsactdate = pxsactdate,
  xsactvalue = pxsactvalue,
  bankaccountid = pbankaccountid,
  chequeno = pchequeno,
  clientbankid = pclientbankid,
  description = pdescription,
  statementno = pstatementno,
  custodypayment = pcustodypayment
WHERE receiptid = preceiptid;

IF (SQL%NOTFOUND) THEN
  INSERT INTO RECEIPT(receiptid,
                      pmodeid,
                      xsactdate,
                      xsactvalue,
                      bankaccountid,
                      chequeno,
                      clientbankid,
                      description,
                      statementno,
                      custodypayment
                      )
  VALUES(preceiptid,
          preceiptmode,
          pxsactdate,
          pxsactvalue,
          pbankaccountid,
          pchequeno,
          pclientbankid,
          pdescription,
          pstatementno,
          pcustodypayment
          ) RETURNING receiptid into (preceiptid);
END IF;

end;

这就是我更新表格的方式

public void UpdateData(DataTable tbl, Oracle.DataAccess.Client.OracleTransaction oTran)
        {
            try
            {
                SetTransaction(oTran);
                this._adapter.Update(tbl);
                //this was added on 03-Aug-2011
                tbl.AcceptChanges();
            }
            //handling concurrency problem
            catch (DBConcurrencyException dbcx)
            {
                MessageBox.Show(CreateMessage(dbcx.Row), "Concurrency Exception", MessageBoxButtons.YesNo);
            }
            catch (OracleException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

堆栈跟踪说

at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
   at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
   at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)
   at Oracle.DataAccess.Client.OracleDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)
   at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping)
   at System.Data.Common.DbDataAdapter.Update(DataTable dataTable)
   at EquityBroker32.APP_DATA.config.GenericBusinessTable.UpdateData(DataTable tbl, OracleTransaction oTran) in d:\REVERSION\Latest\APP_DATA\config\GenericBusinessTable.cs:line 293

1 个答案:

答案 0 :(得分:0)

Voila找到了它!

我将以下代码块添加到现有代码块中并且它有效!

this.nCommandCollection[1].Parameters.Add(new Oracle.DataAccess.Client.OracleParameter("PRECEIPTID", Oracle.DataAccess.Client.OracleDbType.Double, 10, System.Data.ParameterDirection.InputOutput, false, 10, 0, "RECEIPTID", System.Data.DataRowVersion.Current, null));
this.nCommandCollection[1].Parameters["PRECEIPTID"].DbType = DbType.Decimal;

Appreciation goes to this website and Individual who answered it