SQL Server选择和插入问题

时间:2009-08-28 02:21:38

标签: c# .net sql-server visual-studio-2008 ado.net

我在同一个数据库服务器上有两个名为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;
        }
    }
}

4 个答案:

答案 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)

我认为您希望设置批量大小,以便将它们分成可管理的部分。

Bulk copy batch size

检查此批量加载数据白皮书了解其他技术: Bulk load