Несогласованные результаты при проверке нулевых значений (Jet DAO и ACE DAO)

В программе VB6, обращающейся к файлу MDB, выполняется следующий SQL-запрос:

> Select * FROM [table1] WHERE ([type] = 1 OR [type] = 2 OR [type] = 6)
> AND ([notes] = Null OR [notes] = '0') AND [date] >= 
> cvdate('09/03/2013') ORDER BY [date], [column2]

Если я ссылаюсь на Microsoft Access 14.0 Object Library в программе, возвращаемый набор записей имеет 0 строк.

Если я ссылаюсь на Microsoft DAO 3.51 Object Library, возвращаемый набор записей содержит более 100 строк.

В чем причина этой разницы? Есть ли разница между тем, как два провайдера обрабатывают тест для Null? Является ли это критическим изменением для доступа ACE DAO к старым файлам MDB?


person CJ7    schedule 20.04.2013    source источник


Ответы (2)


WHERE ... [notes] = Null — это нестандартный SQL. Нулевое распространение потенциально может привести к тому, что любое выражение, включающее Null, будет возвращать Null. Следовательно, выражение [notes] = Null (которое вы предполагали использовать как логическое выражение) вполне может вернуть Null, которое не является ни True, ни False.

То, как обработчик запросов обрабатывает это значение Null, действительно может различаться от одного механизма базы данных к другому: он может интерпретировать Null как False, или он может просто игнорировать результат, или может вызвать ошибку. Также обратите внимание, что распространение null может свернуть все ваше предложение WHERE до Null, если...

(some other condition) AND (Null)

... оценивается как Null.

Стандартный SQL будет ([notes] IS NULL), а эквивалент Jet/ACE будет IsNull([notes]). Оба они всегда будут возвращать либо True, либо False.

person Gord Thompson    schedule 20.04.2013

DAO 3.51 сильно устарел. Он был заменен DAO 3.6 много лет назад. Вместо этого используйте 3.6, а затем посмотрите, возвращает ли эта версия вашего запроса одинаковые результаты как из DAO 3.6, так и из ACEDAO:

SELECT *
FROM [table1]
WHERE
        [type] IN (1,2,6)
    AND ([notes] Is Null OR [notes] = '0')
    AND [date] >= cvdate('09/03/2013')
ORDER BY [date], [column2];
person HansUp    schedule 16.10.2013