如何将HCL Notes附件与图片存储到MS Sql数据库?遇数组溢出问题
解决HCL Notes附件转存MS SQL的两个问题
一、绕过Notes Byte数组上限问题
Notes原生Byte数组上限为32767,直接定义大数组会触发溢出,推荐用NotesStream对象替代数组,可直接读取完整附件数据,无需拆分:
Dim session As New NotesSession Dim db As NotesDatabase Dim doc As NotesDocument Dim rtitem As NotesRichTextItem Dim att As NotesEmbeddedObject Dim stream As NotesStream Set db = session.CurrentDatabase Set doc = db.GetDocumentByUNID("目标文档UNID") '替换为实际文档UNID Set rtitem = doc.GetFirstItem("Body") '替换为存储附件的富文本字段名 Set att = rtitem.EmbeddedObjects(0) '取第一个附件,可循环处理多个附件 '初始化Stream以二进制模式读取附件 Set stream = session.CreateStream() Call stream.Open(att.Source, "binary")
二、将二进制数据存入MS SQL的varbinary字段
使用ADO参数化查询,直接将NotesStream的二进制数据传入SQL参数,避免手动拼接数组:
Dim conn As Object Dim cmd As Object Set conn = CreateObject("ADODB.Connection") Set cmd = CreateObject("ADODB.Command") '替换为你的SQL Server连接字符串 conn.Open "Provider=SQLOLEDB;Data Source=你的SQL服务器地址;Initial Catalog=目标数据库名;User ID=账号;Password=密码;" '参数化插入语句,避免SQL注入 cmd.CommandText = "INSERT INTO 附件存储表(关联文档ID, 附件内容) VALUES (@DocUNID, @AttachmentData)" cmd.ActiveConnection = conn '添加文档UNID参数 cmd.Parameters.Append cmd.CreateParameter("@DocUNID", 200, 1, 255, doc.UniversalID) '200对应adVarChar类型 '添加附件二进制数据参数 Dim param As Object Set param = cmd.CreateParameter("@AttachmentData", 205, 1) '205对应adVarBinary类型 param.Value = stream.Read() '读取整个Stream的二进制内容 cmd.Parameters.Append param '执行插入操作 cmd.Execute() '释放资源 Call stream.Close() Set stream = Nothing Set att = Nothing Set rtitem = Nothing Set doc = Nothing Set db = Nothing Set cmd = Nothing conn.Close() Set conn = Nothing
备选方案:用分段数组处理(兼容老版本Notes)
如果必须使用数组,可通过分段读取附件字节,拼接为完整的动态数组:
Dim buffer() As Byte Dim totalBytes As Long Dim chunkSize As Integer chunkSize = 32767 '每次读取的最大块大小 totalBytes = att.FileSize '定义存储完整数据的动态数组 Dim allBytes() As Byte ReDim allBytes(0 To totalBytes - 1) As Byte Dim pos As Long pos = 0 Do While pos < totalBytes '根据剩余字节数调整当前块大小 If (totalBytes - pos) < chunkSize Then ReDim buffer(0 To totalBytes - pos - 1) As Byte Else ReDim buffer(0 To chunkSize - 1) As Byte End If Call att.ExtractFileData(buffer) '读取当前块数据 '复制到总数组 Call LSet(allBytes(pos To pos + UBound(buffer)), buffer) pos = pos + UBound(buffer) + 1 Loop '后续将allBytes作为参数传入SQL即可,逻辑同上方ADO参数化查询
注意事项
- SQL字段建议使用
varbinary(max)类型,支持最大2GB存储,完全覆盖你0.5-3MB的附件需求。 - 处理多个附件时,可循环遍历
rtitem.EmbeddedObjects集合。
内容的提问来源于stack exchange,提问作者user1575786
相关产品推荐
相关产品推荐

