永不言弃!
不忘初心:感恩的心!上进的心!

最近用到批量插入数据到oracle,总结了网上的方案,内容如下

备注:亲测了三种方式的对比,参考网址:https://www.cnblogs.com/ggll611928/p/17897390.html

 

方式一:使用数组绑定

https://www.codenong.com/343299/

数据库:CREATE TABLE jkl_test (id NUMBER(9));

USING Oracle.DataAccess.Client;

namespace OracleArrayInsertExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // OPEN a connection USING ODP.Net
            var connection = new OracleConnection("Data Source=YourDatabase; Password=YourPassword; User Id=YourUser");
            connection.Open();

            // CREATE an INSERT command
            var command = connection.CreateCommand();
            command.CommandText ="insert into jkl_test values (:ids)";

            // SET up the parameter AND provide VALUES
            var param = new OracleParameter("ids", OracleDbType.Int32);
            param.Value = new int[] { 22, 55, 7, 33, 11 };

            // This IS critical TO the process; IN ORDER FOR the command TO
            // recognize AND bind arrays, an array bind COUNT must be specified.
            // SET it TO the LENGTH OF the array.
            command.ArrayBindCount = 5;
            command.Parameters.Add(param);
            command.ExecuteNonQuery();
        }
    }
}

 

方式二 使用绑定变量的方式二

https://blog.csdn.net/weixin_50478033/article/details/133983591

public int InsertBindParam(DataTable dt)
{
    int recordCount = dt.Rows.Count, i = 0, count = 0;
 
    using (OracleCommand cmd = new OracleCommand())
    {
        cmd.CommandText = "INSERT INTO TEST001(COL1,COL2,COL3) VALUES(:P_COL1,:P_COL2,:P_COL3)";
        //指定单次需要处理的条数
        cmd.ArrayBindCount = recordCount;
        int[] p_col1 = new int[recordCount];
        string[] p_col2 = new string[recordCount];
        DateTime[] p_col3 = new DateTime[recordCount];
 
        cmd.Parameters.Add(new OracleParameter("P_COL1", OracleDbType.Int32, p_col1, ParameterDirection.Input));
        cmd.Parameters.Add(new OracleParameter("P_COL2", OracleDbType.Varchar2, p_col2, ParameterDirection.Input));
        cmd.Parameters.Add(new OracleParameter("P_COL3", OracleDbType.Date, p_col3, ParameterDirection.Input));
 
        foreach (DataRow dr in dt.Rows)
        {
            p_col1[i] = Convert.ToInt32(dr["COL1"].ToString());
            p_col2[i] = dr["COL2"].ToString();
            p_col3[i] = DateTime.Now;
        }
 
        using (var con = new OracleConnection())
        {
            con.ConnectionString = m_sConnection;
            con.Open();
 
            cmd.Connection = con;
            //执行批处理操作,并返回影响行数
            count = cmd.ExecuteNonQuery();  
        }
 
        return count;
    }
}

 

方式三 使用OracleBulkCopy

https://www.cnblogs.com/longbky/p/8146965.html

public static bool ExcuteNonQuery(DataTable dt)
        {
            using (SqlConnection connection = new SqlConnection(connStr))//创建数据库连接
            {
                using (SqlBulkCopy sqlbulkcopy = new SqlBulkCopy(connection))
                {
                    connection.Open();
                    //sqlbulkcopy.BulkCopyTimeout = 100;  //超时之前操作完成所允许的秒数
                    sqlbulkcopy.BatchSize = dt.Rows.Count;  //每一批次中的行数
                    sqlbulkcopy.DestinationTableName = dt.TableName;  //服务器上目标表的名称
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);  //映射定义数据源中的列和目标表中的列之间的关系
                    }
                    sqlbulkcopy.WriteToServer(dt);  // 将DataTable数据上传到数据表中
                }
            }
            return true;
        }

拷贝博主的内容

特别注意  sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);

插入的时候列的顺序可以不一致,但名称和数据类型最好要保存一致。不一致时候,也能进行正确的转换,除了比如DataTime数据类型,不能插入一个无效的string时间字符串。

在插入数据的时候如果数据类型是Guid类型的时候。一定要创建列的时候一定要指定数据类型: dt.Columns.Add("UserID", typeof(System.Data.SqlTypes.SqlGuid));,

不然会报“来自数据源的 String 类型的给定值不能转换为指定目标列的类型 uniqueidentifier。”这个错。

 

posted on 2023-12-12 15:19  永不言弃!  阅读(110)  评论(0编辑  收藏  举报