执行 Oracle 批量插入/更新时出错 - 无法将“System.DateTime[]”类型的对象转换为“System.IConvertible”类型

问题描述 投票:0回答:1

我正在尝试使用数据表中的数据对 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;
}
c# bulkinsert oracle21c
1个回答
0
投票

解决方案是单衬管。在“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;
}

这次改变之后,它就像一个魅力。

© www.soinside.com 2019 - 2024. All rights reserved.