Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 25-02-2026
GINMARMENOR GINMARMENOR is offline
Miembro
 
Registrado: feb 2016
Posts: 79
Poder: 11
GINMARMENOR Va por buen camino
Grabacion de Registros en una tabla.

Muy buenas, Estoy Trabajando con Delphi 2.010 y uso Firibird 2.5 las bases de datos las he creado con IbExpert, y de momento llevo creando el programa varios años, y todo funciona bien, dentro del programa tengo un total de unas 50 Tablas (IbTables) con sus TDataSources correspondientes, las Tablas más importantes que más utilizo que es la IbTablaPedidos, dispone de 85 campos en los cuales trabajo a una velocidad normal tarda 2 a 3 segundos en guardar un pedido, aunque aparentemente es lento pero se puede trabajar bien, siempre utilizo este Sintaxis para grabar los pedidos:

Código:
 
                IbTablePedidos.Insert
                IbTablaPedidosID.Asinteger:=StrtoInt(edit1.text);
                IbTablaPedidosCodigo.AsInteger:=Strtoint(edit2.text);
                   .
                   .
                   .
                IbTablaPedidosCantidad:AsInteger:=StrtoInt(Edit20.text);
             
                IbTablePedidos.post;
Introduzco de una tirada unos 15 ó 20 Campos de una tirada.

Pero acabo de crear una nueva Tabla que tiene 140 campos, pero de una tirada grabo unos 25 campos, el resto de campos los voy introduciendo en otros procesos, pero resulta que ahora en vez de 2 ó 3 segundos en grabar tarda de 30 segundos más o menos, utilizando un código similar.

No sé si es debido a tener tantos campos en la tabla, o es el código, si me pueden echar una mano,

La tabla anterior tiene dentro unos 2.000 registros, y funciona con ese desfase de 2 ´o 3 segundos

Ésta nueva tabla al ser creada hace poco dispone de unos 40 registros pero siempre en cada grabación tarda unos 30 segundos.

Si me pueden echar una mano para ver el por qué o si debo cambiar el código se lo agradecería
Responder Con Cita
  #2  
Antiguo 25-02-2026
chenech chenech is offline
Miembro
 
Registrado: dic 2013
Posts: 138
Poder: 13
chenech Va por buen camino
las Table creo que estan por compatibilidad con BDE y no las recomienda casi nadie, yo uso Query con un Insert siempre y en tablas con 60 millones de registros y mas de 90 campos tarda menos de un segundo, siempre milisegundos, en algunos clientes tengo FireBird 2.5 y en otros FireBird 3 y lo mismo practicamente, prueba a usar esto:
Código:
INSERT INTO TABLEX (CAMPO1, CAMPO2, CAMPO3 ...)
VALUES (:PCAMPO1, :PCAMPO2, :PCAMPO3 ...)
FieldByParam('PCAMPO1').AsInteger := StrToInt(Edit1.Text);
...
...

Última edición por chenech fecha: 25-02-2026 a las 20:30:37.
Responder Con Cita
  #3  
Antiguo 26-02-2026
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 19.435
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por GINMARMENOR Ver Mensaje
Pero acabo de crear una nueva Tabla que tiene 140 campos, pero de una tirada grabo unos 25 campos, el resto de campos los voy introduciendo en otros procesos, pero resulta que ahora en vez de 2 ó 3 segundos en grabar tarda de 30 segundos más o menos, utilizando un código similar.
La tablas muy "anchas" (con muchos campos) se hacen más lentas, por la forma de acceder a los campos, de todas formas 30 segundos me parece algo desorbitado.
Está claro que eso no es normal.

Yo intentaría ir descartando cosas o haciendo pruebas con diferentes factores para ver dónde está el problema.
* Intentar realizar la conexión con el mismo código pero con otros componentes (FireDac, ADO+ODBC).
* Revisar que no estés realizando la conexión cada vez (eso justificaría los 30 sg. aunque tampoco sería normal)
* Probar con otra Base de datos sólo con esa tabla (descartar problemas en ese fichero).
* Probar en local si está en red (para eliminar ese factor)
* Reducir los campos de la tabla a ver si en algún momento ese tiempo baja (-cosa que sería muy rara-).
* Realizar el mismo INSERT, pero en lugar de utilizar un IBTable, utilizar un IBQuery (y todo lo demás igual).
* ...
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 27-02-2026
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.806
Poder: 22
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
También mira si tienes procedimientos que se ejecuten como eventos de algunas tablas.
OnBeforeInsert/Update/Post/Close/Open
OnAfterInsert/Update/Post/Close/Open

Debuga con alguna forma de log apra ver cuanto tarda cada parte;

Código Delphi [-]
/// Procedimiento simple para guardar en un fichero eventos de log
/// El fichero tiene el mismo nombre que la aplicacion
procedure Log(s: string);
var
  F : TextFile;
  FileName : string;
begin
  FileName := ChangeFileExt(Application.ExeName, '.log');
  AssignFile(F, FileName);
  try
     Append(F);
  except
     try
        Rewrite(F);
     except
        on e: Exception do
           ShowMessage('LOG - Error al abrir fichero : ' + FileName + #13#10 + e.Message);
     end;
  end;
  WriteLn(F, FormatDatetime('[yyyy-mm-dd hh:nn:ss.zzz] ', Now) + s);
  CloseFile(F);
end;

[...]

  Log('Insert');
  IbTablePedidos.Insert
  Log('Asignacion');
  IbTablaPedidosID.Asinteger:=StrtoInt(edit1.text);
  IbTablaPedidosCodigo.AsInteger:=Strtoint(edit2.text);
  .
  .
  .
  IbTablaPedidosCantidad:AsInteger:=StrtoInt(Edit20.text);
             
  Log('Post');
  IbTablePedidos.post;
  Log('Fin Insert');
Responder Con Cita
  #5  
Antiguo 13-03-2026
Avatar de olbeup
olbeup olbeup is offline
Miembro
 
Registrado: jul 2005
Ubicación: Santiago de la Ribera (España)
Posts: 688
Poder: 21
olbeup Va camino a la fama
Hola GINMARMENOR,

En vez de utilizar
Código Delphi [-]
IbTablePedidos.Insert
utiliza el
Código Delphi [-]
IbTablePedidos.Append
, este último lo pone al final del fichero y el que utilizas lo pone al principio desplazando todos los demás y creo que ese es el retraso que tienes.

Un saludo.
__________________
Al hacer una consulta SQL, haz que los demás te entiendan y disfruten de ella, será tú reflejo de tú saber.
Responder Con Cita
  #6  
Antiguo Hace 2 Semanas
GINMARMENOR GINMARMENOR is offline
Miembro
 
Registrado: feb 2016
Posts: 79
Poder: 11
GINMARMENOR Va por buen camino
Buenas estoy siguiendo los pasos de chenec mediante SQL, pero no encuentro la syntaxys correcta según su ejemplo es el siguiente,

Cita:
INSERT INTO TABLEX (CAMPO1, CAMPO2, CAMPO3 ...)
VALUES (:PCAMPO1, :PCAMPO2, :PCAMPO3 ...)
FieldByParam('PCAMPO1').AsInteger := StrToInt(Edit1.Text);
...
...
Yo estoy utilizando prácticamente la misma la secuencia, pero tengo que insertar un ibQuery1 y enlazarlo a la Tablax del siguiente modo:


Cita:
select * from TableX
A partir de ahí utilizo el siguiente código:

Cita:
IbQuery1.clear;
IbQuery1.sql.close

IbQuery.Text:=' INSERT INTO TABLEX (CAMPO1, CAMPO2, CAMPO3 ...)
VALUES (:PCAMPO1, :PCAMPO2, :PCAMPO3 ...) ';

IbQuery.open;

FieldByParam('PCAMPO1').AsInteger := StrToInt(Edit1.Text);
...
...

Pero no funciona, da error, como siempre busco por internet pero no encuentro la sintaxys correcta, si podéis echarme una mano, . en principio sería sólo insertar un registro mediante únicamente sql, que es más rápido que utilizar BDE con IbTable.append, IbTbable Post, que a veces me da problemas, ralentizándose bastante. Gracias.
Responder Con Cita
  #7  
Antiguo Hace 2 Semanas
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.806
Poder: 22
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
No mencionas el mensaje de error que te devuelve la aplicación.
De todos modos, creo que se trata del "Open".
En el caso de que no se devuelvan datos, deberías utilizar ExecQuery.

Además, debes asignar los parámetros antes de ejecutar el query o abrir una tabla.

Código Delphi [-]

// Cierro el DataSet si esta abierto.
IbQuery1.Close

// Limpio la sentencia SQL
IbQuery1.SQL.Clear;

// Cargo la sentencia SQL que me interesa
IbQuery.Text:=' INSERT INTO TABLEX (CAMPO1, CAMPO2, CAMPO3 ...)
VALUES (:PCAMPO1, :PCAMPO2, :PCAMPO3 ...) ';

// Asigno valores a los parámetros
FieldByParam('PCAMPO1').AsInteger := StrToInt(Edit1.Text);

// Ejecuto Sentencia SQL
IbQuery.ExecQuery;

// Cierro el DataSet.
IbQuery1.Close;

// Commit de la transaccion ???
IbQuery1.Transaction.Commit;
...
Responder Con Cita
  #8  
Antiguo Hace 2 Semanas
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.806
Poder: 22
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Yo trabajo con TFDQuery contra una base de datos Firebird, pero supongo que es más o menos lo mismo...

Código Delphi [-]
// ------------------------------------------------------------
// UNIDAD UUTILES.PAS

function DameTransactionRO(BaseDeDatos: TFDConnection; Iniciar: Boolean = False): TFDTransaction;
begin
  Result := TFDTransaction.Create(BaseDeDatos);
  with Result do
  begin
    Connection := BaseDeDatos;
    Options.AutoCommit := True;
    Options.DisconnectAction := xdCommit;
    Options.Isolation := xiReadCommitted;
    Options.ReadOnly := True;
    {
      Options.Params.Clear;
      Options.Params.Add('read_committed'); // do not localize
      Options.Params.Add('read'); // do not localize
    }

    if Iniciar and (not Result.Active) then
      StartTransaction;
  end;
end;

function DameTransactionRW(BaseDeDatos: TFDConnection; Iniciar: Boolean = False): TFDTransaction;
begin
  Result := TFDTransaction.Create(BaseDeDatos);
  with Result do
  begin
    Connection := BaseDeDatos;
    Options.AutoCommit := True;
    Options.DisconnectAction := xdRollback;
    Options.Isolation := xiSnapshot;
    Options.ReadOnly := False;
    {
      Options.Params.Clear;
      Options.Params.Add('read_committed'); // do not localize
      Options.Params.Add('rec_version'); // do not localize
      Options.Params.Add('nowait'); // do not localize
    }

    if Iniciar and (not Result.Active) then
      StartTransaction;
  end;
end;

function DameQueryRO(AOwner: TComponent; BaseDeDatos: TFDConnection): TFDQuery;
begin
  Result := TFDQuery.Create(AOwner);
  with Result do
  begin
    Connection := BaseDeDatos;
    Transaction := DameTransactionRO(BaseDeDatos, True);
  end;
end;

function DameQueryRW(AOwner: TComponent; BaseDeDatos: TFDConnection): TFDQuery;
begin
  Result := TFDQuery.Create(AOwner);
  with Result do
  begin
    Connection := BaseDeDatos;
    Transaction := DameTransactionRW(BaseDeDatos, True);
  end;
end;

// ------------------------------------------------------------
// UTILIZACION EN UN DATAMODULE

TDM = class(TDataModule)
    DB: TFDConnection;
[...]

procedure TDM.RegistraEntrada;
begin
  with DameQueryRW(Self, DB) do
  begin
    try
      SQL.Text := 'EXECUTE PROCEDURE LOG_ENTRADAS (:ID_USUARIO)';
      ParamByName('ID_USUARIO').AsInteger := Entorno.IdUsuario;
      ExecSQL;

      Close;
      Transaction.Commit;
    finally
      Free;
    end;
  end;
end;
Responder Con Cita
  #9  
Antiguo Hace 2 Semanas
GINMARMENOR GINMARMENOR is offline
Miembro
 
Registrado: feb 2016
Posts: 79
Poder: 11
GINMARMENOR Va por buen camino
Es correcto, lo he hecho en principio sin Transactiones pero funciona perfectamente, mil gracias
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
Duda sobre grabación de registros usuario1000 Varios 25 18-02-2019 14:13:17
Update registros de columna1 de tabla A con registros de columna1 de tabla B soldierxp Firebird e Interbase 0 08-09-2013 16:45:09
enviar registros de una tabla a un campo de otra tabla a travez de ciclo IF en MYSQL CLUSTERBIT SQL 8 23-10-2008 15:50:03
grabación jorodgar Windows 4 19-09-2005 11:22:42
Seleccionar registros en una tabla, envio, e insercion en otra tabla!! EfrainSanmiguel Conexión con bases de datos 3 21-10-2004 01:12:43


La franja horaria es GMT +2. Ahora son las 03:27:56.


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