ANSI Sql запрос для принудительного возврата 0 записей - PullRequest
5 голосов
/ 17 декабря 2009

Я ищу метод ANSI-SQL для выполнения запроса Select без возврата какой-либо записи, но для заполнения структуры полей TDataSet.

Метод, который я нашел, заключается в добавлении «где 1 = 0» в любой запрос, например:

Select Id, name, province
from customers
where 1=0

Это довольно тривиальный пример, он становится немного сложнее, когда мне приходится работать с запросами, введенными пользователем, затем анализировать их, удалять предложение where, если оно уже есть, и заменять на «1 = 0». .

Если последнее предложение в запросе, введенном пользователем, является предложением where, тогда нет никаких проблем, но как насчет более сложных запросов, таких как:

select
  c.lastname,
  sum(cs.amount)
from customersales cs
join customers c on c.idcustomer=cs.idcustomer
/* where 1=0 */
group by c.idcustomer, c.lastname

Используя метод "where 1 = 0", единственный способ вставить его в предыдущем примере - использовать довольно мощный анализатор SQL (помните, что пользователь может вводить сложные запросы, включая подзапросы и все такое), кто можно понять, где включить эту строку.

Кто-нибудь знает лучший способ сделать это? Я не могу использовать «предел 1», потому что он должен соответствовать ANSI.

Ответы [ 5 ]

11 голосов
/ 17 декабря 2009

А как насчет добавления вашего собственного SELECT в пользовательский SELECT?

SELECT * FROM (
select
  c.lastname,
  sum(cs.amount)
from customersales cs
join customers c on c.idcustomer=cs.idcustomer
/* where 1=0 */
group by c.idcustomer, c.lastname
) x
WHERE 0=1

РЕДАКТИРОВАТЬ: ORDER BY не будет работать с этим решением, но, поскольку у вас нет строк, вы можете попытаться удалить это из запроса при необходимости.

0 голосов
/ 18 декабря 2009

Или используйте

CustomerSQL='SELECT <Fields> FROM <Table>';
MySQL=Replace(CustomerSQL,'SELECT ','SELECT TOP 0 ');

(возможно, с некоторой проверкой работоспособности, но вы поняли - SELECT TOP 0 вернет только метаданные, содержащие макет записи, но не данные записи).

0 голосов
/ 18 декабря 2009

В Firebird вы можете «подготовить» инструкцию вместо «выполнить» ее. Подготовка просто анализирует инструкцию и возвращает список полей.

0 голосов
/ 18 декабря 2009

если вы используете MSSQL Server, то вы можете обернуть ваш запрос в SET FMTONLY

SET FMTONLY ON SELECT * FROM tablename SET FMTONLY OFF
0 голосов
/ 18 декабря 2009

Для дальнейшего использования в случае, если люди окажутся здесь с другой целью: обратите внимание, что создание противоречия в предложении WHERE может привести к тому, что оптимизатор решит вообще не выполнять подплан. Так что, если вам нужны побочные эффекты запроса (будь то кеш, прогрев кеша, выполнение процедуры, что угодно), имейте в виду. : -)

...