views:

420

answers:

6

I have an MS Access database (intolerably enough), and communicating with it through PHP (ODBC).

There is a DateTime field that I have to include in my INSERT statement. This field is NOT defined as "Required" in Access, meaning that it is indeed NULL-able, and in fact some of the rows in the Access database are already NULL.

The problem I'm having is simple: How to insert NULL through SQL? All the results I've found online have addressed it from something like Visual Basic or C#, whereas I'm using SQL through ODBC in PHP.

I have already tried the following:

INSERT INTO table_name (datetime_field) VALUES (NULL)
INSERT INTO table_name (datetime_field) VALUES (#NULL#)
INSERT INTO table_name (datetime_field) VALUES ('NULL')
INSERT INTO table_name (datetime_field) VALUES ('#NULL#')
INSERT INTO table_name (datetime_field) VALUES ('')

(There's about 30 other columns in my query.)

The exact error I get is 'Data type mismatch in criteria expression' when I try '' or NULL. The others return a parse error (understandably).

Please note that I have to include the field in the INSERT statement. The field has a default value, but in many cases the original data that I'm transporting has a NULL that must also be a NULL in the target database.

Thanks in advance!

A: 

Try just leaving it blank

(values fld1,,fld2)
Beth
I do not believe that will work, it causes a syntax error both in ADO and the query design window.
Remou
You could also try leaving out the reference to the field entirely- insert (fld1,fld3) values (val1,val3)
Beth
The OP has a default value defined for datetime_field, so wants an INSERT with Null to over-ride the default ... gotta include the field in the INSERT statement.
HansUp
Yeah, you're right, forgot about that. Since it's a date field, try zero.
Beth
Zero is a valid date. `Format(0, "dd mmm yyyy hh:nn ampm")` -> `30 Dec 1899 12:00 AM` The OP wants Null for datetime_field, so must INSERT Null. Zero is not the same.
HansUp
(sigh) OK, we also had an issue with a DB2 ODBC driver where it had to be configured a certain way to pass dates to MS Access dbs. It could be something with the ODBC driver settings.
Beth
I wondered about that, too. That's why I suggested the OP try the INSERT in Access directly ... without ODBC (or PHP) in the picture. It would be good to know if this is an Access problem or a problem with how the statement is built and fed to Access.
HansUp
I cannot leave it blank because it has a default value, so if I leave it, it won't be null.
Helgi Hrafn Gunnarsson
+1  A: 

Try the following. It works for me:

INSERT INTO sometable ( somedate, somethingelse )
SELECT Null AS Expr1, "foo" AS Expr2;

Basically, you are wrapping the null in the select query and letting SQL figure out how to represent it to the insert.


-- EDIT --

This SHOULD also work:

INSERT INTO sometable ( somedate, somethingelse )
values (Null , "foo");

But for some reason it doesn't with my default install.

On I hunch, I switched my DB from ANSI-89 to ANSI-92, and the VALUES method started working. I switched it back to ANSI-89, and it still works. Not only that, on ANY new database I create, it now also works. Weird... something in the installation must be getting changed, (and sticking) by the switching back and forth that's not just ANSI-89/92. This seems to be why we were getting different results.

You can switch the database ocwe by going to Office Logo->Access Options->OBJECT DESIGNERS->QUERY DESIGN. Change SQL Server Compatible Syntax (ANSI 92) - and checking "This database".

Ok, very odd.

CodeSlave
You must have a from table with Access, that is not going to work.
Remou
Replace the SELECT... with VALUES (Null, "foo")
David-W-Fenton
@Remou - I've tried it natively in MS Access 2007 - and it works. That was a straight copy and paste
CodeSlave
@David - Like wise, natively in MS Access 2007, values(null,"foo") doesn't work, and clearly it doesn't for the OP either, based upon their first try/example.
CodeSlave
You can INSERT a single-row SELECT without a FROM. If you wanted to UNION two SELECTs for the INSERT, that would be a different story.
HansUp
@CodeSlave Interesting, you are right on the select not needing a from table in this instance, however, I do not see why Values does not work for you. It is standard SQL and has worked on every version of Access in ADO and native since I can recall.
Remou
I just tested this SQL INSERT INTO tblCustomer (LastName, Created) VALUES ("Fenton", Null); in Access (the Created field has a default value), and it worked exactly as expected. I did it in the QBE SQL view, not using any special mode (e.g., default SQL 89). As @Remou says, this has always been supported in Access/Jet/ACE.
David-W-Fenton
@CodeSlave: there was obviously something wonky with your instance of Access. This has always worked in a default Access install, and there's no need to use SQL 92 mode to make it work.
David-W-Fenton
@David. What can I say? It was a vanilla install (all defaults), patched up to date, and I'd never swapped ANSI versions before. It failed the same way as the OP, and wouldn't let me insert using "values" at all. Flipping between 89 and 92 and back to 89 made it work. I would hypothesise that you, Remou and HansUp probably have flipped back and forth (or move to 92 permanently) on your installations before testing. The only way to tell is with a fresh installation; possibly on a VIRGIN workstation. I can't try it here right now, but I'll build something it on Tuesday/Wednesday to prove it out.
CodeSlave
I'll also note, when I built the insert query the first time in the query builder, it created it exactly as it was in my first example. After doing the 89-92-89 flip, it did it the second way. Anyone have a contact on MS's office development team. This is a neat one.
CodeSlave
None of the above works for me, +1 for trying though.
Helgi Hrafn Gunnarsson
I don't use SQL 92 except for testing things on SO! So, yes, my installation has been flipped, but support for SELECT-less inserts is not a SQL 92 issue in the first place. It's bog-standard SQL that was supported before SQL 92 mode even existed. I just tested it in A97 and it worked fine. My guess is that you have multiple versions of Access installed and ended up running in a version that had not completed the re-registration process after running one of the other versions.
David-W-Fenton
Sorry David, no dice. Vanilla install. But the fact that you have switched back and forth previously would be consistent with what I experienced. Like I said, I'll try it on a brand new machine this week.
CodeSlave
It's all a red herring as the OP isn't using Access at all, so our installations of Access don't have anything to do with his/her problem.
David-W-Fenton
I just tested on a different machine with a A2003 install that I know has never been flipped between SQL 89 and SQL 92 mode. The SELECT-less insert worked just fine. Trying the same thing on the same machine in A2010 (also never having SQL mode flipped) also worked. I don't know what the source of your problem is, but it isn't something inherent to Access or Jet/ACE.
David-W-Fenton
A: 

What are the libraries, you are using in order to talk to ODBC?
Could it be a problem with the syntax for null values, the way library interprets it?

See, if this page helps.
Note: I have not worked with PHP.

shahkalpesh
I'm using the ODBC components in PHP. It shouldn't matter though, since I'm just passing SQL to the ODBC driver.
Helgi Hrafn Gunnarsson
I don't work in PHP that often, but is there perhaps a PHP magic value ofr Null or something? That is, are you passing the word "Null" as a string in the SQL statement? It's a long shot...
David-W-Fenton
A: 

I tested with Access 2007 (Office Ultimate 2007) and SP2. Here is the DDL for the table I created:

Public Sub CreateTableDateTimeTest()
    Dim strSql As String
    strSql = "CREATE TABLE table_name (" & vbNewLine & _
        vbTab & "id COUNTER CONSTRAINT PrimaryKey PRIMARY KEY," & vbNewLine & _
        vbTab & "datetime_field DATETIME DEFAULT Date()," & vbNewLine & _
        vbTab & "text_field TEXT(255) NOT NULL);"
    CurrentProject.Connection.Execute strSql
End Sub

And here is my INSERT statement:

Public Sub InsertNullDate()
    Dim strSql As String
    strSql = "INSERT INTO table_name (datetime_field, text_field)" & vbNewLine & _
        "VALUES (Null, '" & CStr(Now()) & "');"
    ' test INSERT with both DAO and ADO '
    CurrentDb.Execute strSql, dbFailOnError
    CurrentProject.Connection.Execute strSql
End Sub

The INSERT succeeded when executed by both DAO and ADO. I ran the same test with both MDB and ACCDB database formats. In every case the INSERT was successful.

I'm at a loss to explain why the OP's INSERT fails.

HansUp
That's so weird. I've tried that, but it doesn't work for me. It keeps saying "Data type mismatch in criteria expression"
Helgi Hrafn Gunnarsson
And CodeSlave's suggestion didn't cure your problem? If that's the case, there is no way I can help you without seeing a copy of your database.
HansUp
+1  A: 

I don't know what the hell I did, but inserting Null works now.

Thanks to all who put effort into this! Access works in mysterious ways!

Helgi Hrafn Gunnarsson
A: 

I know you've already figured this out but there is also dbNull

masfenix