Как я могу сделать параметры запроса MS Access необязательными? - PullRequest
3 голосов
/ 19 сентября 2008

У меня есть запрос, который я хочу фильтровать по-разному в разное время. То, как я сделал это прямо сейчас, поместив параметры в поле критериев соответствующих полей запроса, однако есть много случаев, когда я не хочу фильтровать данное поле, а только другие поля. Есть ли способ, которым какой-то подстановочный знак можно передать параметру критерия, чтобы я мог обойти фильтрацию для этого конкретного вызова запроса?

Ответы [ 6 ]

12 голосов
/ 19 сентября 2008

Если вы строите свой запрос так:

PARAMETERS ParamA Text ( 255 );
SELECT t.id, t.topic_id
FROM SomeTable t
WHERE t.id Like IIf(IsNull([ParamA]),"*",[ParamA])

Все записи будут выбраны, если параметр не заполнен.

3 голосов
/ 29 сентября 2008

Обратите внимание, что подстановочный знак * с ключевым словом LIKE будет иметь желаемый эффект только в режиме запросов ANSI-89.

Многие люди ошибочно полагают, что подстановочный знак в Access / Jet всегда *. Не так. У Jet есть два подстановочных знака:% в режиме запросов ANSI-92 и * в режиме запросов ANSI-89.

ADO всегда ANSI-92, а DAO всегда ANSI-89, но интерфейс доступа может быть любым.

При использовании ключевого слова LIKE в объекте базы данных (то есть что-то, что будет сохранено в файле mdb), вам следует подумать: что произойдет, если кто-то использует эту базу данных, используя режим запросов, отличный от того, который я обычно использую использовать себя? Скажем, вы хотели ограничить текстовое поле только числовыми символами и написали свое Правило валидации следующим образом:

NOT LIKE "*[!0-9]*"

Если кто-то невольно (или иным образом) подключится к вашей .mdb через ADO, то приведенное выше правило проверки позволит ему добавлять данные с нечисловыми символами, и ваша целостность данных будет нарушена. Не хорошо.

Лучше IMO всегда кодировать для обоих режимов запросов ANSI. Возможно, это лучше всего достигается путем явного кодирования для обоих режимов, например

NOT LIKE "*[!0-9]*" AND NOT LIKE "%[!0-9]%"

Но с более сложным Jet SQL DML / DDL, это может быть очень трудно достичь кратко. Вот почему я рекомендую использовать ключевое слово ALIKE, которое использует подстановочный знак ANSI-92 Query Mode независимо от Query Mode, например.

NOT ALIKE "%[!0-9]%"

Заметьте, что ALIKE недокументирован (и я полагаю, именно поэтому мой оригинальный пост был уценен). Я проверил это в Jet 3.51 (Access97), Jet 4.0 (Access2000 до 2003) и ACE (Access2007), и он отлично работает. Ранее я публиковал это в новостных группах и получил одобрение Access MVP. Обычно я бы держался подальше от недокументированных функций, но сделал бы исключение в этом случае, потому что Jet устарел в течение почти десятилетия, и команда Access, которая поддерживает его, не заинтересована в внесении глубоких изменений в движки (или исправлении ошибок! ), что делает реактивный двигатель очень стабильным продуктом.

Подробнее о режимах запросов ANSI Jet см. О режиме запросов SQL ANSI .

1 голос
/ 19 сентября 2008

Вернуться к моему предыдущему экзамену в вашем предыдущем вопросе. Ваш параметризованный запрос представляет собой строку, похожую на эту:

qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = [fid_country]"

в зависимости от характера fid_Country (число, текст, идентификатор, дата и т. Д.), Вам придется заменить его значением джокера и определенными символами-разделителями:

qr = replace(qr,"[fid_country]","""*""")

Чтобы полностью разрешить подстановочные знаки, ваш оригинальный запрос также может быть:

qr = "Select Tbl_Country.* From Tbl_Country _
      WHERE id_Country LIKE [fid_country]"

Затем вы можете получить значения подстановочных знаков для fid_Country, такие как

qr = replace(qr,"[fid_country]","G*")

Как только вы закончите с этим, вы можете использовать строку, чтобы открыть набор записей

set rs = currentDb.openRecordset(qr)
0 голосов
/ 19 сентября 2008

Ну, вы можете вернуть ненулевые значения, передав * в качестве параметра для полей, которые вы не хотите использовать в текущем фильтре. В Access 2003 (и, возможно, более ранних и более поздних версиях), если вы используете like [paramName] в качестве критерия для числового поля, поля «Текст», «Дата» или «Логическое поле», звездочка будет отображать все записи (которые соответствуют другим указанным критериям). Если вы также хотите вернуть нулевые значения, вы можете использовать like [paramName] or Is Null в качестве критерия, чтобы он возвращал все записи. (Это лучше всего работает, если вы строите запрос в коде. Если вы используете существующий запрос и не хотите возвращать нулевые значения, когда у вас есть значение для фильтрации, это не будет работать.)

Если вы фильтруете поле Memo, вам придется попробовать другой подход.

0 голосов
/ 19 сентября 2008

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

Довольно хакерским способом было бы переписать сохраненный запрос на лету и затем получить к нему доступ; однако, если у вас есть несколько человек, использующих одну и ту же БД, вы можете столкнуться с конфликтами, и вы запутаете следующего разработчика.

Вы также можете программно передать значение по умолчанию в запрос (как обсуждалось в предыдущем вопросе)

0 голосов
/ 19 сентября 2008

Не думаю, что ты можешь. Как вы выполняете запрос?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...