SQL Server 2005错误701 - 内存不足

Tuf*_*ufo 8 memory sql-server-2005

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

Msg 701, Level 17, State 123
There is insufficient system memory to run this query.
Run Code Online (Sandbox Code Playgroud)

我正在使用4GB内存,64位Windows 7旗舰版,Core2Duo T6400(2GHz)......

有没有办法执行它而不接收此消息(可能强制SQL Server使用交换文件?)或部分执行它(如100次查询一次)...

该文件基本上是一个CREATE TABLE,后面是INSERT查询的thousads,我有很多这些(使用ABC DBF Converter将.DBF文件转换为SQL查询)

任何想法将非常感谢!

Aar*_*ght 9

这个问题实际上似乎经常出现在这里. 马克有正确的(也是最常用的)答案,但让我尝试添加我能做的更清楚的答案.

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

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

所以我很遗憾地告诉你这个但是你不能让SQL Server完全按照它编写的那样执行这个脚本.没有办法,没有办法,无论你调整什么设置都没关系.但是,您可以使用许多选项来解决它:

具体来说,您有三个选择:

  1. 使用GO陈述.这被SSMS和各种其他工具用作批处理分隔符.不是为整个脚本生成单个分析树,而是为分隔的批次的每个分段生成单独的分析树GO.这是大多数人所做的事情,并且使脚本在事务上安全非常简单,正如其他人所证明的那样,我在此不再重复.

  2. 而不是生成一个大型脚本来插入所有行,而是将数据保存在文本文件中(即以逗号分隔).然后使用bcp实用程序导入它.如果您需要这个"脚本化" - 即导入需要在与CREATE TABLE语句相同的脚本/事务中进行,那么请使用BULK INSERT.虽然BULK INSERT是一个非记录操作,不管你信不信,它仍然可以放在BEGIN TRAN/ COMMIT TRANblock中.

  3. 如果你真的,真的希望INSERT成为一个记录操作,并且不希望批量发生插入,那么你可以使用OPENROWSET打开一个文本文件,excel文件等作为临时"表" ,然后将其插入到新创建的表中.我通常不愿意推荐使用OPENROWSET,但由于这显然是一个管理脚本,它并不是一个真正的主要问题.


之前的评论表明你对#1感到不舒服,尽管这可能仅仅是因为不能在一次交易中做错的假设,在这种情况下请参阅托马斯的回答.但如果你已经走了另一条路,我建议你去#2,创建一个文本文件并使用BULK INSERT."安全"脚本的一个示例是:

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
Run Code Online (Sandbox Code Playgroud)

希望这有助于您走上正确的轨道.我很确定这涵盖了你所有可用的"盒子里"选项 - 除此之外,你必须开始编写实际的应用程序或shell脚本来完成这项工作,我认为这种复杂程度并不高真的有理由在这里.


use*_*019 5

您可以将文件分成几批 - 例如,在每一千次插入后添加一条 go 语句

例如

insert db..table( field list ) values  ...
insert db..table( field list ) values  ...
go
insert db..table( field list ) values  ...
...
insert db..table( field list ) values  ...
go
Run Code Online (Sandbox Code Playgroud)

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

  • 然后从批处理插入到另一个表中,例如在 tempdb 中,然后将主表作为插入...从 tempdd..x 中选择 (5认同)