【问题标题】:Inserting NULL in an nvarchar fails in MSAccess在 MS Access 中,在 nvarchar 中插入 NULL 失败
【发布时间】:2009-06-11 04:07:12
【问题描述】:

我遇到了一些奇怪的事情。

我在 SQL Server 2008 上有一个表,例如 StockEvent,其中包含定义为 nVarchar(MAX)Description 字段。
该字段设置为 Nullable,没有默认值,也没有索引。

该表已链接到 Access 2007 应用程序,但如果我在字段中显式插入 NULL,我会系统地得到:

Run-time Error '3155' ODBC--insert on a linked table 'StockEvent' failed.

因此 Access 中的以下代码位都重现了错误:

Public Sub testinsertDAO()
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Set db = CurrentDb
    Set rs = db.OpenRecordset("StockEvent", _
                              dbOpenDynaset, _
                              dbSeeChanges + dbFailOnError)
    rs.AddNew
    rs!Description = Null
    rs.Update
    rs.Close
    Set rs = Nothing
    Set db = Nothing
End Sub

Public Sub testinsertSQL()
    Dim db As DAO.Database
    Set db = CurrentDb
    db.Execute "INSERT INTO StockEvent (Description) VALUES (NULL);", _
               dbSeeChanges
    Set db = Nothing
End Sub

但是,如果我从 SQL Server Management Studio 中执行相同的操作,则不会出现错误并且记录已正确插入:

INSERT INTO StockEvent (Description) VALUES (NULL);

它似乎不是特定于机器的:我尝试了 3 个不同的 SQL Server 安装和 2 个不同的 PC,结果是一致的。
我最初认为问题可能出在我的 Access 应用程序的某个地方,但我将上面的代码隔离到它自己的 Access 数据库中,并链接到该唯一表并且结果是一致的。

那么,Access 或 ODBC 是否存在一些已知问题并将NULL 值插入nvarchar 字段?

更新。
感谢您到目前为止的答案。
仍然没有运气理解为什么;-(

我尝试了一组更小的假设:我在 SQL Server 中创建了一个新数据库,其中定义了一个表 StockEvent

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[StockEvent](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Description] [nvarchar](max) NULL
) ON [PRIMARY]

GO

然后通过 ODBC 将该表链接到测试 Access 2007 应用程序中。
该应用程序不包含任何表单,除了上面确切的 2 个子例程。

  • 如果我单击链接表,我可以在数据表模式下编辑数据和添加新记录。
    工作正常。
  • 如果我尝试使用 2 个 subs 中的任何一个插入记录,它们都会失败并显示 3155 错误消息。
    (该表已关闭且未在其他任何地方引用,并且编辑数据表已关闭。)
  • 如果我在 SQL Server Management Studio 中尝试 SQL 插入查询,它工作正常。

现在是有趣的一点:

  • 似乎任何大于或大于nvarchar(256) 的东西,包括nvarchar(MAX) 都会失败。
  • nvarchar(255) 以上或以下的任何内容都有效。
    就像 Access 将 nvarchar 视为一个简单的字符串,而不是一个大于 255 的备忘录。
  • 更奇怪的是,varchar(MAX)(没有 n)确实有效!

我觉得烦人的是,Microsoft 自己的从 Access 到 SQL Server 2008 的转换器将 Memo 字段转换为 nvarchar(MAX),所以我希望它能够工作。

现在的问题是我需要 nvarchar,因为我正在处理 Unicode...

【问题讨论】:

  • 我得到了类似的东西。请让我在这里发布我的问题的链接:http://stackoverflow.com/questions/1686431/varcharmax-datatype-odbc-mapping-to-ms-access2003 我刷新了登录 SQL-Server 2008 本身的 ODBC-Links,并从 clinet windows2003 64 位 Citrix-server 获得了不同的数据类型映射。第一次尝试是完美的 varchar(max) 映射到 ms-access 数据类型“备忘录”。第二次尝试是将 varchar(max) 映射到 ms-access 数据类型“text(255)”的效果不佳。并且不要忘记,

标签: sql-server ms-access


【解决方案1】:

好的,我可能找到了相关答案:Ms Access linking table with nvarchar(max)

我尝试使用标准 SQL Server 驱动程序而不是 SQL Server Native Client 驱动程序,而 nvarchar(MAX) 与旧驱动程序一起正常工作。

这似乎是一个长期存在的、未修复的错误,这让我非常恼火。
没有正当理由为什么 nvarchar 应该被一个驱动程序错误地解释为 string 并在使用另一个驱动程序时被错误地解释为 memo
在这两种情况下,当在 Access 的表设计视图下查看数据类型时,它们都显示为 memo

如果有人有更多信息,请在此页面上留下。我相信其他人会很高兴找到它。

【讨论】:

  • 感谢您发布答案。我绝对可以将其视为一个陷阱:)
【解决方案2】:

这应该是合法的语法。您尝试提供空值的字段是否可能链接到其他不允许允许空值的字段?

【讨论】:

  • 表中的所有其他字段都允许 Null,除了用作主键的 Identity 字段。我不明白的是,如果案例与表定义有关,那么它在 SQL Server 管理工作室控制台中也不起作用。
  • 是的,我只是在这里吐口水:) 这个不可行,但是您可以更改链接表的一些属性,并且 required 就是其中之一。如果您进入链接表的设计视图,是否有任何机会将“必需”设置为“是”?我还会检查链接表和源表,以确保没有违反验证规则。
【解决方案3】:

潜在的并发问题...记录是由同一台或不同机器上的另一个 Access 实例打开的,还是绑定到表的表单在同一台机器上的同一个 Access 实例中打开了记录?

Renaud,在插入时尝试在其他字段之一中添加一些内容。

另外,请尝试插入一个空字符串 ("") 而不是 null。

【讨论】:

  • 没有。我提取了您在问题中看到的代码,这是 Access 应用程序中唯一的内容,没有表单,没有其他表试图访问数据,没有并发问题。
【解决方案4】:

雷诺,

您是否尝试过运行 SQL Profiler 跟踪?如果您查看错误和警告类别,如果您的插入因 SQL Server 约束而失败,它应该会抛出一个错误。

如果您没有看到任何错误,您可以放心地认为问题出在您的应用程序中。

另外,您确定您实际上已连接到 SQL Server 吗? CurrentDB 与您在 Access 测试循环中使用的变量不同吗?

【讨论】:

  • 嗨亚伦。更新甚至没有到达探查器,因此它显然是 ODBC 或 Access 问题,就在发送数据之前。我已经更新了上面的调查结果。
【解决方案5】:

我遇到了另一个问题(这里是我的帖子:link text

在极少数情况下,保存带有更改的备注字段的行时会出现错误 - 我在之前的帖子中解释了相同的结构,但驱动 sql2000-servers 并且它是适当的 odbc-driver (SQL SERVER)。

唯一奇怪的修复是:用数据类型 [timestamp] 的列扩展 sql-server 上的表结构并刷新 odbc-links。这有效并在这一行的这一列中释放了显示停止器...

也许此信息可以帮助某人 - 对我来说,使用 sql2008 将数据类型 [text] 更改为 [varchar(max)] 是进一步使用 odbc 的历史。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-06
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多