将UniDataSet复制到SQL Server的最有效方法是什么?

时间:2015-06-12 19:31:29

标签: c# sql-server u2 u2netdk rocket-u2

我有一个U2 / UniVerse数据库,需要将一个表中的数据复制到SQL Server表中。该表有大约600,000行,不到200列。我没有创建表格,也无法改变它。

对于其他表格,我一次循环一条DataTable条记录并将其添加到SqlBulkCopy,然后使用DataTable将记录复制到SQL Server。这样可以正常工作,但是在创建DataTable dt = new DataTable("myTempTable"); dt.Columns.Add("FirstColumn", typeof(string)); dt.Columns.Add("SecondColumn", typeof(string)); ... //adding a bunch more columns here dt.Columns.Add("LastColumn", typeof(string)); U2Connection con = GetU2Con(); UniSession us1 = con.UniSession; UniSelectList s1 = us1.CreateUniSelectList(0); UniFile f1 = us1.CreateUniFile("MyU2TableName") s1.Select(f1); UniDataSet uSet = f1.ReadRecords(s1.ReadListAsStringArray()); foreach (UniRecord uItem in uSet) { List<String> record = new List<String>(uItem.Record.ToString().Split(new string[] { "þ" }, StringSplitOptions.None)); DataRow row = dt.NewRow(); row[0] = uItem.RecordID; row[1] = record[0]; row[2] = record[1]; ... //add the rest of the record row[50] = record[49] dt.Rows.Add(row); } con.Close(); 时,使用大表我似乎内存不足。

UniDataSet

这样就可以将DataTable中的记录复制到SqlBulkCopy中。然后,我DataTable string SQLcon = GetSQLCon(); using (SqlBulkCopy sbc = new SqlBulkCopy(SQLcon)) { sbc.DestinationTableName = "dbo.MySQLTableName"; sbc.BulkCopyTimeout = 0; sbc.BatchSize = 1000; //I've tried anywhere from 50 to 50000 try { sbc.WriteToServer(dt); } catch { Console.WriteLine(ex.Message); } } 进入SQL表:

 <menu xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  tools:context=".MyActivity" >
   <item android:id="@+id/Refresh"
    android:title="@string/Refresh"
    android:icon="@drawable/refresh_icon"
    android:orderInCategory="100"
    app:showAsAction ="always"/>

    <item android:id="@+id/action_settings"
    android:title="@string/action_settings"
    android:orderInCategory="100"
    app:showAsAction="never" />

</menu>

这适用于我的U2表,这些表有50,000行左右,但是当表有500,000行时,它基本上会破坏调试器(VS Express 2012)。我这样做的PC是带有4GB内存的Windows 7 x64。 VS进程看起来在崩溃之前使用高达3.5GB的RAM。

我希望有一种方法可以使用SqlBulkCopy将UniDataSet写入SQL,但我对U2 .Net工具包不太熟悉。

我面临的问题是UniDataSet记录是多值的,我需要将它们分开才能将它们写入SQL。

谢谢!

2 个答案:

答案 0 :(得分:1)

DataTable在插入数据库之前,它在内存中变得太大了。 为什么不拆分批量插入操作?例如,读取前50.000个结果并插入到Sql server数据库,清除DataTable Memory并再次使用接下来的50.000行重新开始。

if (dt.Rows.Count > 50000)
{
    //do SqlbulkCopy
    dt.Rows.Clear();
}

答案 1 :(得分:1)

在U2 Toolkit for .NET v2.1.0中,我们实现了Native Access。现在,您可以直接从UniData / UniVerse文件创建DataSet / DataTable。您也可以指定WHERE和SORT子句。您将看到性能提升,因为它不会过多地获取ID以获取ID。例如,如果您有1000个记录ID,它将进行1000次服务器旅行。然而,如果您使用Native Access,它将进行一次服务器旅行。

请下载适用于.NET v2.2.0 Hot Fix 1的U2 Toolkit并尝试以下代码。有关更多信息,请联系u2askus@rocketsoftware.com。

            U2Connection con = GetU2Con();
            U2Command cmd = lConn.CreateCommand();
            cmd.CommandText = string.Format("Action=Select;File=MyU2TableName;Attributes=MyID,FirstColumn,SecondColumn,LastColumn;Where=MyID>0;Sort=MyID");
            U2DataAdapter da = new U2DataAdapter(cmd);
            DataSet ds = new DataSet();
            da.Fill(ds);
            DataTable dt = ds.Tables[0];