Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MySQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=21)
-   -   Mensaje Conflicto entre tablas, Migración Query a ADOQuery (https://www.clubdelphi.com/foros/showthread.php?t=91413)

koalasoft 31-01-2017 16:40:09

Mensaje Conflicto entre tablas, Migración Query a ADOQuery
 
Buen dia .. tengo un detalle .... anterior mente usaba el siguiente código con el componente Query y me funcionaba muy bien sin problemas, usando en aquel entonces tablas paradox..

Código PHP:

with QueryRegONT do          // Busqueda por Modelo y Tipo
 
begin
   Close
;
   
SQL.Clear;
   
// ------------------------------------------------------------
   // Se ultilizó el PArametro JOIN para unir las otras Tablas
   // relacionando el Campo FOLIO en todas ellas siempre y cuando
   // Se cumpliera la condicion de busqueda del ONT ya registrado.
   // ------------------------------------------------------------
   
SQL.Add('SELECT * FROM CTRLONT.db CTRL ');
   
SQL.Add('join CLIENTES.db CL on CTRL.FOLIO = CL.FOLIO ');
   
SQL.Add('join ONT.db ONT on CTRL.FOLIO = ONT.Folio ');
   
SQL.Add('WHERE BOARD_ONT=:BOARD_ONT');
   
SQL.Add(' AND FRAME_ID=:FRAME_ID');
   
SQL.Add(' AND SLOT_ID=:SLOT_ID');
   
SQL.Add(' AND PORT_ID=:PORT_ID');
   
SQL.Add(' AND ONT_ID=:ONT_ID');

   
// --------------------------------------------------------
   //  Valores de búsqueda para el registro de Cliente.
   // --------------------------------------------------------
   
ParamByName('BOARD_ONT').AsInteger := StrToInt(Edit1.Text);
   
ParamByName('FRAME_ID').AsInteger := StrToInt(Edit2.Text);
   
ParamByName('SLOT_ID').AsInteger := StrToInt(Edit3.Text);
   
ParamByName('PORT_ID').AsInteger := StrToInt(Edit4.Text);
   
ParamByName('ONT_ID').AsInteger := StrToInt(Edit5.Text);
   
Open;
   if 
QueryRegONT.IsEmpty then
    Begin
    msError
('El ONT no se encuentra registrado, porfavor verifica los datos.','No existe Datos..');
    exit;
    
End
     
Else
      
Begin
      F
:= QueryRegONT.FieldByName('FOLIO').AsInteger;
      
// -------------------
      
with QueryCL do          // Busqueda por Modelo y Tipo
        
begin
          Close
;
          
SQL.Clear;
          
SQL.Add('SELECT * FROM CLIENTES.db ');
          
SQL.Add('WHERE FOLIO=:FOLIO');
          
ParamByName('FOLIO').AsInteger :=F;
          
Open;
        
end;
      
with QueryONT do          // Busqueda por Modelo y Tipo
        
begin
          Close
;
          
SQL.Clear;
          
SQL.Add('SELECT * FROM ONT.db ');
          
SQL.Add('WHERE FOLIO=:FOLIO');
          
ParamByName('FOLIO').AsInteger :=F;
          
Open;
        
end;
      
// -------------------
      
Bok.Enabled := True;
      
BBuscar.Enabled := False;
      
DesactivarCampos([Edit1,Edit2,Edit3,Edit4,Edit5]);
      
End;
 
end


Ahora el mismo código lo intenté migrar al componente ADOQuery ya que ahora estoy trabajando con tablas Mysql y lo tengo de esta forma:

Código PHP:

with ADOQueryCtrlONT do          // Busqueda por Modelo y Tipo
 
begin
   Close
;
   
SQL.Clear;
   
// ------------------------------------------------------------
   // Se ultilizó el PArametro JOIN para unir las otras Tablas
   // relacionando el Campo FOLIO en todas ellas siempre y cuando
   // Se cumpliera la condicion de busqueda del ONT ya registrado.
   // ------------------------------------------------------------
   
SQL.Add('SELECT * FROM CTRLONT CTRL ');
   
SQL.Add('join CLIENTES CL on CTRL.FOLIO = CL.FOLIO ');
   
SQL.Add('join ONTs ONT on CTRL.FOLIO = ONT.Folio ');
   
SQL.Add('WHERE BOARD_ONT= :BOARD_ONT');
   
SQL.Add(' AND FRAME_ID= :FRAME_ID');
   
SQL.Add(' AND SLOT_ID= :SLOT_ID');
   
SQL.Add(' AND PORT_ID= :PORT_ID');
   
SQL.Add(' AND ONT_ID= :ONT_ID');

   
// --------------------------------------------------------
   //  Valores de búsqueda para el registro de Cliente.
   // --------------------------------------------------------
   
Parameters.ParamByName('BOARD_ONT').Value  := Edit1.Text;
   
Parameters.ParamByName('FRAME_ID').Value := Edit2.Text;
   
Parameters.ParamByName('SLOT_ID').Value := Edit3.Text;
   
Parameters.ParamByName('PORT_ID').Value := Edit4.Text;
   
Parameters.ParamByName('ONT_ID').Value := StrToInt(Edit5.Text);
   
Open;
   if 
ADOQueryCtrlONT.IsEmpty then
    Begin
    msError
('El ONT no se encuentra registrado, por favor verifica los datos.','No existe Datos..');
    exit;
    
End
     
Else
      
Begin
      F
:= ADOQueryCtrlONT.FieldByName('FOLIO').Value;
      
// -------------------
      
with ADOQueryCL do          // Busqueda por Modelo y Tipo
        
begin
          Close
;
          
SQL.Clear;
          
SQL.Add('SELECT * FROM CLIENTES ');
          
SQL.Add('WHERE FOLIO= :FOLIO');
          
Parameters.ParamByName('FOLIO').Value :=F;
          
Open;
        
end;
      
with ADOQueryONT do          // Busqueda por Modelo y Tipo
        
begin
          Close
;
          
SQL.Clear;
          
SQL.Add('SELECT * FROM ONTs ');
          
SQL.Add('WHERE FOLIO= :FOLIO');
          
Parameters.ParamByName('FOLIO').Value :=F;
          
Open;
        
end;
      
// -------------------
      
Bok.Enabled := True;
      
BBuscar.Enabled := False;
      
DesactivarCampos([Edit1,Edit2,Edit3,Edit4,Edit5]);
      
End;
 
end

Al ejecutarlo me marca un mensaje de error que dices asi:

"Argumentos incorrectos, fuera del intervalo permitido o en conflicto con otro"

El compilador no marca error y prácticamente estoy usando el mismo código con el que si me funcionaba, saben cual podría ser el error?

EL error del mensaje lo genera en esta línea:

Código PHP:

SQL.Add('WHERE BOARD_ONT=:BOARD_ONT'); 


aposi 31-01-2017 17:14:26

Hola,
En el Where indica a que tabla se refiere el campo
CL si es la tabla cliente, CTRL si esta en CTRLON o ONT si esta en ONTs

koalasoft 31-01-2017 17:31:20

Gracias por responder ..

Hice lo que mencionas, lo cambié por esto...

Código PHP:

   SQL.Add('SELECT * FROM CTRLONT CTRL ');
   
SQL.Add('join CLIENTES CL on CTRL.FOLIO = CL.FOLIO ');
   
SQL.Add('join ONTs ONT on CTRL.FOLIO = ONT.Folio ');
   
SQL.Add('WHERE CTRL.BOARD_ONT= :BOARD_ONT');        // Aquí marca el error
   
SQL.Add(' AND CTRL.FRAME_ID= :FRAME_ID');
   
SQL.Add(' AND CTRL.SLOT_ID= :SLOT_ID');
   
SQL.Add(' AND CTRL.PORT_ID= :PORT_ID');
   
SQL.Add(' AND CTRL.ONT_ID= :ONT_ID'); 

Ya que la búsqueda correponde a la tabla CTRLONT, pero en la misma línea WHERE me sigue marcando el mismo error.

aposi 31-01-2017 17:43:18

la tabla ONT se llama ONT o ONTs?

En el Query que funcionava se llama ONT
Código Delphi [-]
SQL.Add('join ONT.db ONT on CTRL.FOLIO = ONT.Folio ');
Y en el nuevo ONTs
Código Delphi [-]
SQL.Add('join ONTs ONT on CTRL.FOLIO = ONT.Folio ');

koalasoft 31-01-2017 17:57:19

Cita:

Empezado por aposi (Mensaje 512831)
la tabla ONT se llama ONT o ONTs?

En el Query que funcionava se llama ONT
Código Delphi [-]
SQL.Add('join ONT.db ONT on CTRL.FOLIO = ONT.Folio ');
Y en el nuevo ONTs
Código Delphi [-]
SQL.Add('join ONTs ONT on CTRL.FOLIO = ONT.Folio ');

Ahora se llama ONTs la tabla, pero pasa algo curioso, quite estas líneas:

Código PHP:

SQL.Add(' AND CTRL.FRAME_ID= :FRAME_ID'); 
   
SQL.Add(' AND CTRL.SLOT_ID= :SLOT_ID'); 
   
SQL.Add(' AND CTRL.PORT_ID= :PORT_ID'); 
   
SQL.Add(' AND CTRL.ONT_ID= :ONT_ID'); 

Dejando la consulta de esta forma:

Código PHP:

SQL.Add('SELECT * FROM CTRLONT ');  
SQL.Add('WHERE BOARD_ONT= :BOARD_ONT'); 

Y de nuevo en la segunda línea donde esta el WHERE me marca el mismo error.

TOPX 31-01-2017 18:25:41

Buen día.

... información de interés ~ Using parameters with ADO Query (mysql/MyConnector) - StackOverflow
-

fjcg02 31-01-2017 18:51:20

Una pregunta...

el campo BOARD_ONT es de la tabla CTRLONT ?

Saludos

koalasoft 31-01-2017 19:01:59

Gracias por el dato .. intenté con esto ...

Código PHP:

with ADOQueryCtrlONT.Parameters.AddParameter do
    
begin
      Name 
:= 'BOARD';
      
DataType := ftInteger;
    
end;

with ADOQueryCtrlONT do          // Busqueda por Modelo y Tipo
 
begin
   Close
;
   
SQL.Clear;
   
SQL.BeginUpdate;
   
SQL.Add('SELECT * FROM CTRLONT ');
   
SQL.Add('WHERE BOARD_ONT = :BOARD');
   
Open;
...
.. 

Pero me sigue mandando el mismo mensaje en la línea donde tiene el WHERE ..

Una pregunta tendrá algo que ver el tipo de datos que tenga definida en la BD, ya que el campo BOARD_ONT es de tipo Int(11) en la BD Mysql.

koalasoft 31-01-2017 19:03:13

Cita:

Empezado por fjcg02 (Mensaje 512836)
Una pregunta...

el campo BOARD_ONT es de la tabla CTRLONT ?

Saludos

Asi es estimado !! es un campo de la Tabla CTRLONT de tipo INT [int(11)] de la BD Mysql.

fjcg02 31-01-2017 21:33:26

Hola, lo normal es asignar la sql y luego dar valor a los parámetros, es decir, después de hacer query.Sql.Add(), defines el valor del parámetro. Yo creo que no hace falta declararlo, solamente asignarle el valor.

Saludos

bitbow 31-01-2017 21:47:50

Revisa si tienes los parametros creados puesto que estas asignando el Query en runtime deberias de crear los parametros ya que no existen aun.

En las propiedades del TQuery te das cuenta en Parameters si tienes dados de alta alguno.

Saludos.

AgustinOrtu 31-01-2017 21:59:17

Tal y como respondi en DelphiAccess:

El componente internamente interpreta la sentencia SQL y crea automaticamente los parametros; no hace falta que invoques para nada al metodo Parameters.AddParameter

Osea por ejemplo, con un SQL asi:

Código Delphi [-]
  ADOQuery.SQL.Add(...)
  ADOQuery.SQL.Add(' WHERE Campo = :Param ');
  ADOQuery.Parameters.ParamByName('Param') --> devuelve el TParameter correspondiente

Se crea automaticamente un objeto TParameter con nombre o "identificador" 'Param'.

Si por algun motivo te interesa desactivar esto ultimo y encargarte vos mismo de crear los parametros, debes setear la propiedad ParamCheck a False

El problema son los parametros pero por ambiguedad; internamente la coleccion TParameters del TADOQuery va a tener dos parametros llamados igual y uno va a quedar sin un valor definido y por eso tiene conflicto de datos

Prueba de concepto (necesario que el ADOQuery tenga su propiedad Connection seteada a una conexion "valida")

Código Delphi [-]
procedure TForm1.FormCreate(Sender: TObject);
var
  Param: TParameter;
begin
  ADOQuery1.SQL.Text := ' SELECT * FROM Clientes WHERE Nombre = :Nombre ';
  Param := ADOQuery1.Parameters.AddParameter;
  Param.Name := 'Nombre';
  Param.DataType := TFieldType.ftInteger;
  ShowMessage(ADOQuery1.Parameters.Count.ToString); // imprime 2
  if ADOQuery1.Parameters.ParamByName('Nombre') <> Param then // evalua true
    ShowMessage('son distintos objetos');
end;

koalasoft 01-02-2017 01:46:46

Bueno no se si sea la forma mas elegante o teng consecuencia a futuro .. pero al menos de esta forma me funcionó..

Puse los valores en una variable ..

Código PHP:

Var   B,F,S,P,integer;
..
.
.
// Variables
B:= StrToInt(Edit1.Text);
F:= StrToInt(Edit2.Text);
S:= StrToInt(Edit3.Text);
P:= StrToInt(Edit4.Text);
O:= StrToInt(Edit5.Text); 

De alli aplique la consulta siguiente ...

Código PHP:

Close;
   
SQL.Clear;
   
SQL.Add('SELECT * FROM CTRLONT CTRL ');
   
SQL.Add('join CLIENTES CL on CTRL.FOLIO = CL.FOLIO ');
   
SQL.Add('join ONTs ONT on CTRL.FOLIO = ONT.Folio ');
   
SQL.Add('WHERE CTRL.BOARD_ONT = 'IntToStr(B));
   
SQL.Add(' AND CTRL.FRAME_ID = 'IntToStr(F));
   
SQL.Add(' AND CTRL.SLOT_ID = 'IntToStr(S));
   
SQL.Add(' AND CTRL.PORT_ID = '+  IntToStr(P));
   
SQL.Add(' AND CTRL.ONT_ID = '+  IntToStr(O));
   
Open

Y ahora si no me envió NINGUN mensaje de error y me ejecuto la búsqueda al menos como lo hacía antes. ^\||/

bitbow 01-02-2017 17:11:27

No es la forma adecuada, puedes llegar a tener problemas con los tipos de datos o cadenas con comilla simple, lo ideal es usar los params ya que con ellos te evitas esos temas.

Revisando lo que comenta Agustin es correcto, al agregar a la setencia ":valor" el parametro es creado automaticamente, revisa si el prefijo de params esta como caracter ":" , en algunso caso viene como "@" (en algun componente lo llegue a ver) y la otra es el params check que se encuentr en false, por ultimo te recomendaria (si tu sentencia es fija y siempre usa los mismos parametros) setearla desde diseño y ahi podras ver si se crean los parametros y asignarle valores en diseño para pruebas.

Saludos.


La franja horaria es GMT +2. Ahora son las 20:57:14.

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