Хотя сокращенные доменные функции, такие как DLookup, заманчивы, они имеют свои недостатки. Эквивалент Jet SQL - это что-то вроде
SELECT FIRST(island)
FROM villages
WHERE village = ?;
Если у вас есть более одного подходящего кандидата, он выберет «первый», определение «первый» зависит от реализации (движка SQL) и не определено для движка Jet / ACE IIRC. Вы знаете, какой из них будет первым? Если вы не держитесь подальше от DLookup :)
[Для интереса ответом для Jet / ACE будет либо минимальное значение, основанное на индексе clusterd в момент последнего сжатия файла базы данных, либо первое (допустимое время) вставленное значение, если база данных никогда не была уплотнена. Кластерный индекс, в свою очередь, определяется ключом PRIAMRY, если он присутствует, в противном случае - УНИКАЛЬНОЕ ограничение или индекс, определенный для столбцов NOT NULL, в противном случае - первая (действительное время) вставленная строка. Что если в столбцах NOT NULL определено более одного ограничения или индекса UNIQUE, какое из них будет использоваться для кластеризации? Понятия не имею! Надеюсь, вы поняли, что «первое» определить нелегко, даже если вы знаете, как!]
Я также видел совет от Microsoft, чтобы избежать использования агрегатных функций домена с точки зрения оптимизации:
Информация о производительности запросов в базе данных Access
http://support.microsoft.com/kb/209126
«Избегайте использования агрегатных функций домена, таких как функция DLookup ... ядро базы данных Jet не может оптимизировать запросы, использующие агрегатные функции домена»
Если вы решите переписать с использованием запроса, вы можете воспользоваться синтаксисом PARAMETERS или предпочитаете синтаксис Jet 4.0 / ACE PROCEDURE, например, что-то вроде
CREATE PROCEDURE GetUniqueIslandName
(
:village_name VARCHAR(60)
)
AS
SELECT V1.island_name
FROM Villages AS V1
WHERE V1.village_name = :village_name
AND EXISTS
(
SELECT V2.village_name
FROM Villages AS V2
WHERE V2.village_name = V1.village_name
GROUP
BY V2.village_name
HAVING COUNT(*) = 1
);
Таким образом, вы можете использовать собственную функциональность движка - или, по крайней мере, функции его поставщиков данных - для экранирования всех символов (не просто двойных и одинарных кавычек) по мере необходимости.