Я ищу метод ANSI SQL, чтобы сделать Запрос Select, не возвращая записи, но заполнить Полевую структуру TDataSet.
Метод, который я нашел, путем добавления "где 1=0" в любом запросе, например:
Select Id, name, province
from customers
where 1=0
Это - довольно тривиальный пример, это становится немного более сложным, когда я должен работать с запросами, вводимыми пользователем, затем проанализировать их, удалить, где пункт, если это уже имеет один, и замена "1=0".
Если последний пункт во вводимом пользователями запросе где пункт, то нет никакой проблемы вообще, но что относительно более сложных запросов как это:
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
При помощи, "где 1=0" метод, единственный способ вставить его в предыдущий пример при наличии довольно мощного синтаксического анализатора SQL (помнят, пользователь может ввести сложные запросы, включая Подзапросы и все это), кто может понять, где включать эту строку.
Кто-либо знает лучший способ сделать это? Я не могу использовать "предел 1", потому что это должен быть в ANSI путь.
А как насчет добавления собственного 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
EDIT: ORDER BY
не будет работать с этим решением, но поскольку вы не получаете строк, вы могли бы при необходимости попробуйте удалить это из запроса.
В Firebird вы можете «подготовить» оператор вместо «выполнить» его. Подготовка просто анализирует инструкцию и возвращает список полей.
Или используйте
CustomerSQL='SELECT <Fields> FROM <Table>';
MySQL=Replace(CustomerSQL,'SELECT ','SELECT TOP 0 ');
(возможно, с некоторой проверкой работоспособности, но вы поняли идею - SELECT TOP 0 вернет только метаданные, содержащие макет записи, но не данные записи).
Для справки в будущем на случай, если люди остановятся здесь с другой целью: Обратите внимание, что создание противоречия в предложении WHERE может привести к тому, что оптимизатор решит вообще не выполнять подплан. Поэтому, если вам нужны побочные эффекты запроса (будь то прогрев кеша, выполнение процедуры, что угодно), имейте в виду. : -)
если вы используете сервер MSSQL, тогда вы можете обернуть свой запрос вокруг SET FMTONLY
SET FMTONLY ON SELECT * FROM tablename SET FMTONLY OFF