SQL Server Native Client / ODBC Driver for SQL Server & DAO 无法将 blob > 8k 插入 varbinary(MAX) 字

Posted

技术标签:

【中文标题】SQL Server Native Client / ODBC Driver for SQL Server & DAO 无法将 blob > 8k 插入 varbinary(MAX) 字段【英文标题】:SQL Server Native Client / ODBC Driver for SQL Server & DAO can't insert blob > 8k into varbinary(MAX) field 【发布时间】:2017-10-17 01:50:10 【问题描述】:

考虑下表:

USE [MyTestDb]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[MyTable](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [FileBlob] [varbinary](max) NULL,
 CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

我想在这里插入一个 PDF 文件作为二进制 blob:

Function FileToBlob(FilePath As String) As Byte()    
    Dim File As Integer
    Dim FileBlob() As Byte
    File = FreeFile(0)
    Open FilePath For Binary Access Read As #File
    ReDim FileBlob(LOF(File) - 1)
    Get #File, , FileBlob
    Close #File

    FileToBlob = FileBlob
End Function

Private Sub Command1_Click()    
    On Error GoTo ErrHdl

    Dim db As DAO.Database
    Set db = DBEngine(0).OpenDatabase("", False, False, "ODBC;Driver=ODBC Driver 13 for SQL Server;Server=(local);Database=MyTestDb;Trusted_Connection=yes;DataTypeCompatibility=80")

    Dim rec As DAO.Recordset
    Set rec = db.OpenRecordset("MyTable", dbOpenDynaset, dbSeeChanges)

    rec.AddNew 

    rec![FileBlob] = FileToBlob("D:\TestFile.pdf")

    rec.Update

    rec.Close    
    db.Close

    Exit Sub

ErrHdl:    
    Dim i As Long
    For i = 0 To Errors.Count - 1
        Debug.Print Errors(i).Number, Errors(i).Description
    Next i
End Sub

rec.Update 运行时,错误处理程序会打印以下输出:

0 [Microsoft][ODBC Driver 13 for SQL Server]字符串数据,对 截断

3146 ODBC--调用失败。

我观察到以下更改导致 blob 被成功插入:

使用大小 如下切换到旧版“SQL 驱动程序”:"ODBC;Driver=SQL Server;..." 将 blob 列的数据类型从 varbinary(MAX) 更改为(已弃用)image 切换到 ADO 连接和记录集

但是,对我来说,这些都不代表真正的解决方案。有没有办法用原来的插入命令成功?

【问题讨论】:

DAO 看到的FileBlob 字段的类型是什么? Debug.Print rec.Fields("FileBlob").Type 打印 11,根据 this 站点,解析为 dbLongBinary 你试过AppendChunk吗? 同样的结果,不幸的是。我将 blob 拆分为多个 8k 字节数组,并通过AppendChunk 将它们一一添加。但是,对rec.Update 的最终调用失败并显示相同的错误消息。如果仅追加一个 8k 字节数组,则更新命令成功。 【参考方案1】:

您需要设置DataTypeCompatibility=0。 80 表示您仅限于 Sql Server 2005 数据类型,不包括 MAX 类型。

https://docs.microsoft.com/en-us/sql/relational-databases/native-client/system-requirements-for-sql-server-native-client

OLE DB 和 ADO 应用程序可以使用 SQL Server Native Client 的 DataTypeCompatibility 连接字符串关键字来操作旧数据类型。当 DataTypeCompatibility=80 时,OLE DB 客户端将使用 SQL Server 2005 表格数据流 (TDS) 版本而不是 TDS 版本进行连接。这意味着对于 SQL Server 2008 及更高版本的数据类型,下级转换将由服务器执行,而不是由 SQL Server Native Client 执行。这也意味着连接上可用的功能将仅限于 SQL Server 2005 功能集。

【讨论】:

不幸的是,错误仍然存​​在。使用DataTypeCompatibility=0 编辑连接字符串或完全删除DataTypeCompatibility 会导致相同的行为。

以上是关于SQL Server Native Client / ODBC Driver for SQL Server & DAO 无法将 blob > 8k 插入 varbinary(MAX) 字的主要内容,如果未能解决你的问题,请参考以下文章

navicat 连接sqlserver提示要安装 sql server native client

08001 - SQL Server Native Client 11.0 不支持连接到SQL Server 2000或更早的版本。

[08001] [Microsoft] [SQL Server Native Client 11.0] 命名管道提供程序:无法打开与SQL Server的连接

20180603_navicat 连接sqlserver提示要安装 sql server native client

错误 [42000] [Microsoft][SQL Native Client][SQL Server]关键字“SET”附近的语法不正确

SQL Server Native Client / ODBC Driver for SQL Server & DAO 无法将 blob > 8k 插入 varbinary(MAX) 字