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

What is the most efficient way to copy UniDataSet to SQL Server?

我有一个 U2/UniVerse 数据库,需要将一个 table 中的数据复制到 SQL 服务器 table 中。有问题的 table 有大约 600,000 行和不到 200 列。我没有创建 table,也无法更改它。

对于其他 tables,我一次遍历 UniDataSet 一条记录并将其添加到 DataTable,然后使用 SqlBulkCopy 来将记录复制到 SQL 服务器。这工作正常,但是对于大 table 我似乎 运行 在创建 DataTable.

时内存不足
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 中。然后,我把SqlBulkCopyDataTable改成了SQLtable:

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);
    }
}

这对我的 U2 table 具有 50,000 行左右的效果很好,但是当 table 具有 500,000 行时,它基本上会使调试器 (VS Express 2012) 崩溃。我正在执行此操作的 PC 是 Windows 7 x64 和 4GB 内存。 VS 进程看起来在崩溃前最多使用了 3.5GB RAM。

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

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

谢谢!

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

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

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

请下载 U2 Toolkit for .NET v2.2.0 Hot Fix 1 并尝试以下代码。欲了解更多信息,请联系 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];