我正在尝试使用数据表中的数据对 Oracle 表进行批量插入和/或更新。 当我尝试执行“command.ExecuteNonQuery()”时,它会抛出“无法将“System.DateTime[]”类型的对象转换为“System.IConvertible”类型”。 从我在其他类似帖子中看到的情况来看,System.DateTime 似乎不能用作 System.IConvertable。不知道如何解决。
淡化版本是:
数据库表(ACUTALITEMSINBAG):
CREATEDON DATE
ABC VARCHAR2(12 BYTE)
ACTUALWEIGHT FLOAT
数据表中的示例数据:
CREATEDON ABC ACTUALWEIGHT
2/1/2024 2ABCDEFGHI17 3.9
2/1/2024 2JKLMNOPQR17 6.06
public int InsertActualWeightTable(DataTable dt)
{
int iRet = 0;
List<OracleParameter> spParams = new List<OracleParameter>();
DateTime[] CreatedOn = new DateTime[dt.Rows.Count];
string[] ABC= new string[dt.Rows.Count];
decimal[] ActualWeight = new decimal[dt.Rows.Count];
for (int j = 0; j < dt.Rows.Count; j++)
{
CreatedOn[j] = Convert.ToDateTime(dt.Rows[j]["CREATEDON"]);
ABC[j] = Convert.ToString(dt.Rows[j]["ABC"]);
ActualWeight[j] = Convert.ToDecimal(dt.Rows[j]["ACTUALWEIGHT"]);
}
string sInsertQuery = "INSERT INTO ACUTALITEMSINBAG(CREATEDON, ABC, ACTUALWEIGHT) VALUES(:CREATEDON, :ABC, :ACTUALWEIGHT)";
OracleParameter opCreatedON = new OracleParameter();
opCreatedON.OracleDbType = OracleDbType.Date;
opCreatedON.Value = CreatedOn;
opCreatedON.ParameterName = "CREATEDON";
spParams.Add(opCreatedON);
OracleParameter opABC = new OracleParameter();
opABC.OracleDbType = OracleDbType.Varchar2;
opABC.Value = ABC;
opABC.ParameterName = "ABC";
spParams.Add(opABC);
OracleParameter opActualWeight = new OracleParameter();
opActualWeight.OracleDbType = OracleDbType.Decimal;
opActualWeight.Value = ActualWeight;
opActualWeight.ParameterName = "ACTUALWEIGHT";
spParams.Add(opActualWeight);
try
{
dbContext.Open();
iRet = dbContext.InsertUsingOracleBulkCopy(sInsertQuery, spParams);
}
catch (Exception e)
{
throw e;
}
finally
{
dbContext.Close();
}
return iRet;
}
public int InsertUsingOracleBulkCopy(string sInsertQuery, List<OracleParameter> spParams)
{
int iRet = 0;
try
{
using (OracleCommand command = new OracleCommand())
{
command.CommandType = CommandType.Text;
command.Parameters.AddRange(spParamsToArray<OracleParameter>());
command.Connection = DbConnection;
command.CommandText = sInsertQuery;
command.BindByName = true;
command.CommandText = sInsertQuery;
iRet = command.ExecuteNonQuery(); // <--- THROWS ERROR HERE
}
}
catch (Exception ex)
{
iRet = -1;
}
return iRet;
}
解决方案是单衬管。在“InsertUsingOracleBulkCopy”方法中,我必须添加一个额外的参数(iCount),它是 InsertActualWeightTable(DataTable dt) 函数中数据表参数 dt 中的行数,如下所示:
int iCount = dt.Rows.Count;
try
{
dbContext.Open();
iRet = dbContext.InsertUsingOracleBulkCopy(sInsertQuery, spParams, iCount);
}
我在this SOF post中找到了所需的行。所以改变是:
public int InsertUsingOracleBulkCopy(string sInsertQuery, List<OracleParameter> spParams, int iCount)
{
int iRet = 0;
try
{
using (OracleCommand command = new OracleCommand())
{
command.CommandType = CommandType.Text;
command.Parameters.AddRange(spParams.ToArray<OracleParameter>());
command.Connection = DbConnection;
command.CommandText = sInsertQuery;
command.BindByName = true;
command.CommandText = sInsertQuery;
// This is critical to the process; in order for the command to
// recognize and bind arrays, an array bind count must be specified.
command.ArrayBindCount = iCount; // <-- This was the added line
iRet = command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
iRet = -1;
throw ex;
}
return iRet;
}
这次改变之后,它就像一个魅力。