Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Mostrar consulta SQL con parámetros (https://www.clubdelphi.com/foros/showthread.php?t=95370)

ethangio 31-08-2021 07:52:05

Mostrar consulta SQL con parámetros
 
Buen día a todos y gracias por tomarse el tiempo para leer mi pregunta.

Antes de hacer la pregunta busqué pero no encontré cómo poder ver mi consulta SQL con parámetros.

Tengo esta consulta en código delphi:
Código Delphi [-]
Query.Close;
Query.Clear;
Query,SQL.Add(' INSERT INTO ventas (folio, fecha, clave, producto) ');
Query.SQL.Add(' VALUES (:folio, :fecha, :clave, :producto) ');
Query.ParamByName('folio').AsInteger      := '1'; 
Query.ParamByName('fecha').AsString      := '2021-08-31';
Query.ParamByName('clave').AsString      := 'AB001';
Query.ParamByName('producto').AsString := 'Azúcar';
Query.Prepared := true;
Query.ExecSQL;
Si hago un:
Código Delphi [-]
ShowMessage(Query.SQL.text);
Me muestra la consulta de la siguiente manera:
Código SQL [-]
INSERT INTO ventas (folio, fecha, clave, producto) VALUES (:folio, :fecha, :clave, :producto)
Y yo quisiera ver la consulta así:
Código SQL [-]
INSERT INTO ventas (folio, fecha, clave, producto) VALUES (1, '2021-08-31', 'AB001', 'Azúcar')
Cómo puedo lograr esto ?

Casimiro Notevi 31-08-2021 10:23:59

Cita:

Empezado por ethangio (Mensaje 542528)
Cómo puedo lograr esto ?

No usando parámetros.
Pero es mejor usar parámetros.
Depende de la base de datos que estés usando, puedes ver las sentencias que ejecuta la misma.

kuan-yiu 31-08-2021 10:52:54

Siempre puedes construir tú mismo un procedimiento que haga eso.

Caminante 31-08-2021 15:36:17

Cita:

Empezado por ethangio (Mensaje 542528)
Buen día a todos y gracias por tomarse el tiempo para leer mi pregunta.
Código Delphi [-]Query.Close; Query.Clear; Query,SQL.Add(' INSERT INTO ventas (folio, fecha, clave, producto) '); Query.SQL.Add(' VALUES (:folio, :fecha, :clave, :producto) '); Query.ParamByName('folio').AsInteger := '1'; <---- Aqui tengo la duda Query.ParamByName('fecha').AsString := '2021-08-31'; Query.ParamByName('clave').AsString := 'AB001'; Query.ParamByName('producto').AsString := 'Azúcar'; Query.Prepared := true; Query.ExecSQL;

Hola


Solo una observacion. Si haces Query.ParamByName('folio').AsInteger ¿Porque envias el valor entrecomillado? ¿No te da error ahi?

ethangio 31-08-2021 18:34:41

Cita:

Empezado por Casimiro Notevi (Mensaje 542531)
No usando parámetros.
Pero es mejor usar parámetros.
Depende de la base de datos que estés usando, puedes ver las sentencias que ejecuta la misma.

Me confunde tu respuesta :D ...

Entiendo que no es posible entonces. Estoy usando ZeosLib y MySQL.

Gracias por responder. Saludos.

ethangio 31-08-2021 18:38:24

Cita:

Empezado por kuan-yiu (Mensaje 542536)
Siempre puedes construir tú mismo un procedimiento que haga eso.

Pensé en hacerlo pero no quería reinventar la rueda :) , pensé que algo ya había para ver la consulta SQL.

Enviaré los parámetros como argumentos a una función se me ocurre.

Les comento que esto que quiero hacer es para guardar en una tabla la consulta ejecutada.

ethangio 31-08-2021 18:40:27

Cita:

Empezado por Caminante (Mensaje 542538)
Hola


Solo una observacion. Si haces Query.ParamByName('folio').AsInteger ¿Porque envias el valor entrecomillado? ¿No te da error ahi?

Si tienes razón causa error, una disculpa hice el ejemplo al momento de formular mi pregunta.

Solo era para ejemplificar :) . Saludos.

Casimiro Notevi 31-08-2021 19:38:51

Cita:

Empezado por ethangio (Mensaje 542541)
Me confunde tu respuesta :D ...
Entiendo que no es posible entonces. Estoy usando ZeosLib y MySQL.

Lo que quiero decir es que algunas BD lo permiten y otras no, desconozco si con MySql se puede.

Cita:

Empezado por ethangio (Mensaje 542542)
Les comento que esto que quiero hacer es para guardar en una tabla la consulta ejecutada.

Precisamente, con Firebird puedes hacerlo, todas las sentencias sql puedes ir viéndolas, guárdandolas en una tabla o como quieras.

ethangio 31-08-2021 20:10:36

Sigo investigando y encontré que en MySQL si cambiamos los valores de las variables log_output y general_log las consultas realizadas podemos verlas en la base de datos mysql en la tabla general_log.

Estos son los pasos:

Código SQL [-]
SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = 'ON';

Se me ocurre que cuando haga una consulta SQL inmediatamente vaya a esa base de datos y de esa tabla tome la ultima consulta ejecutada para guardarla en mi base de datos y en mi tabla.

Las preguntas que me surgen son:

Está bien hacer eso ?
Es seguro ?
Es una buena manera de hacer las cosas o debería hacer mi propia función o procedimiento ?
Que problemas futuros puedo encontrarme ?

mamcx 01-09-2021 03:20:41

Cita:

Empezado por ethangio (Mensaje 542528)
Código Delphi [-]
Query,SQL.Add(' INSERT INTO ventas (folio, fecha, clave, producto) ');
Query.SQL.Add(' VALUES (:folio, :fecha, :clave, :producto) ');
Query.ParamByName('folio').AsInteger      := '1'; 
Query.ParamByName('fecha').AsString      := '2021-08-31';
Query.ParamByName('clave').AsString      := 'AB001';
Query.ParamByName('producto').AsString := 'Azúcar';
Si hago un:
Código Delphi [-]
ShowMessage(Query.SQL.text);

Ahi mismo en tu ejemplo esta la solucion. Recorre los params del objeto y los imprimes "debajo" del sql o haces una substitucion. Un tip si quieres hacer reemplazo: Ordena los nombres de mayor a menos y reemplazas, no lo hagas directo, asi no te saldran problemas si un param es menor a otro (como "var" y "variable")

ethangio 01-09-2021 04:44:55

Cita:

Empezado por mamcx (Mensaje 542550)
Ahi mismo en tu ejemplo esta la solucion. Recorre los params del objeto y los imprimes "debajo" del sql o haces una substitucion. Un tip si quieres hacer reemplazo: Ordena los nombres de mayor a menos y reemplazas, no lo hagas directo, asi no te saldran problemas si un param es menor a otro (como "var" y "variable")

Agradezco mucho tu respuesta. No sé hacerlo pero lo voy a investigar y hacerlo hasta que lo logre.

Saludos y de nuevo gracias.

engranaje 01-09-2021 09:31:36

Como ya te han recomendado es posible que la mejor opción para tí sea utilizar el propio log de Mysql que como leo estas investigando, o hacerte una función que recorra los parámetros de la query y los sustituya por el valor.


De todas formas basándome en tu ejemplo, algo rápido para salir del paso y desde luego nada reutilizable puede ser algo de este estilo:


Código Delphi [-]
Query.Close;
Query.Clear;
strInsert := ' INSERT INTO ventas (folio, fecha, clave, producto) ';
strValuesAUtilizar := ' VALUES (:folio, :fecha, :clave, roducto) ';

Query,SQL.Add(strInsert);
Query.SQL.Add(strValuesAUtilizar);
Query.ParamByName('folio').AsInteger      := 1; 
Query.ParamByName('fecha').AsString      := '2021-08-31';
Query.ParamByName('clave').AsString      := 'AB001';
Query.ParamByName('producto').AsString := 'Azúcar';
Query.Prepared := true;
                                                          
strValuesParaLog := format(' VALUES (%d, %s, %s, %s) ',  [Query.params[0].asInteger,
                                                          quotedstr(Query.params[1].asstring),
                                                          quotedstr(Query.params[2].asstring),
                                                          quotedstr(Query.params[3].asstring)]);                                                          
Query.ExecSQL;                                                            
showmessage(strInsert + #13 +strValuesParaLog);

kuan-yiu 01-09-2021 09:58:57

Yo tengo esta (no es mía sino de un compañero):
Código Delphi [-]
   if query.sql.Text <> '' then
   begin
      consulta := stringReplace(query.sql.Text, #13#10, ' ', [rfreplaceall]);

      for i:= 0 to query.ParamCount-1 do
      begin
         try
            if query.Params[i].DataType = ftString then
                  consulta := stringReplace(sSql, ':'+ query.Params[i].Name, QuotedStr(query.Params[i].AsString), [rfreplaceall, rfIgnoreCase])
            else if query.Params[i].DataType = ftDateTime then
                  consulta := stringReplace(sSql, ':'+ query.Params[i].Name, QuotedStr(FormatDateTime('yyyy/mm/dd', query.Params[i].AsDateTime)), [rfreplaceall, rfIgnoreCase])
            else  consulta := stringReplace(sSql, ':'+ query.Params[i].Name, query.Params[i].AsString, [rfreplaceall, rfIgnoreCase]);
         except
            // Lo que quieras hacer si falla
         end;
      end;

      // Devuelves 'consulta' o lo grabas o lo que necesites
   end;

movorack 01-09-2021 16:30:09

Otra opción es usar el monitor que tienen los componentes. En el caso de ZeosLib (no he usado esta suite) creo que el monitor es el TZSQLMonitor

ethangio 01-09-2021 21:40:18

Cita:

Empezado por kuan-yiu (Mensaje 542556)
Yo tengo esta (no es mía sino de un compañero):

Cita:

Empezado por engranaje (Mensaje 542555)
Como ya te han recomendado es posible que la mejor opción para tí sea utilizar el propio log de Mysql que como leo estas investigando, o hacerte una función que recorra los parámetros de la query y los sustituya por el valor.

Muchas gracias a ambos, con ayuda de los 2 pude hacer mi procedimiento:
Código Delphi [-]
procedure GuardaConsulta(Query: TZQuery; Conexion: TZConnection);
var
  QInsert          : TZQuery;
  FechaHora      : TDateTime;
  ConsultaSQL,
  VarTmp          : String;
  i                    : Integer;
begin
  // Cadena de consulta SQL
  ConsultaSQL := Query.SQL.Text;

  // Remplazamos los parámetros por sus valores
  for i := 0 to Query.Params.Count-1 do
  begin
    // Creamos el nombre del parámetro para remplazarlo
    VarTmp := ':'+Query.Params.Items[i].Name;
    if query.Params[i].DataType = ftString then
      ConsultaSQL := StringReplace(ConsultaSQL, VarTmp, QuotedStr(Query.Params.Items[i].Value), [rfIgnoreCase])
    else if query.Params[i].DataType = ftInteger then
      ConsultaSQL := StringReplace(ConsultaSQL, VarTmp, Query.Params.Items[i].Value, [rfIgnoreCase])
    else
      ConsultaSQL := StringReplace(ConsultaSQL, VarTmp, QuotedStr(Query.Params.Items[i].Value), [rfIgnoreCase]);
  end;

  // Insert del query
  QInsert := TZQuery.Create(nil);
  try
    //
    FechaHora := now();
    QInsert.Connection := Conexion;
    ReadySQL(QInsert);
    QInsert.SQL.Add(' INSERT INTO consultas_sql (query, fechahora) ');
    QInsert.SQL.Add(' VALUES('+ QuotedStr(ConsultaSQL) + QuotedStr(FormatDateTime('yyyy-mm-dd hh:nn:ss', FechaHora)) +')');
    QInsert.ExecSQL;
  finally
    //
    QInsert.Free;
  end;

end;

Muchas gracias movorack por el tip y a todos por sus respuestas. Saludos desde Puebla, México :)


La franja horaria es GMT +2. Ahora son las 11:01:44.

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