在 MSAccess 中,在 nvarchar 中插入 NULL 失败

发布于 2024-07-23 16:33:27 字数 2609 浏览 4 评论 0原文

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

我在 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 个子程序中的任何一个插入记录,它们都会失败并显示 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...

I'm experiencing something a bit strange.

I have a table on SQL Server 2008, say StockEvent that contains a Description field defined as nVarchar(MAX).
The field is set to be Nullable, has no default value and no index on it.

That table is linked into an Access 2007 application, but if I explicitly insert a NULL into the field, I'm systematically getting:

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

So the following bits of code in Access both reproduce the error:

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

However, if I do the same thing from the SQL Server Management Studio, I get no error and the record is correctly inserted:

INSERT INTO StockEvent (Description) VALUES (NULL);

It doesn't appear to be machine-specific: I tried on 3 different SQL Server installations and 2 different PCs and the results are consistent.
I initially though that the problem may be in my Access application somewhere, but I isolated the code above into its own Access database, with that unique table linked to it and the results are consistent.

So, is there some known issue with Access, or ODBC and inserting NULL values to nvarchar fields?

Update.
Thanks for the answers so far.
Still no luck understanding why though ;-(

I tried with an even smaller set of assumptions: I created a new database in SQL Server with a single table StockEvent defined as such:

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

Then linked that table though ODBC into the test Access 2007 application.
That application contains no forms, nothing except the exact 2 subroutines above.

  • If I click on the linked table, I can edit data and add new records in datasheet mode.
    Works fine.
  • If I try any of the 2 subs to insert a record, they fail with the 3155 error message.
    (The table is closed and not referenced anywhere else and the edit datasheet is closed.)
  • If I try the SQL insert query in SQL Server Management Studio, it works fine.

Now for the interesting bit:

  • It seems that anything as big or bigger than nvarchar(256), including nvarchar(MAX) will fail.
  • Anything with on or below nvarchar(255) works.
    It's like Access was considering nvarchar as a simple string and not a memo if its size is larger than 255.
  • Even stranger, is that varchar(MAX) (wihout the n) actually works!

What I find annoying is that Microsoft's own converter from Access to SQL Server 2008 converts Memo fields into nvarchar(MAX), so I would expect this to work.

The problem now is that I need nvarchar as I'm dealing with Unicode...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

千里故人稀 2024-07-30 16:33:27

好的,我可能找到了相关的答案: Ms Access 使用 nvarchar(max) 链接表

我尝试使用标准 SQL Server 驱动程序而不是 SQL Server Native Client 驱动程序,并且 nvarchar(MAX) 在该旧驱动程序中按预期工作。

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

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

OK, I may have found a related answer: Ms Access linking table with nvarchar(max).

I tried using the standard SQL Server driver instead of the SQL Server Native Client driver and nvarchar(MAX) works as expected with that older driver.

It really annoys me that this seems to be a long-standing, unfixed, bug.
There is no valid reason why nvarchar should be erroneously interpreted as a string by one driver and as a memo when using another.
In both cases, they appear as memo when looking a the datatype under the table design view in Access.

If someone has any more information, please leave it on this page. I'm sure others will be glad to find it.

暗藏城府 2024-07-30 16:33:27

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

That should be legal syntax. Is it possible that the field you are try to give a null value is linked to other fields that don't allow null values?

后eg是否自 2024-07-30 16:33:27

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

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

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

Potential concurrency problem... Is the record open by another instance of Access on the same or a different machine, or does a form bound to the table have the record open in the same instance of Access on the same machine?

Renaud, try putting something in one of the other fields when you do the insert.

Also, try inserting an empty string ("") instead of a null.

凯凯我们等你回来 2024-07-30 16:33:27

Renaud,

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

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

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

Renaud,

Did you try running a SQL Profiler trace? If you look at the Errors and Warnings category it should kick out an error if your insert failed as a result of a SQL Server constraint.

If you don't see any errors, you can safely assume that the problem is in your application.

Also, are you sure you're actually connected to SQL Server? Is CurrentDB not the same variable you're using in your Access test loop?

溺渁∝ 2024-07-30 16:33:27

我遇到了另一个问题(这里是我的帖子:链接文本

在某些非常罕见的情况下,保存具有更改的备注字段的行时会出现错误 - 与我之前的帖子中解释的结构相同,但驱动 sql2000-servers 并且它是适当的 odbc- 。

唯一奇怪的修复是:使用数据类型 [timestamp] 的列扩展 sql-server 上的表结构并刷新 odbc-links,这会起作用并释放此列中的显示停止程序 行...

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

i got annother issue (here my post: link text

In some very rare cases an error arises when saving a row with a changed memo field - same construct explained in my former post but driving sql2000-servers and it's appropriate odbc-driver (SQL SERVER).

The only weired fix is: to expand the table structure on sql-server with a column of datatype [timestamp] and refresh the odbc-links. That works and releases the show-stopper in this column on this one row ...

Maybe this info can help someone - for me it's history in going further to odbc with sql2008 in changing the datatypes [text] to [varchar(max)].

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文