1、我需要从c# 的datatable插入数据到oracle数据库。
2、datatable里面数据量比较大,总共27万条记录。
3、插入前需要先清空数据库的表。
4、要求插入效率比较高。
5、如果插入失败,回滚到插入前的表。求高人,给完整代码。最好通过以下代码改造,下面的代码可以运行,但效率很低。
 public static int BatchInsert(string table, DataTable dt)
        {
            OracleConnection connOracle = new OracleConnection(connectionString);
            connOracle.Open();
            //Oracle.DataAccess.Client.OracleConnection connOracle = new Oracle.DataAccess.Client.OracleConnection(connectionString);
            try
            {
                string strfields = "";
                string strvalues = "";
                string filed = "";
                string strvalue = "";
                int count = 0;                OracleDataAdapter da = new OracleDataAdapter();                OracleCommandBuilder ob = new OracleCommandBuilder(da);                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    string strfiled = dt.Columns[i].ColumnName;
                    strfields += strfiled + ",";
                    strvalues += ":" + strfiled + ",";
                }                if (strfields != "")
                {
                    strfields = strfields.Substring(0, strfields.LastIndexOf(","));
                    strvalues = strvalues.Substring(0, strvalues.LastIndexOf(","));
                }                da.InsertCommand = new OracleCommand();
                da.InsertCommand.Connection = connOracle;
                da.InsertCommand.CommandText = "insert into " + table + "(" + strfields + ") values (" + strvalues + ")";                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    filed = dt.Columns[i].ColumnName;
                    strvalue = ":" + filed;
                    OracleParameter oparam = new OracleParameter();
                    oparam.ParameterName = strvalue;
                    oparam.SourceVersion = DataRowVersion.Current;
                    oparam.SourceColumn = filed;
                    da.InsertCommand.Parameters.Add(oparam);
                }                count = da.Update(dt);                connOracle.Close();                return count;
            }
            catch (Exception ex)
            {
                string aa = ex.Message;
                return 0;
            }
        }

解决方案 »

  1.   

    如果数据在内存,那就遍历insert语句插入,如果数据在另一个数据库,可以进行数据导入
      

  2.   

    要回滚,可参照:
                SqlConnection sqlCnn = new SqlConnection(Class_mssql_conn.ConnStr);
                sqlCnn.Open();
                SqlCommand sqlCmd = new SqlCommand();
                sqlCmd.Connection = sqlCnn;
                SqlTransaction st = sqlCnn.BeginTransaction(IsolationLevel.ReadCommitted);
                sqlCmd.Transaction = st;
     try
    {
        foreach (int i = 0; i < dt.Columns.Count; i++)
        {
            sqlCmd.CommandText = attendance.delhourSql(dt.Rows[0][0].Tostring());//此处为插入数据表的SQL语句
            sqlCmd.ExecuteNonQuery();
        }
        st.Commit();
        MessageBox.Show("保存成功", "信息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
    }
    catch (Exception ex)
    {
        MessageBox.Show("保存失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    finally { sqlCnn.Close(); }
      

  3.   

                SqlConnection conn = new SqlConnection(你的连接字符);
                comm.Parameters.Add("@BatchNo", SqlDbType.NVarChar, 50).Value = v_BatchNO;
                try
                {
                    IDictionary<string, string> Mapping = new Dictionary<string, string>();
                    //datatable中有多少属性严格按序添加
                    Mapping.Add("ID", "ID");
                        …………
                    Mapping.Add("~~","~~");
                    int i = Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteSqlBulkCopy(Mapping, "表名", 连接字符串, dataTable);
                    if (i == 0)
                    {
                        return false;
                    }
                   
                    return true;
                }
                catch (SqlException ex)
                {
                    //throw new Exception(ex.Message);
                    return false;
                }
                finally
                {
                    conn.Close();
                }
      

  4.   

    执行多条SQL语句,实现数据库事务。
            private void DoInsert()
            {
                DataTable dtSource = 你获取的DataTable//
                ArrayList SQLStringList = new ArrayList();            SQLStringList.Add("Delete删除语句");            if (dtSource != null)
                {
                    for (int i = 0; i < dtSource.Rows.Count; i++)
                    {
                        SQLStringList.Add("根据要求拼接的插入数据库预计");
                    }
                 
                }            ExecuteSqlTran(SQLStringList);
            }
            /// <summary>
            /// 执行多条SQL语句,实现数据库事务。
            /// </summary>
            /// <param name="SQLStringList">多条SQL语句</param>
            public static void ExecuteSqlTran(ArrayList SQLStringList)
            {
                using (OracleConnection conn = new OracleConnection(connectionString))
                {
                    conn.Open();
                    OracleCommand cmd = new OracleCommand();
                    cmd.Connection = conn;
                    OracleTransaction tx = conn.BeginTransaction();
                    cmd.Transaction = tx;
                    try
                    {
                        for (int n = 0; n < SQLStringList.Count; n++)
                        {
                            string strsql = SQLStringList[n].ToString();
                            if (strsql.Trim().Length > 1)
                            {
                                cmd.CommandText = strsql;
                                cmd.ExecuteNonQuery();
                            }
                        }
                        tx.Commit();
                    }
                    catch (System.Data.OracleClient.OracleException E)
                    {
                        tx.Rollback();
                        throw new Exception(E.Message);
                    }
                }
            }
      

  5.   

    我不知道oracle的过程能不能将DataTable做为参数传人的。
    可以 还是建议用储存过程。SQL2008是可以用DataTable做参数传入的。