我在同一个数据库服务器上有两个名为DB1和DB2的数据库。我在DB2中有Table1,在DB2中有Table2。目前,我使用insert into select *将Table2中的所有数据传输到Table1(Table1为空,我的目的是制作从Table2到Table1的数据副本)。表结构是聚簇ID列(GUID类型)和XML二进制(varbinary)数据列。
我目前的问题是,内存消耗非常高。有什么好的想法可以减少内存消耗吗?我粗略的想法是,我可以初始化几个小事务,并从每个事务中插入部分数据。
我正在使用VSTS 2008 + C#+ ADO.Net + SQL Server 2008 Enterprise。任何好的解决方案或参考样品?
这是我当前的代码导致内存不足异常。我正在使用ADO.Net SQLBulkCopy功能。
namespace BulkCopyTable
{
public class CopyData
{
string _sourceConnectionString;
string _destinationConnectionString;
public CopyData(string sourceConnectionString,
string destinationConnectionString)
{
_sourceConnectionString =
sourceConnectionString;
_destinationConnectionString =
destinationConnectionString;
}
public void CopyTable(string table)
{
using (SqlConnection source =
new SqlConnection(_sourceConnectionString))
{
string sql = string.Format("SELECT * FROM [{0}]", table);
SqlCommand command = new SqlCommand(sql, source);
source.Open();
IDataReader dr = command.ExecuteReader();
using (SqlBulkCopy copy =
new SqlBulkCopy(_destinationConnectionString))
{
copy.DestinationTableName = table;
copy.WriteToServer(dr);
}
}
}
}
class Program
{
static void Main(string[] args)
{
CopyData copier = new CopyData(ConfigurationSettings.AppSettings["source"], ConfigurationSettings.AppSettings["destination"]);
Console.WriteLine("Begin Copy");
copier.CopyTable(ConfigurationSettings.AppSettings["Table"]);
Console.WriteLine("End Copy");
return;
}
}
}
答案 0 :(得分:2)
您可以尝试使用BCP实用程序。
如果需要,可以使用Process类在C#中运行。
答案 1 :(得分:2)
这是一次性工作吗?如果是这样,您可以使用DTS或SSIS 如果没有,请查看您是否可以使用SQLBulkCopy&框架中的相关类
编辑:我看到你的代码&可以在调用WriteToServer之前建议使用BatchSize属性。答案 2 :(得分:1)
设置游标,逐步遍历源表中的每一行,并为每个获取的行“插入 - 选择”,使用更少的内存? BOL有很多踩过游标的例子。
更新:这是我从FETCH上的BOL T-Sql引用中复制/修改的一个例子:(评论来自BOL文章,我只是改了几个名字)
-- // Declare the variables to store the values returned by FETCH.
DECLARE @id uniqueidentifier, @xml varbinary(4000)
DECLARE myCursor CURSOR FOR
SELECT id, xml FROM Table1
OPEN myCursor
-- // Perform the first fetch and store the values in variables.
-- // Note: The variables are in the same order as the columns
-- // in the SELECT statement.
FETCH NEXT FROM myCursor
INTO @id, @xml
-- // Check @@FETCH_STATUS to see if there are any more rows to fetch.
WHILE @@FETCH_STATUS = 0
BEGIN
-- // Do something with your values!
INSERT INTO db2..Table2 (id, xml) SELECT @id, @xml
-- // This is executed as long as the previous fetch succeeds.
FETCH NEXT FROM myCursor
INTO @id, @xml
END
CLOSE myCursor
DEALLOCATE myCursor
答案 3 :(得分:1)