【发布时间】:2023-03-03 10:27:02
【问题描述】:
尝试将二进制文件插入 varbinary 列时,我遇到了一个奇怪的错误。架构如下:
具有此表对象的 SQL Server 2008 数据库:
CREATE TABLE [dbo].[BLOBs] (
[FileName] nvarchar(128) NOT NULL
, [FileExt] AS CASE
WHEN CHARINDEX(N'.', [FileName]) > 0 THEN REVERSE(SUBSTRING(REVERSE([FileName]), 1, CHARINDEX('.', REVERSE([FileName])) - 1))
ELSE NULL
END PERSISTED
, [FileBLOB] [varbinary](max) NOT NULL
, CONSTRAINT [PK_BLOBs] PRIMARY KEY CLUSTERED ( [FileName] ASC ) ON [DEFAULT]
) ON [DEFAULT];
GO
该表链接到一个 MS Access 2007 应用程序,作为表 BLOBs 包含这个“quick'n dirty”书面模块:
Public Function saveBLOB(strFQFN As String) As Long
10 If HandleErrors() Then On Error GoTo ERR_HANDLING
20 ErrorHandler().CallStack.PushCallStack "saveBLOB('" & strFQFN & "')"
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim fs As Long
Dim fn As String
Dim hdl As Integer
Dim blob() As Byte
30 fn = Right(strFQFN, Len(strFQFN) - InStrRev(strFQFN, "\"))
' read data from file
40 hdl = FreeFile()
50 Open strFQFN For Binary Access Read As #hdl
60 fs = LOF(hdl) - 1
70 ReDim blob(fs)
90 Get #hdl, , blob
' updateblob data in database
100 Set db = CurrentDb()
110 Set rs = db.OpenRecordset("BLOBs", dbOpenDynaset, dbSeeChanges)
120 rs.FindFirst ("[FileName] = '" & fn & "'")
130 If rs.NoMatch Then
140 rs.AddNew
150 rs!FileName = fn
160 Else
170 rs.Edit
180 End If
190 rs!FileBLOB = blob
200 rs.Update
210 saveBLOB = True
CLEANUP:
8000 Close #hdl
8010 On Error Resume Next
8020 rs.close
8030 Set rs = Nothing
8040 Set db = Nothing
8050 Erase blob
FINALLY:
9000 On Error GoTo 0
9010 ErrorHandler().CallStack.PopCallStack
9020 Exit Function
ERR_HANDLING:
9900 ErrorHandler().handleError ErrSinkScreen, "saveBLOB()"
9910 saveBLOB = False
9920 Resume CLEANUP
End Function
顺便说一句:ODBC 驱动程序是 SQL Server 版本 6.01.7601.17514 (SQLSRV32.DLL, 21.11.2010)。
只要我通过即时窗口调用该函数,一切都很好:
? saveBLOB("U:\example.txt")
-1
blob 数据已成功保存。现在有一个表单中的这个小子:
Private Sub UploadFile()
10 If HandleErrors() Then On Error GoTo ERR_HANDLING
20 ErrorHandler().CallStack.PushCallStack Me.Name & ".UploadFile()"
30 If (Not saveBLOB(Nz(Me!txtFQFN, vbNullString))) Then _
MsgBox "Beim Speichern des BLOBs in der Datenbank ist ein Fehler aufgetreten.", vbExclamation
FINALLY:
9000 ErrorHandler().CallStack.PopCallStack
9010 Exit Sub
ERR_HANDLING:
9900 ErrorHandler().handleError ErrSinkDatabase + ErrSinkScreen, Me.Name & ".UploadFile()"
9910 Resume FINALLY
End Sub
如果从这里调用saveBLOB(),则会发生错误(您试图将 Null 值分配给不是 Variant 数据类型的变量。):
更新:这似乎是一个大小问题。插入了一个新创建的 8KB 的 Excel 文件。导入 681KB 的文件失败。 Blob 列是varbinary(max)。根据 docs.microsoft.com:
max 表示最大存储大小为 2^31-1 字节。 所以 681KB 应该非常适合。
非常感谢您!
【问题讨论】:
-
奇怪的错误处理。它的源头在哪里?跳过编号的代码行作为不必要的github.com/rubberduck-vba/Rubberduck/issues/…
-
VBA 中没有集成调试器。必须实施错误堆栈等。我完全同意你的观点,代码需要(很多)改进。但是该应用程序现在已有 20 多年的历史了......
-
有人偷了你的调试器;(代码看起来还不错(除了缺少查询参数和两个刘海,假设使用了 Option Explict)。对于 vba 中的专业错误处理,请尝试vbwatchdog。
标签: vba ms-access ms-access-2007