【发布时间】:2014-08-28 08:38:06
【问题描述】:
用途:Oracle9i 标准版、ODAC 11.2.0.4、Oracle Instant Client 11.2.0.4
我正在将我的项目从 Microsoft 的 Oracle Provider 转换为 Oracle 的 ODP.NET
错误
无法转换类型为“Oracle.DataAccess.Types.OracleDecimal”的对象 键入“System.IConvertible”。无法在 RECEIPTID 列中存储 。 预期类型是 Int64。
当我的 Stored Proc 有返回参数时会弹出这个错误。返回是 Oracle 中的 Number 类型。我在使用 Microsoft 的 Oracle Provider 时没有遇到任何困难。
最初我将列RECEIPTID 的命令参数设置为System.Data.OracleClient.OracleType.Number;包含 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
【问题讨论】:
标签: c# winforms oracle plsql odp.net