Попробуйте изменить LIKE
на ALIKE
, а подстановочные знаки с *
на %
.
Механизм базы данных Access (Jet, ACE и т. д.) имеет два файла Режимы запросов ANSI, каждый из которых использует разные подстановочные знаки для LIKE
:
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