2009-12-17 13 views
5

Estoy buscando un método ANSI-SQL para hacer una consulta Seleccionar sin devolver ningún registro, pero completar una estructura de Campos de TDataSet.ANSI consulta Sql para forzar el retorno 0 registros

El método que he encontrado es mediante la adición de un "donde 1 = 0" en cualquier consulta, por ejemplo:

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

Este es un ejemplo bastante trivial, resulta un poco más complicado cuando tengo que trabajar con consultas ingresadas por el usuario, luego analizarlas, eliminar la cláusula where si ya tiene una, y reemplazar por "1 = 0".

Si la última cláusula de la consulta introducida por el usuario es la cláusula where, entonces no hay problema en absoluto, pero ¿qué pasa con las preguntas más complicadas como esta:

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 

Al utilizar el "donde 1 = 0 "método, la única forma de insertarlo en el ejemplo anterior es tener un analizador SQL bastante poderoso (recuerde que el usuario puede ingresar consultas complejas, incluidas las subconsultas y todo eso), que pueden entender dónde incluir esta cadena.

¿Alguien sabe una mejor manera de hacer esto? No puedo usar el "límite 1" porque debe estar en una forma ANSI.

+0

¿Para qué necesita esto? –

+0

Lo necesito porque estoy agregando una función a un software, que permite al usuario crear consultas personalizadas, luego uso las consultas para mostrar Gráficos, Tablas y para crear Informes usándolos. Necesito esto para diseñar los Informes. Para mostrar el Diseñador de informes con los conjuntos de datos disponibles (extraídos de las consultas hechas por el usuario) Necesito esta característica. Los "conjuntos de datos" son simples listas de campos extraídos después de realizar las consultas. BTW, estoy usando FastReport 4. –

+0

para crear una consulta hecha por el cliente: ¿por qué no utiliza el generador de consultas rápido incluido con el informe rápido? ¿Y por qué no el cubo rápido? –

Respuesta

11

¿Qué hay de agregar su propio SELECT en SELECT del usuario?

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 no quiere trabajar con esa solución, pero ya no se obtienen las filas, se podría tratar de eliminar que a partir de la consulta cuando sea necesario.

+1

Gracias Peter, probado en PostgreSql y Firebird y funciona !. Lo único que tuve que agregar fue un alias para la consulta interna. seleccionar * de (consulta interna) AS FOO donde 1 = 0. Gracias de nuevo. –

0

Para referencia futura en caso de que las personas terminen aquí con un objetivo diferente: Tenga en cuenta que hacer que la cláusula WHERE sea una contradicción puede hacer que el optimizador decida no ejecutar el subplano en absoluto. Por lo tanto, si necesita algunos efectos secundarios de la consulta (ya sea una memoria caché, ejecutar un procedimiento, lo que sea), tenga en cuenta. :-)

0

si el uso de MSSQL Server, a continuación, se puede envolver alrededor de su consulta SET FMTONLY

SET FMTONLY ON SELECT * FROM tablename SET FMTONLY OFF 
0

En Firebird puede 'preparar' la declaración en lugar de 'ejecutar' la misma. Preparing simplemente analiza la declaración y devuelve la lista de campos.

0

O utilice

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

(tal vez con un poco de cordura comprobar, pero se entiende la idea - un TOP SELECT 0 devolverá sólo los metadatos que contienen el diseño de registro y no hay datos de registro).

Cuestiones relacionadas