- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
(请阅读下面的更新部分,为了清楚起见,我也保留了原始问题)
我正在将许多文件插入到为文件流配置的 SQL Server 数据库中。
我正在循环中将文件从文件夹插入到数据库表中。
一切都很顺利,直到我尝试插入 600 MB 文件。
当它插入时,任务管理器中的内存使用量超过了 600MB,我遇到了错误。
数据库大小 < 1 GB,文档总大小为 8 GB,我使用的是 SQL Server Express R2,根据文档,只有在尝试插入大于 10 GB 的文档时,我才会遇到问题(明确限制)- 当前数据库大小。
谁能告诉我为什么会出现这个错误?这对我来说非常重要。
赏金更新:
我提供了150,因为这对我来说非常重要!
这似乎是Delphi内存管理器的限制,试图插入大于500MB的文档,我没有检查确切的阈值,反正它在500到600MB之间)。我使用 SDAC 组件,特别是 TMSQuery (但我认为可以使用 TDataset 后代完成同样的操作),将文档插入到具有 PK (ID_DOC_FILE) 和 varbinary(max) 字段 (DOCUMENT) 的表中:
procedure UploadBigFile;
var
sFilePath: String;
begin
sFilePath := 'D:\Test\VeryBigFile.dat';
sqlInsertDoc.ParamByName('ID_DOC_FILE').AsInteger := 1;
sqlInsertDoc.ParamByName('DOCUMENT').LoadFromFile(sFilePath, ftblob);
sqlInsertDoc.Execute;
sqlInsertDoc.Close;
end;
SDAC 团队告诉我这是 Delphi 内存管理器的限制。现在,由于 SDAC 不支持文件流,我无法执行第一个答案中 c# 中建议的操作。唯一的解决方案是向 Embarcadero 报告并要求修复错误吗?
最终更新:
真的谢谢所有回答我的人。当然,对于 Express 版来说,插入大 blob 可能是个问题(因为 1 GB 内存的限制),无论如何,我在企业版上遇到了错误,而且这是一个“delphi”错误,而不是 sql server 错误。所以我认为我接受的答案确实解决了问题,即使我现在没有时间验证它。
最佳答案
SDAC team told me this is a limitation of Delphi memory manager
对我来说,这看起来像是一个简单的答案,我进行了调查。我没有 SDAC 组件,也不使用 SQL Server,我最喜欢的是 Firebird SQL 和 IBX 组件集。我尝试使用 IBX 将 600Mb blob 插入表中,然后使用 ADO 尝试相同的操作(涵盖两种连接技术,都是 TDataSet 的后代)。我发现事实是在中间的某个地方,它并不是真正的内存管理器,这不是 SDAC 的错(嗯...他们有能力对此做点什么,如果更多的人尝试将 600 Mb blob 插入到数据库,但这与本讨论无关)。 “问题”出在Delphi 中的DB 代码上。事实证明,Delphi 坚持使用单个 Variant 来保存可能加载到参数中的任何类型的数据。这是有道理的,毕竟我们可以将很多不同的东西加载到 INSERT 的参数中。第二个问题是,Delphi 希望将该 Variant 视为 VALUE 类型:它将它在列表中复制两次,也许三次!从文件加载参数时会立即生成第一个副本。当参数准备发送到数据库引擎时,会创建第二个副本。
写这个很容易:
var V1, V2:Variant;
V1 := V2;
并且适用于整数、日期和小字符串,但是当 V2 是 600 Mb 变体数组时,该赋值显然会生成完整副本!现在考虑一下未在“3G”模式下运行的 32 位应用程序的可用内存空间。只有 2 Gb 的寻址空间可用。其中一些空间是保留的,一些空间用于可执行文件本身,然后是库,然后是为内存管理器保留的一些空间。在进行第一个 600 Mb 分配后,可能没有足够的可用寻址空间来分配其他 600 Mb 缓冲区!因此,可以肯定地将其归咎于内存管理器,但话又说回来,为什么数据库内容到底需要 600 Mb 怪物的另一个副本?
尝试将文件分割成更小、更易于管理的 block 。将数据库表设置为具有 3 个字段:ID_DOCUMENT、SEQUENCE、DOCUMENT。还将表上的主键设置为(ID_DOCUMENT,SEQUENCE)。接下来试试这个:
procedure UploadBigFile(id_doc:Integer; sFilePath: String);
var FS:TFileStream;
MS:TMemoryStream;
AvailableSize, ReadNow:Int64;
Sequence:Integer;
const MaxPerSequence = 10 * 1024 * 1024; // 10 Mb
begin
FS := TFileStream.Create(sFilePath, fmOpenRead);
try
AvailableSize := FS.Size;
Sequence := 0;
while AvailableSize > 0 do
begin
if AvailableSize > MaxPerSequence then
begin
ReadNow := MaxPerSequence;
Dec(AvailableSize, MaxPerSequence);
end
else
begin
ReadNow := AvailableSize;
AvailableSize := 0;
end;
Inc(Sequence); // Prep sequence; First sequence into DB will be "1"
MS := TMemoryStream.Create;
try
MS.CopyFrom(FS, ReadNow);
sqlInsertDoc.ParamByName('ID_DOC_FILE').AsInteger := id_doc;
sqlInsertDoc.ParamByName('SEQUENCE').AsInteger := sequence;
sqlInsertDoc.ParamByName('DOCUMENT').LoadFromStream(MS, ftblob);
sqlInsertDoc.Execute;
finally MS.Free;
end;
end;
finally FS.Free;
end;
sqlInsertDoc.Close;
end;
关于sql-server - 将 600MB 文件作为文件流数据插入 SQL Server Express 时出现内存不足错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3247324/
本周我将在 Windows Server 2008 上设置一个专用的 SQL Server 2005 机器,并希望将其精简为尽可能简单,同时仍能发挥全部功能。 为此,“服务器核心”选项听起来很有吸引力
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 8 年前。 Improve
我获取了 2014 版本数据库的备份,并尝试在另一台服务器中将其恢复到具有相同名称和登录名的数据库中。此 SQL Server 版本是 2016。 恢复备份文件时,出现此错误: TITLE: Micr
我获取了 2014 版本数据库的备份,并尝试在另一台服务器中将其恢复到具有相同名称和登录名的数据库中。此 SQL Server 版本是 2016。 恢复备份文件时,出现此错误: TITLE: Micr
TFS 是否提供任何增强的方法来存储对 sql server 数据库所做的更改,而不是使用它来对在数据库上执行的 sql 语句的文本文件进行版本控制? 或者我正在寻找的功能是否仅在第 3 方工具(如
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我即将将我的 SQL Server 2012 实例升级到 SQL Server 2014。 我已经克隆了主机 Windows VM 并将其重命名为 foo-2012至 foo-2014 . 重新启动时
我想为 SQL Server 登录授予对数据库的访问权限。我知道 sp_grantdbaccess,但它已被弃用。我可以改用什么以及如何检查登录名是否还没有访问数据库的权限? 场景:UserA 创建数
客户别无选择,只能在接下来的几天内从 sql server 2000 迁移到 2008。测试显示 2005 年的重要功能出现了 Not Acceptable 性能下降,但 2008 年却没有。好消息是
我有一个测试数据库,我需要将其导出到我们客户的测试环境中。 这将是一次性的工作。 我正在使用 SQL Server 2005(我的测试数据库是 SQL Server 2005 Express) 执行此
我需要将一个 CSV 文件导入到 mongoDB 不幸的是我遇到了以下错误: error connecting to host: could not connect to server: se
我以为 R2 是一个补丁/服务包。我一直在寻找下载,但没有看到。因此,我假设 R2 是一个新版本,并且我需要 sqlserver 2008 r2 的安装介质来进行升级? 另外,我需要为新许可证付费吗?
我无法使用 SQL Server Management Studio 连接到 SQL Server。 我有一个连接字符串: 我尝试通过在服务器名中输入 myIP、在登录名中输入 MyID、在密码中
我们希望使用 SQL Server 加密来加密数据库中的几个列。我们还需要在生产和测试环境之间传输数据。看来最好的解决方案是在生产和测试服务器上使用相同的主 key 、证书和对称 key ,以便我可以
有没有可以分析 SQL Server 数据库潜在问题的工具? 例如: a foreign key column that is not indexed 没有 FILL FACTOR 的 uniquei
我正在尝试从我的 SQL 2012 BI 版本建立复制,但我收到一条奇怪的错误消息! "You cannot create a publication from server 'X' because
如果您使用 SQL Server 身份验证 (2005),登录详细信息是否以明文形式通过网络发送? 最佳答案 如您所愿,安全无忧... 您可以相当轻松地配置 SSL,如果您没有受信任的证书,如果您强制
我想将数据从一个表复制到不同服务器之间的另一个表。 如果是在同一服务器和不同的数据库中,我使用了以下 SELECT * INTO DB1..TBL1 FROM DB2..TBL1 (to copy w
我希望得到一些帮助,因为我在这个问题上已经被困了 2 天了! 场景:我可以从我的开发计算机(和其他同事)连接到 SERVER\INSTANCE,但无法从另一个 SQL Server 连接。我得到的错误
我正在尝试从我的 SQL 2012 BI 版本建立复制,但我收到一条奇怪的错误消息! "You cannot create a publication from server 'X' because
我是一名优秀的程序员,十分优秀!