0

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

对于其他表,我一次循环通过UniDataSet一条记录并将其添加到 aDataTable中,然后使用SqlBulkCopy将记录复制到 SQL Server。这很好用,但是对于大表,我在创建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();

这样就可以将记录从 复制UniDataSetDataTable. 然后,我SqlBulkCopy进入DataTable一个 SQL 表:

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

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

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

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

谢谢!

4

2 回答 2

1

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

if (dt.Rows.Count > 50000)
{
    //do SqlbulkCopy
    dt.Rows.Clear();
}
于 2015-06-12T19:38:40.273 回答
1

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

请下载 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]; 
于 2015-06-18T04:51:47.873 回答