Sql server 2005 SQL Server 2005错误701-内存不足

Sql server 2005 SQL Server 2005错误701-内存不足,sql-server-2005,memory,Sql Server 2005,Memory,在sql Server 2005上执行约26MB的.sql文件时,我当前收到以下错误消息: Msg 701, Level 17, State 123 There is insufficient system memory to run this query. 我正在使用4GB内存、64位Windows7 Ultimate、Core2Duo T6400(2GHz) 有没有一种方法可以在不接收此消息的情况下执行它(可能会强制SQL Server使用交换文件?),或者有没有一种方法可以部分执行它(例

在sql Server 2005上执行约26MB的.sql文件时,我当前收到以下错误消息:

Msg 701, Level 17, State 123
There is insufficient system memory to run this query.
我正在使用4GB内存、64位Windows7 Ultimate、Core2Duo T6400(2GHz)

有没有一种方法可以在不接收此消息的情况下执行它(可能会强制SQL Server使用交换文件?),或者有没有一种方法可以部分执行它(例如一次执行100个查询)

该文件基本上是一个CREATE表,后面跟着数千个INSERT查询,我有很多这样的查询(使用abcdbf转换器将.DBF文件转换为SQL查询)


任何想法都将不胜感激

您可以将文件分为多个批处理—例如,在每千次插入后添加go语句

e、 g


另一种方法可能是使用批量上传,例如bcp

,此外,每隔这么多条记录喷洒GO语句,如果您关心整个运行或回滚过程,则使用如下事务:

SET XACT_ABORT ON
BEGIN TRAN

Insert ...
Insert ...
Insert ...
...
GO
Insert ..
Insert ..
Insert ..
GO

If @@TranCount > 0 Commit Tran

当XACT_ABORT设置为ON时,任何失败的insert语句都将回滚整个事务。

您可以在sql查询之间添加DBCC命令,如:

DBCC FREESYSTEMCACHE ('ALL')
GO
DBCC FREESESSIONCACHE
GO
DBCC FREEPROCCACHE
GO

这将有助于释放内存。此外,Microsoft在SQLServer2005(外观)中发布了一个修补程序来解决此问题。尝试安装修补程序\服务包。

这个问题在这里似乎经常出现。有正确的(也是最常用的)答案,但让我试着补充我能做的,以使这更清楚

错误消息有点误导。SQL Server告诉您它没有足够的内存来运行查询,但它真正的意思是它没有足够的内存来解析查询

在运行查询时,SQL Server可以使用它想要的所有内容—如果需要,可以使用千兆字节。解析是另一回事;服务器必须构建一个解析树,而可用于该解析树的内存量非常有限。我从来没有在任何地方找到记录的实际限制,但对于一个典型的充满
INSERT
语句的批处理,它一次处理的内存不能超过几MB

因此,我很抱歉地告诉您,但您不能让SQL Server完全按照编写的脚本执行此脚本。不可能,不可能,不管你调整什么设置。但是,您有许多解决方案:

具体而言,您有三种选择:

  • 使用
    GO
    语句。SSMS和各种其他工具将其用作批处理分隔符。不是为整个脚本生成单个解析树,而是为批处理的每个段生成单个解析树,这些段由
    GO
    分隔。这是大多数人都会做的,而且让脚本在事务上保持安全是非常简单的,正如其他人所演示的,我在这里不再重复

  • 与其生成大量脚本来插入所有行,不如将数据保存在文本文件中(即逗号分隔)。然后使用。如果需要“可编写脚本”——即导入需要在与
    CREATE TABLE
    语句相同的脚本/事务中进行,请改用。尽管
    批量插入
    是一个未记录的操作,但信不信由你,它仍然可以放在
    开始传输
    /
    提交传输
    块中

  • 如果您真的非常希望
    INSERT
    是一个日志操作,并且不希望批量插入,那么您可以使用打开一个文本文件、excel文件等作为一个临时“表”,然后将其插入到新创建的表中。我通常不愿意推荐使用
    OPENROWSET
    ,但由于这显然是一个管理脚本,所以这并不是什么大问题


  • 之前的评论表明,您对#1感到不舒服,尽管这可能只是因为一个错误的假设,即它不能在单个事务中完成,在这种情况下,请参阅的答案。但如果你执意要换一种方式,我建议你使用#2,创建一个文本文件并使用
    批量插入
    。“安全”脚本的一个示例是:

    BEGIN TRAN
    
    BEGIN TRY
    
        CREATE TABLE MyTable (...)
    
        BULK INSERT  MyTable
        FROM 'C:\Scripts\Data\MyTableData.txt' 
        WITH (
            FIELDTERMINATOR = ',',
            ROWTERMINATOR = '\r\n',
            BATCHSIZE = 1000,
            MAXERRORS = 1
        )
    
        COMMIT
    
    END TRY
    
    BEGIN CATCH
    
        ROLLBACK
    
    END CATCH
    

    希望这能帮助你走上正轨。我敢肯定,这涵盖了您所有可用的“机箱内”选项——除此之外,您还必须开始编写实际的应用程序或shell脚本来完成这项工作,我认为在这里并不保证复杂性的水平。

    直到编辑完成,他的意思是在每千次插入后添加一个
    GO
    语句。我已经使用GO语句来解决这个问题,但我不想使用批处理执行,因为如果我有任何错误,我将无法回滚事务…然后从批处理插入到另一个表中,例如在tempdb中,然后将主表作为插入。。。从tempdd..x中选择
    BEGIN TRAN
    
    BEGIN TRY
    
        CREATE TABLE MyTable (...)
    
        BULK INSERT  MyTable
        FROM 'C:\Scripts\Data\MyTableData.txt' 
        WITH (
            FIELDTERMINATOR = ',',
            ROWTERMINATOR = '\r\n',
            BATCHSIZE = 1000,
            MAXERRORS = 1
        )
    
        COMMIT
    
    END TRY
    
    BEGIN CATCH
    
        ROLLBACK
    
    END CATCH