Почему запрос LIKE в Access не возвращает никаких записей?

Есть ли причина, по которой

SELECT * FROM MyTable WHERE [_Items] LIKE '*SPI*'

не возвращает никаких записей с OleDbAdapter.Fill(DataSet) или OleDbCommand.ExecuteReader()?

Когда я запускаю тот же SQL напрямую в MS Access, он возвращает ожидаемые записи. Кроме того, в том же коде, если я изменю SQL на

 SELECT * FROM MyTable 

все записи возвращаются.


person Jake    schedule 02.03.2011    source источник
comment
Что именно означает прямой запуск SQL-запроса в MS Access?   -  person StockB    schedule 26.11.2013
comment
В MS Access можно создать запрос в режиме SQL. Это то, что я имел в виду, чтобы ввести запрос напрямую в Access.   -  person Jake    schedule 27.11.2013


Ответы (4)


Измените * на %, так как % — это поиск по шаблону при использовании OLE DB.

SELECT * FROM MyTable WHERE [_Items] LIKE '%SPI%' 
person Neil Knight    schedule 02.03.2011
comment
Этот ответ не сообщает, что * правильно в определенных ситуациях, хотя % правильно в других ситуациях. Моя база данных Access 2010 предпочитает *. Смотрите ответ @onedaywhen ниже. - person CodeMed; 23.07.2015

Попробуйте изменить LIKE на ALIKE, а подстановочные знаки с * на %.

Механизм базы данных Access (Jet, ACE и т. д.) имеет два файла Режимы запросов ANSI, каждый из которых использует разные подстановочные знаки для LIKE:

  • Режим запроса ANSI-89 использует *

  • Режим запроса ANSI-92 использует %

OLE DB всегда использует режим запросов ANSI-92. DAO всегда использует режим запросов ANSI-89. Пользовательский интерфейс Access можно настроить на использование одного или другого.

Однако при использовании ключевого слова ALIKE подстановочный знак всегда будет % независимо от режима запроса ANSI.

Рассмотрим бизнес-правило, которое гласит, что элемент данных должен состоять ровно из восьми числовых символов. Скажем, я реализовал правило следующим образом:

CREATE TABLE MyStuff 
(
 ID CHAR(8) NOT NULL, 
 CHECK (ID NOT LIKE '%[!0-9]%')
);

Использование % в качестве подстановочного знака неизбежно, поскольку тип данных Access CHAR и ограничения CHECK могут быть созданы только в режиме запросов ANSI-92.

Однако кто-то может получить доступ к базе данных с помощью DAO, который всегда использует режим запроса ANS-89, и символ % будет считаться буквальным, а не «специальным» символом, и может быть выполнен следующий код:

INSERT INTO MyStuff (ID) VALUES ('%[!0-9]%');

вставка будет успешной, и целостность моих данных будет нарушена :(

То же самое можно сказать, используя LIKE и * в правиле проверки, созданном в режиме запросов ANSI-89, и кто-то, кто подключается с использованием ADO, который всегда использует режим запросов ANSI-92, и ВСТАВЛЯЕТ символ *, где символ * не должен быть. .

Насколько мне известно, нет способа указать, какой режим запроса ANSI используется для доступа к базе данных Access. Поэтому я думаю, что весь SQL должен быть закодирован так, чтобы вести себя последовательно, независимо от режима запроса ANSI, выбранного пользователем.

Обратите внимание, что не так уж сложно закодировать оба варианта с использованием LIKE в приведенном выше примере, например.

CHECK (
       ID NOT LIKE '%[!0-9]%'
       AND ID NOT LIKE '*[!0-9]*'
      )

... или действительно полностью избегайте подстановочных знаков, например.

CHECK (ID LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')

Однако использование ALIKE приведет к менее подробному коду, т. е. более легкому для чтения человеком и, следовательно, более простому в обслуживании.

Кроме того, когда приходит время портировать продукт SQL, совместимый со стандартами SQL, ALIKE тоже хорошо портирует, т. е. все, что требуется, — преобразовать ключевое слово ALIKE в LIKE. При синтаксическом анализе заданного предиката SQL гораздо проще найти одно ключевое слово LIKE, чем найти все многочисленные экземпляры символа * в текстовых литералах. Помните, что «переносимость» не означает, что «код будет работать как есть»; скорее, это мера того, насколько легко перемещать код между платформами (и имейте в виду, что перемещение между версиями одного и того же продукта — это перенос, например, Jet 4.0 на ACE — это перенос, поскольку безопасность на уровне пользователя больше не работает, DECIMAL значения сортировать по-разному и т. д.).

person onedaywhen    schedule 02.03.2011
comment
Я предполагаю, что ALIKE — это сокращение от ANSI LIKE. Я не вижу в этом никакой пользы, кроме как для людей, которые являются иностранцами для доступа. Это означает, что вы в конечном итоге пишете непереносимый SQL, но на самом деле важен ваш метод интерфейса данных. Если вы являетесь беженцем из-за пределов Access, и коленный рефлекс должен использовать % в качестве подстановочного знака, то все, что вам нужно сделать, это убедиться, что вы всегда используете методы доступа к данным, которые будут использовать режим ANSI 92. Это приведет к переносимому SQL и без проприетарных хламов вроде ALIKE. На самом деле, если вы собираетесь использовать ALIKE, вы можете просто использовать * - оба не переносимы. - person David-W-Fenton; 06.03.2011
comment
@David-W-Fenton: все, что вам нужно сделать, это убедиться, что вы всегда используете методы доступа к данным, которые будут использовать режим ANSI 92 - скорее, нужно убедиться, что все пользователи используют только ANSI- 92 Режим запроса, но как это сделать? Насколько я знаю, это невозможно. Поэтому вам необходимо обрабатывать оба режима запросов ANSI или подвергать своих клиентов проблемам с целостностью данных. Кроме того, ALIKE очень переносим, ​​гораздо более переносим, ​​чем использование LIKE + *. Я обновил свой ответ соответственно. - person onedaywhen; 07.03.2011
comment
ALIKE поддерживается другими СУБД? Я этого не знал — я думал, что это специфично для Jet/ACE. Просто погуглив в течение минуты, я не нашел доказательств того, что ALIKE поддерживается каким-либо другим механизмом базы данных. - person David-W-Fenton; 07.03.2011
comment
@onedaywhen: я не понимаю вашего мнения о том, чтобы все пользователи использовали только режим запросов ANSI-92. Если вы создаете приложение, у вас есть полный контроль над этим. Если у вас есть серверная часть Jet/ACE, которую вы хотите ограничить этим режимом, вы устанавливаете это свойство для этой базы данных. Теперь это никак не повлияет на доступ к этой базе данных из DAO, но это будет означать, что если кто-то откроет ее в Access, он будет использовать режим SQL 92. Я не знаю, поддерживает ли ODBC это при любом сценарии, но могу ошибаться. Итак, я не понимаю вашу точку зрения. - person David-W-Fenton; 07.03.2011
comment
@David-W-Fenton: Если вы создаете приложение, у вас есть полный контроль над ним... Теперь это никак не повлияет на доступ к этой базе данных из DAO... Я не знайте, что ODBC его поддерживает... -- вы как бы подчеркнули для меня мысль: у вас нет никакого контроля над режимом запросов ANSI, в котором будет выполняться ваш код SQL! Если вы так думаете, то вы обманываете себя :) - person onedaywhen; 08.03.2011
comment
@David-W-Fenton: я не нахожу доказательств того, что ALIKE поддерживается каким-либо другим механизмом базы данных. См. Мое обновление: помните, что портативность не означает, что код будет работать «как есть»; скорее, это мера того, насколько легко перемещать код между платформами... Преобразование ALIKE в LIKE — один из самых простых портов, на которые вы можете надеяться :) - person onedaywhen; 08.03.2011
comment
Вы имеете в виду, что это намного проще, чем преобразовать SQL с * в качестве подстановочного знака в использование % в качестве подстановочного знака? Для меня это выглядит как простой поиск и замена в обоих случаях, поэтому я не понимаю, почему кто-то предпочитает один другому. - person David-W-Fenton; 10.03.2011
comment
@David-W-Fenton: Нет, я имею в виду, что гораздо проще преобразовать ALIKE в LIKE, чем преобразовать * в % - учтите, что вы можете анализировать составную строку, обрабатывать *, CHR(42) и CHR$(42), и что * символ или код 42 ascii можно хранить в таблице! Но это незначительная проблема по сравнению с нейтральностью ANSI Query Mode. - person onedaywhen; 10.03.2011

Попробуйте преобразовать подстановочные знаки (*) в %

Это должно решить проблему.

person Pooli    schedule 02.03.2011

Боже, это работает! Большое спасибо.

Мне просто нужно было заменить not like criteria на not alike criteria.

Я делюсь своей «историей», чтобы помочь другим легче найти этот пост и избавить их от двухчасового поиска.

Хотя я связал xls-файлы Excel 95-97 с базой данных Access 2010 и выполнил запросы create table и insert into для импорта всех данных в базу данных, по какой-то странной причине запрос выбора не смог найти строки, которые я набрал. .

Пробовал not like "something" и not like "%something%" безуспешно - просто не работало.

L

person Levi    schedule 10.12.2013