Sql – Inserting NULL in an nvarchar fails in MSAccess

ms-accesssql-server

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…

Best Solution

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.