Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Parámetros opcionales en consulta SQL (https://www.clubdelphi.com/foros/showthread.php?t=86539)

roman 28-08-2014 21:36:21

Parámetros opcionales en consulta SQL
 
Hola,

Si tengo una consulta de este tipo:

Código SQL [-]
SELECT * FROM tabla WHERE campo = :param OR :param IS NULL

con los componentes que uso (MyDac) funciona como se espera, o como espero. Esto es, si no asigno ningún valor al parámetro :param, la consulta devuelve todos los registros, pero si asigno un valor entonces el filtro se hace efectivo y devuelve sólo los registros correspondientes.

Mi duda es si este comportamiento sucede en general en otros componentes tipo Query o es exclusivo de MyDac.

// Saludos

ecfisa 28-08-2014 22:40:51

Hola roman.

Hice unas pruebas y con Firebird/TIBQuery, algunos cambios mediante, finalmente funcionó del modo que comentas.
Código Delphi [-]
  with IBQuery1 do
  begin
    Close;
    SQL.Add('SELECT * FROM USUARIOS');
    SQL.Add('WHERE NAME = CAST(:PARAM AS VARCHAR(30))');
    SQL.Add('OR CAST(:PARAM AS VARCHAR(30)) IS NULL');
    ParamByName('PARAM').Value:= NULL;
    Open;
  end;

Con mdb/TADOQuery me trae todos los campos, aún cuando le especifique uno:
Código Delphi [-]
  with ADOQuery1 do
  begin
    Close;
    SQL.Add('SELECT * FROM COUNTRY');
    SQL.Add('WHERE (NAME = :PARAM) OR (:PARAM IS NULL)');
    Parameters.ParamByName('PARAM').Value:= 'Cuba'; // igual que con NULL
    Open;
  end;

Con BDE y TQuery si la tiene, no le encontré la vuelta (pero estos dos últimos componentes y gestores no son mi fuerte).

Saludos :)

Al González 29-08-2014 06:27:24

Hola Román.

Cita:

Empezado por roman (Mensaje 480481)
Código SQL [-]
SELECT * FROM tabla WHERE campo = :param OR :param IS NULL

Es como dices, creo que así debe trabajar cualquier motor SQL, y no debiera ser relevante el componente Delphi que se use. ^\||/

Aunque yo pondría primero la condición :Param Is Null y luego la condición Campo = :Param. Bajo la lógica de contemplar primero la opción más simple de razonar (¿trae valor?) y luego la más elaborada (¿el valor que trae es el mismo del campo tal?). Desde luego, aplico esta clase de acomodos "mentales" siempre que no repercuta negativamente en el desempeño de procesamiento.

Aprovecho para pedirte que por favor me esperes un par de semanas más para darte una razón de aquello que está pendiente. ;)

Un abrazo.

Al.

cloayza 29-08-2014 16:30:09

Aquí informe...

Componentes: FIBPlus
Evaluado: FIBDataset
Código Delphi [-]
procedure TForm2.BitBtn1Click(Sender: TObject);
begin
     pFIBDataSet1.Close;
     pFIBDataSet1.ParamByName('ID_EMP').Clear; //Null
     pFIBDataSet1.Open;
end;

procedure TForm2.BitBtn2Click(Sender: TObject);
begin
     pFIBDataSet1.Close;
     pFIBDataSet1.ParamByName('ID_EMP').AsInteger:=1;
     pFIBDataSet1.Open;
end;
El resultado es el esperado...
Saludos cordiales

roman 29-08-2014 18:01:49

Muchas gracias por las respuestas. Por lo que veo, no parece ser un estándar aun cuando sería deseable que lo fuese. Claro que, en realidad, el problema se origina en que la VCL no establece un ancestro común para los componentes tipo Query (TDataSet es demasiado genérico) así que, supongo, queda en manos de cada implementador el qué hacer cuando no se asigna valor a un parámetro.

// Saludos


La franja horaria es GMT +2. Ahora son las 18:40:26.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi