题:
我有一个从select语句中插入约4.5万个脚本的脚本。当我尝试运行它时,收到一条错误消息,指出我的内存不足。如何使该脚本运行?
内容:
- 添加了一些新的数据字段,以使一个应用程序可以与客户端使用的另一个应用程序完美兼容。
- 从客户端获取了一个包含所有数据的电子表格,这些数据将当前数据项映射到这些新字段的值。
- 将电子表格转换为插入语句。
- 如果我仅运行某些语句,则它可以工作,但整个脚本却不能。
- 不,没有错别字。
如果有其他方法,我应该加载此数据,请随时批评我并告知我。
题:
我有一个从select语句中插入约4.5万个脚本的脚本。当我尝试运行它时,收到一条错误消息,指出我的内存不足。如何使该脚本运行?
内容:
如果有其他方法,我应该加载此数据,请随时批评我并告知我。
Answers:
SQL Server 2005的最大批处理大小为65,536 *网络数据包大小(NPS),其中NPS通常为4KB。达到256 MB。这意味着您的插入语句平均每个5.8 KB。这似乎不对,但也许那里有多余的空间或不寻常的东西。
我的第一个建议是在每个INSERT语句之后添加一个“ GO”语句。这会将您的45,000个INSERT语句单批分解为45,000个单独的批处理。这应该更容易消化。小心,如果其中一个插入失败,您可能很难找到罪魁祸首。您可能想通过交易来保护自己。如果您的编辑器具有良好的搜索和替换(可以让您搜索并替换\ r \ n之类的返回字符)或宏工具,则可以快速添加这些语句。
第二个建议是使用向导直接从Excel导入数据。该向导将在后台为您构建一个小的SSIS程序包,然后运行该程序包。它不会有这个问题。
GO
后每说法?好吧,我想您是否正在使用其他确定的脚本生成它们。否则,我每隔1000 INSERT
秒就放一个。关于使事务原子化并最大程度地减少事务的大小,为什么不将所有行加载到临时表或表变量中,然后从那里一次加载到目标表?
BULK INSERT
还是bcp
比45,000个插入语句更合适的选项。
如果您需要坚持使用insert语句,则可以考虑以下几种选择:
答:使用事务并在每条中包装100或500或1000条语句,以最大程度地减少对日志和批处理的影响。例如
BEGIN TRANSACTION;
INSERT dbo.table(a, ...) SELECT 1, ...
INSERT dbo.table(a, ...) SELECT 2, ...
...
INSERT dbo.table(a, ...) SELECT 500, ...
COMMIT TRANSACTION;
GO
BEGIN TRANSACTION;
INSERT dbo.table(a, ...) SELECT 1, ...
INSERT dbo.table(a, ...) SELECT 2, ...
...
INSERT dbo.table(a, ...) SELECT 500, ...
COMMIT TRANSACTION;
GO
B:一次使用UNION ALL
100或500个语句,而不是单个插入语句,例如
INSERT dbo.table(a, ...)
SELECT 1, ...
UNION ALL SELECT 2, ...
...
UNION ALL SELECT 500, ...
GO
INSERT dbo.table(a, ...)
SELECT 501, ...
UNION ALL SELECT 502, ...
...
UNION ALL SELECT 1000, ...
GO
为了简洁起见,我省略了错误处理,但要点是,我绝不会尝试将单个45,000条单独的语句发送到SQL Server。
VARCHAR(800)
的编译时间在2008年的dev实例上插入了1000行,其中包含10 列,因为它做了很多不必要的比较值的工作,而不是继续插入值(执行很多操作)参数化时更快,没有值可查看)。尽管在2012年有了很大的改进,但非线性模式仍然存在并且应在以后的版本中进行修复。
我不确定为什么会出现内存不足错误,但是有一种更简单的方法。
如果可以将电子表格中的数据导出为定界格式(例如csv),则可以使用SSMS中的数据导入向导为您插入数据:
使用多个SqlBulkCopy,创建一个临时表。将新数据插入到临时表中,然后将临时表中的数据合并到现有表中。使用C#SqlBulkCopy.WriteToServer方法(DataTable)的示例。希望能帮助到你
是的,我们可以做到这一点,我尝试使用BCP(大容量复制程序)方法来避免内存不足的问题。
注意:在SQL Server 2014上尝试过。
在BCP中,首先我们需要将源数据库数据导出到bcp文件(在本地目录文件夹中),然后需要将该bcp文件导入到目标数据库。
以下是步步高升的步骤:
注意:
a)确保目标数据库中存在空表
b)确保C盘中存在Temp文件夹
使用如下所示的命令创建一个名为Export_Data.bat的蝙蝠文件:
bcp.exe [Source_DataBase_Name].[dbo].[TableName] OUT "C:\Temp\TableName.bcp" -S "Computer Name" -U "SQL Server UserName" -P "SQL Server Password" -n -q
暂停
运行该bat文件,结果将在Temp文件夹中生成一个bcp文件
然后使用以下命令创建另一个名为Import_Data.bat的蝙蝠文件:
bcp.exe [Destination_DataBase_Name].[dbo].[TableName] IN "C:\Temp\TableName.bcp" -S "Computer Name" -U "SQL Server UserName" -P "SQL Server Password" -n -q
暂停
现在我们开始!