【问题标题】:Bulk insert to Oracle from a DataTable using C#使用 C# 从 DataTable 批量插入到 Oracle
【发布时间】:2018-03-10 23:09:02
【问题描述】:

我一直在寻找,但没有找到一个很好的例子来说明我需要完成什么。标题说明了一切。这是我到目前为止所拥有的:

            //gather the report details
            DataTable dtReturn = new DataTable();
            DataTable dtResults = new DataTable();
            string strScript = "";
            bool doReturnData = false;

            try
            {
//this function returns my SQL table in to a datatable dtReturn:
                var ii =
                    Utility.db.Connection.EstablishDBConnection("usp_get_data_recap", dtReturn, null, null, true, 60);

//Clear out table before insert
                dtResults = OracleDataPull(9, "TRUNCATE TABLE user.SIGNUP_1");

                OracleParameter myparam = new OracleParameter();
                OracleCommand mycommand = new OracleCommand();
                int n;

//bulk insert to the signup_1 table from the datatable members. Datatable contains the same 4 fields being inserted in to signup_1 on the oracle side:
                mycommand.CommandText = "INSERT INTO user.SIGNUP_1 ([ID], [ACCOUNT_NUMBER], [MAIN_CUSTOMER], [SIGNUP_DATE]) VALUES(?)";
                mycommand.Parameters.Add(myparam);

                for (n = 0; n < 100000; n++)
                {
                    [what do i do here?]
                }
            }

我不确定这是否正确,或者是否有更简单的方法,但我需要将 dtReturn.Rows[n][0-3] 分别映射到 ID、account_number、main_customer 和 signup_date。

非常感谢帮助!提前致谢!

编辑:

我尝试了以下建议,但 l​​ambda 表达式出现错误: “无法将 lambda 表达式转换为类型‘字符串’,因为它不是委托类型”:

var ii =
    Utility.db.Connection.EstablishDBConnection("usp_get_data", dtReturn, null, null, true, 60);

dtResults = OracleDataPull(9, "TRUNCATE TABLE user.PR_data");

OracleParameter myparam = new OracleParameter();
OracleCommand mycommand = new OracleCommand();

mycommand.ArrayBindCount = dtReturn.Rows.Count;
mycommand.Parameters.Add(":myparam", OracleDbType.Varchar2, dtReturn.Select(c => c.myparam).ToArray(), ParameterDirection.Input);
mycommand.ExecuteNonQuery();

int n;

mycommand.CommandText = "INSERT INTO user.PR_data ([ID], [ACCOUNT_NUMBER], [MAIN_CUSTOMER], [SIGNUP_DATE]) VALUES(?)";
mycommand.Parameters.Add(myparam);

for (n = 0; n < 100000; n++)
{
    myparam.Value = n + 1;
    mycommand.ExecuteNonQuery();
}

dtResults = Utility.db.Connection.oracletoDataTable(strScript, doReturnData);

我也不确定这是为了产生正确的结果而设置的。你能告诉我这里哪里出错了吗?

【问题讨论】:

  • 您要插入的字段在哪里?它在你的数据表中吗?
  • 看看这篇文章:stackoverflow.com/questions/343299/…。提出的问题与您的问题相似,但有细微差别。
  • 我要插入的字段是我在上面的帖子中指出的那些需要转到我在帖子中指出的 Oracle 表的字段。是的,我看了那个帖子。这就是我将我的逻辑拉到上面的地方,不幸的是,这并不是我需要的地方。我需要能够遍历数据表(上述布局)以将批量插入到 Oracle。谢谢!

标签: c# oracle datatable bulkinsert


【解决方案1】:

感谢 codeproject.com,我实际上找到了一种更有效的解决方案。

这是我最后一个效果很好的方法。我所做的就是用我的 schema.table 和 datatable 调用它,其余的由它处理:

public static void WriteToServer(string qualifiedTableName, DataTable dataTable)
            {
                //**************************************************************************************************************************
                //  Summary:  Hit the Oracle DB with the provided datatable. bulk insert data to table.
                //**************************************************************************************************************************
                //  History:
                //   10/03/2017                 Created
                //**************************************************************************************************************************

                try
                {
                    OracleConnection oracleConnection = new OracleConnection(Variables.strOracleCS);

                    oracleConnection.Open();
                    using (OracleBulkCopy bulkCopy = new OracleBulkCopy(oracleConnection))
                    {
                        bulkCopy.DestinationTableName = qualifiedTableName;
                        bulkCopy.WriteToServer(dataTable);
                    }
                    oracleConnection.Close();
                    oracleConnection.Dispose();
                }
                catch (Exception ex)
                {
                    Utility.db.Log.Write(Utility.db.Log.Level.Error, "Utility", "db:WriteToServer: " + ex.Message);
                    throw;
                }
            }

参考:https://www.codeproject.com/Questions/228101/oracle-data-bulk-insert

【讨论】:

  • OracleBulkCopyClass 不好,恕我直言。它在执行插入时禁用索引。这意味着当您插入重复的键值时会遇到严重的问题。索引进入未使用状态。这只是它的一个问题。
【解决方案2】:
mycommand.ArrayBindCount = dtResults.Count;
mycommand.Parameters.Add(":parameterName", OracleDbType.Varchar2, dtResults.Select(c => c.ParameterName).ToArray(), ParameterDirection.Input);
mycommand.ExecuteNonQuery() ;

CommandText 设置后,您可以使用上面的代码。

【讨论】:

  • 这不起作用。它正在产生错误。请看我上面的编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-25
  • 2011-02-12
相关资源
最近更新 更多