Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 27-09-2015
Kenobi Kenobi is offline
Miembro
 
Registrado: mar 2007
Posts: 191
Poder: 18
Kenobi Va por buen camino
Desactivar parametro en query

Hola amigos, el problema que me ocupa es el siguiente, muchas veces creamos datamodulos y lo vamos llenando de componentes query para esto para aquellos etc. por ejemplo un query con todos los campos de la tabla, otro con la cuenta de todos a modo de resumen. bien en ese orden de ideas y pensando en que es bueno crear componentes reutilizables les expongo lo siguiente .....

supongamos que tengo una tabla proyectos que tiene los proyectos con sus categorias, luego para saber cuantos proyectos por categoria hay pues en un query :
Código Delphi [-]
select proyectos,categorias,count(categorias)
from proyectos
group by categorias

ahora bien suponiendo que quiero saber cuantas categorias tiene un proyecto en particular pues:
Código Delphi [-]
select proyectos,categorias,count(categorias)
from proyectos
where proyecto=:miParametro
group by categorias

bien hasta ahora son dos componentes query que hacen lo mismo pero uno con parametros y el otro no pues lo que quisiera hacer es uno solo que segun si le paso parametro o no me mande los resultados, ejemplo:

Código Delphi [-]

if length(miParametro)>1 then query.params.paramvalues['miParametro']:=miParametro
else 'ACA QUE NO TOME EN CUENTA EL PARAMETRO O UTILIZE UN COMODIN'  // miParametro:='%' o '*' "ninguno funciona"

en todo caso se que construyendo la consulta en tiempo de ejecucion:
Código Delphi [-]
query.slq.add('select * from tabla blabablabla....')
se podria pero me gustaria hacerlo en tiempo de diseño, o tambien quitando el paramentro del query a aplicandolo como filtro, pero esta opción (que ya la aplique) es mas lenta porque se trae todos los proyectos para luego filtrar y por otro lado si luego olvidas que la data esta filtrada y haces un insert puedes duplicar registros(pero esto es harina de otro costal)

ojala haya logrado explicarme y sean tan amables de orientarme en esto ....

Gracias
Responder Con Cita
  #2  
Antiguo 27-09-2015
Kenobi Kenobi is offline
Miembro
 
Registrado: mar 2007
Posts: 191
Poder: 18
Kenobi Va por buen camino
otra alternativa es ...

esta es mas loca aun porque depende de al posición del texto en particular dentro del sql del query :

Código Delphi [-]
  if miParametro = '' then query.SQL.Strings[linea_donde_esta_el_where]:=''
                 else query.Params.ParamValues['miParametro']:=miParametro;

funciona, pero es peor el remedio que la enfermedad ....
Responder Con Cita
  #3  
Antiguo 27-09-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
No lo probe nunca pero creo que se podria hacer algo como

Código SQL [-]
SELECT * FROM Table
WHERE Campo = :Param AND Campo <> NULL

Código Delphi [-]
  qry.ParamByName('Param').Clear;
  qry.ParamByName('Param').Value := NULL; // uses Variants
  qry.ParamByName('Param').SetNull;

No estoy seguro cual de las 3 alternativas de arriba es valida, creo que dependen de los componentes/motor bd.

PD: El metodo SetNull no estoy seguro si existe o me lo saque de la chistera
Responder Con Cita
  #4  
Antiguo 27-09-2015
Kenobi Kenobi is offline
Miembro
 
Registrado: mar 2007
Posts: 191
Poder: 18
Kenobi Va por buen camino
No funciona

Hola gracias por tu respuesta, pero no funciona ninguna de las opciones, tanto clear como value:=null devuelven el query vacio quiere decir que no lo usa como comodin de ALL(% , *)

gracias y setNUll en efecto no existe JEJEJEJE
Responder Con Cita
  #5  
Antiguo 27-09-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Bueno, admito que me equivoque eso pasa por hacerlo de memoria y no probarlo jaja

Edito:

Me retracto nuevamente lo que postie no sirve

Última edición por AgustinOrtu fecha: 27-09-2015 a las 06:06:27.
Responder Con Cita
  #6  
Antiguo 27-09-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Kenobi.
Cita:
Empezado por Kenobi Ver Mensaje
...
Código SQL [-]
select proyectos,categorias,count(categorias)
from proyectos
where proyecto=:miParametro
group by categorias
Lo primero que me llama la atención es que la consulta anterior funcione sin haber incluído la columna "proyectos" en la declaración GROUP BY ...

Para reutilizar el mismo query, se me ocurre que podrías hacer algo similar a este ejemplo:
Código Delphi [-]
procedure UnDataModule.CountCategories(const Categoria: string); 
begin
  qyCat.Close;

  qyCat.SQL.Clear;
  qyCat.SQL.Add('SELECT PROYECTO, COUNT(CATEGORIAS)');
  qyCat.SQL.Add('FROM PROYECTOS');
  qyCat.SQL.Add('WHERE PROYECTO = :PARAM');
  qyCat.SQL.Add('GROUP BY PROYECTO');

  if Categoria = EmptyStr then
    qyCat.SQL.Delete(2)
  else
    qyCat.parameters.ParamByName('PARAM').Value := Categoria;

  qyCat.Open;
end;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #7  
Antiguo 27-09-2015
Kenobi Kenobi is offline
Miembro
 
Registrado: mar 2007
Posts: 191
Poder: 18
Kenobi Va por buen camino
Estoy en busca de una opcion mejor, si es que existe

Cita:
Empezado por ecfisa Ver Mensaje
Hola Kenobi.

Lo primero que me llama la atención es que la consulta anterior funcione sin haber incluído la columna "proyectos" en la declaración GROUP BY ...
tienes razon, ese query no funciona ya que lo invente en el momento para no mostrar el codigo del query real, por aquello de proteger el codigo en producción, pero es muy similar.

Cita:
Empezado por ecfisa Ver Mensaje
Para reutilizar el mismo query, se me ocurre que podrías hacer algo similar a este ejemplo:
Código Delphi [-]
procedure UnDataModule.CountCategories(const Categoria: string); 
begin
  qyCat.Close;

  qyCat.SQL.Clear;
  qyCat.SQL.Add('SELECT PROYECTO, COUNT(CATEGORIAS)');
  qyCat.SQL.Add('FROM PROYECTOS');
  qyCat.SQL.Add('WHERE PROYECTO = :PARAM');
  qyCat.SQL.Add('GROUP BY PROYECTO');

  if Categoria = EmptyStr then
    qyCat.SQL.Delete(2)
  else
    qyCat.parameters.ParamByName('PARAM').Value := Categoria;

  qyCat.Open;
end;
así lo tengo hecho pero como mencione estoy buscando una alternativa para no crear el codigo del query( query.sql.add(codigo sql)) en tiempo de ejecución, me apete algo como :
Código Delphi [-]
if length(param) > 1 then qyCat.parameters.ParamByName('PARAM').Value := Param
                           else 'DESACTIVO EL PARAMETRO SIN DESTRUIRLO, BORRARLO PARA QUE LA SENTENCIA SIGA IGUAL A LA CREADA EN DISEÑO, PERO
                                SE EJECUTE SIN EL PARAMETRO, AL MENOS EN ESTA LLAMADA'


Gracias por sus respuestas ....

P.D AgustinOrtu, así sea de memoria y no haya funcionado, en verdad agradezco tu intención y tu tiempo para responder, saludos
Responder Con Cita
  #8  
Antiguo 27-09-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Lightbulb

Estaba convencido de que se podia

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  ADOQuery1.Close;
  if Edit1.Text <> '' then
    ADOQuery1.Parameters.ParamByName('ParamId').Value := Edit1.Text
  else
    ADOQuery1.Parameters.ParamByName('ParamId').Value := NULL;
  ADOQuery1.Open;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ADOQuery1.SQL.Text := ' SELECT * FROM Productos WHERE Id = IsNull(:ParamId, Id) ';
  ADOQuery1.Prepared := True;
end;



Saludos
Responder Con Cita
  #9  
Antiguo 27-09-2015
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por Kenobi Ver Mensaje
tienes razon, ese query no funciona ya que lo invente en el momento para no mostrar el codigo del query real, por aquello de proteger el codigo en producción, pero es muy similar.
-Señor policía, ¿puede ayudarme?
+Sí, dígame lo que le ocurre.
-No puedo, es secreto.

Responder Con Cita
  #10  
Antiguo 27-09-2015
Kenobi Kenobi is offline
Miembro
 
Registrado: mar 2007
Posts: 191
Poder: 18
Kenobi Va por buen camino
En efecto funciona

Barbaro ....
solo 2 cosas, para mySql es IfNull() lo cual es un pequeño problema porque la idea es mantener el codigo mas independiente del manejador, por otro lado me imagino que sera propio del uso de la funcion se afecta el rendimiento notablemente, eso si que es un problema para mi porque seria muchas consultas a las que le aplicaria la solución, gracias mil...

seguire buscando otra alternativa ...
Responder Con Cita
  #11  
Antiguo 27-09-2015
Kenobi Kenobi is offline
Miembro
 
Registrado: mar 2007
Posts: 191
Poder: 18
Kenobi Va por buen camino
buena esa

Cita:
Empezado por Casimiro Notevi Ver Mensaje
-Señor policía, ¿puede ayudarme?
+Sí, dígame lo que le ocurre.
-No puedo, es secreto.

, ojo no es por mezquinar el codigo es simplemente respetar la confidencialidad de la organización ya que mis tablas tienen nombres muy elocuentes....

me disculpo por eso.
Responder Con Cita
  #12  
Antiguo 27-09-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Creo que la mejor forma de independizar del motor es usando interfaces:

Código Delphi [-]
unit SQLFunctions;

interface

uses
  Data.DB;

type
  ISQLFunctions = interface
    ['{CD84579F-2EE3-4842-BCF3-F8B5A2B7C50B}']
    function NullFx(const ParamName, FieldName: string): string;
  end;

  TExtendedSQLConnection = class abstract(TInterfacedObject, ISQLFunctions)
  protected
    FConnection: TCustomConnection;
    function NullFx(const ParamName, FieldName: string): string; virtual; abstract;
  public
    constructor Create(const AConnection: TCustomConnection); virtual;
  end;

implementation

uses
  System.SysUtils;

{ TExtendedSQLConnection }

constructor TExtendedSQLConnection.Create(const AConnection: TCustomConnection);
begin
  if not Assigned(AConnection) then
    raise Exception.Create('TExtendedSQLConnection.Create :: AConnection is not Assigned');

  inherited Create;
  FConnection := AConnection;
end;

end.

Código Delphi [-]
unit MySQLFunctions;

interface

uses
  SQLFunctions;

type
   TMySQLExtendedConnection = class(TExtendedSQLConnection)
   protected
    function NullFx(const ParamName, FieldName: string): string; override;
   end;

implementation

uses
  System.SysUtils;

{ TMySQLExtendedConnection }

function TMySQLExtendedConnection.NullFx(const ParamName, FieldName: string): string;
begin
  Result := Format('IfNull(:%s, %s)', [ParamName, FieldName]);
end;

end.

Código Delphi [-]
unit MSSQLFunctions;

interface

uses
  SQLFunctions;

type
   TMSSQLExtendedConnection = class(TExtendedSQLConnection)
   protected
    function NullFx(const ParamName, FieldName: string): string; override;
   end;

implementation

uses
  System.SysUtils;

{ TMSSQLExtendedConnection }

function TMSSQLExtendedConnection.NullFx(const ParamName, FieldName: string): string;
begin
  Result := Format('IsNull(:%s, %s)', [ParamName, FieldName]);
end;

end.

Última edición por AgustinOrtu fecha: 27-09-2015 a las 22:57:18.
Responder Con Cita
  #13  
Antiguo 27-09-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Ejemplo de uso:

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  ADOQuery1.Close;
  if Edit1.Text = EmptyStr then
    ADOQuery1.Parameters.ParamByName('Param').Value := NULL
  else
    ADOQuery1.Parameters.ParamByName('Param').Value := Edit1.Text;
  ADOQuery1.Open;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FSQLFunctions := TMSSQLExtendedConnection.Create(ADOConnection1);
  ADOQuery1.SQL.Text := 'SELECT * FROM Productos WHERE Id = ' + FSQLFunctions.NullFx('Param', 'Id');
  ADOQuery1.Prepared := True;
end;

Edito:

Si las funciones para comprobar si es Null o no comprometen la eficiencia, la unica manera es usando dos componentes Query.

Última edición por AgustinOrtu fecha: 27-09-2015 a las 23:01:13.
Responder Con Cita
  #14  
Antiguo 28-09-2015
bucanero bucanero is offline
Miembro
 
Registrado: nov 2013
Ubicación: Almería, España
Posts: 208
Poder: 11
bucanero Va camino a la fama
Una alternativa usando solamente parámetros es utilizar dos parámetros, uno que indica que muestre todos y otro para filtrar directamente los datos que queremos

Código SQL [-]
select proyectos, categorias, count(categorias)
from proyectos
where :todos or proyectos=:miParametro
group by proyectos, categorias

y en el codigo de busqueda:

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  ADOQuery1.Close;
  if Edit1.Text = EmptyStr then
    //se le indica que muestre todos
    ADOQuery1.Parameters.ParamByName('todos').Value := 1
  else begin
    //se obliga a filtra por el dato necesario
    ADOQuery1.Parameters.ParamByName('todos').Value := 0
    ADOQuery1.Parameters.ParamByName('miParametro').Value := Edit1.Text;
  end;
  ADOQuery1.Open;
end;
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Realizar un Update en delphi con un query concondicion desde otro query!!! rotsen26 SQL 9 09-03-2013 23:17:47
Pasar un array como parámetro a una Query pape19 Varios 7 10-10-2011 23:53:40
Saber si un parametro de un Query ha sido asignado sinalocarlos Varios 1 26-03-2008 03:44:38
Desactivar Evento en un Query MaMu Conexión con bases de datos 4 27-06-2007 01:46:01
Como hacer referencia a un query dentro de otro query? JuanBCT SQL 2 05-09-2006 19:35:25


La franja horaria es GMT +2. Ahora son las 00:50:37.


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
Copyright 1996-2007 Club Delphi