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)
-   -   Error al insertar en bd con parametros (https://www.clubdelphi.com/foros/showthread.php?t=94765)

identsoft 02-07-2020 11:57:22

Error al insertar en bd con parametros
 
Un saludo para todos.
Al insertar datos en una tabla con sql y parámetros me da el error :'Assertion failure (c:\user\code\....\firebird.sql.pas, line 1004)'.
Lo que hago es :
1.-leer un fichero de texto plano con separador de campos('|').
2.-Separar cada campo para asignárselo a cada parámetro
3.- Insertarlo en la base de datos.

Código Delphi [-]
          Readln(f,slinea);
          SQLInsertar.Close;
          SQLInsertar.SQL.Clear;
          SQLInsertar.SQL.Text := 'INSERT INTO AGENTES (AGENTE,NOM_AGENTE,DIR_AGENTE,POB_AGENTE,' +
               'CPOS_AGENTE,TELEFONO1,FAX,PROVIN,OBSERVACIONES,POR_RETE,POR_COMIS, ' +
               'CTA_SUPLIDOS,CTA_CLIENTE)' +
               ' VALUES (:IAGENTE,:INOM_AGENTE,:IDIR_AGENTE,:IPOB_AGENTE, ' +
               ':ICPOS_AGENTE,:ITELEFONO1,:IFAX,:IPROVIN,:IOBSERVAC,:IPOR_RETE,:IPOR_COMIS, ' +
               ':ICTA_SUPLIDOS,:ICTA_CLIENTE)';
          SQLInsertar.ParamByName('IAGENTE').AsInteger := StrToInt(GetToken(slinea,'|',1));
          SQLInsertar.ParamByName('INOM_AGENTE').AsString := StringReplace(getToken(slinea,'|',2),',',' ',[rfReplaceAll]);
          SQLInsertar.ParamByName('IDIR_AGENTE').AsString := StringReplace(getToken(slinea,'|',3),',',' ',[rfReplaceAll]);
          SQLInsertar.ParamByName('IPOB_AGENTE').AsString := StringReplace(getToken(slinea,'|',4),',',' ',[rfReplaceAll]);
          SQLInsertar.ParamByName('ICPOS_AGENTE').AsInteger := StrToInt(getToken(slinea,'|',5));
          SQLInsertar.ParamByName('ITELEFONO1').AsString := getToken(slinea,'|',6);
          SQLInsertar.ParamByName('IFAX').AsString := getToken(slinea,'|',7);
          SQLInsertar.ParamByName('IPROVIN').AsInteger := StrToInt(getToken(slinea,'|',8));
          SQLInsertar.ParamByName('IOBSERVAC').AsString := getToken(slinea,'|',9);
          SQLInsertar.ParamByName('IPOR_RETE').AsFloat := StrToFloat(getToken(slinea,'|',10));
          SQLInsertar.ParamByName('IPOR_COMIS').AsFloat := StrToFloat(getToken(slinea,'|',11));
          SQLInsertar.ParamByName('ICTA_SUPLIDOS').AsString := getToken(slinea,'|',12);
          SQLInsertar.ParamByName('ICTA_CLIENTE').AsString := getToken(slinea,'|',13);
          SQLInsertar.ExecSQL;
          SQLInsertar.Close;
El error lo da al ejecutar la linea :SQLInserta.ExecSQL.

El tipo de parámetro (asinteger,..) es correcto( es decir coincide con el tipo de campo de la BD) y la separación de campos también lo hace bien.
GetToken es una función para separar campos.

Utilizo Dephi XE7 y Firebird 2.5 con Windows 10

Alguna idea?
Gracias por vuestro tiempo

Neftali [Germán.Estévez] 02-07-2020 12:19:26

¿Con qué componentes estás trabajando?
¿No hay más info. del error?
¿Si intentas lanzar la misma consulta (sustituyendo los parámetros) directamente sobre la Base de Datos (con el Administrador que tengas), te da algún error?

identsoft 02-07-2020 17:15:11

1.-Estoy trabajando con DBExpres (perdón por no decirlo antes).
2.- No hay más info del error. Eso es todo lo que sale.
3.- Si sustituyo los parámetros por sql directo, funciona bien. No da error:
Código Delphi [-]
         SQLInsertar.SQL.Text := 'INSERT INTO AGENTES (AGENTE,NOM_AGENTE,DIR_AGENTE,POB_AGENTE,' +
               'CPOS_AGENTE,TELEFONO1,FAX,PROVIN,OBSERVACIONES,POR_RETE,POR_COMIS, ' +
               'CTA_SUPLIDOS,CTA_CLIENTE)' +
               'VALUES (' + getToken(slinea,'|',1) + ',' + QuotedStr(gettoken(sLinea,'|',2)) + ',' + QuotedStr(gettoken(slinea,'|',3)) + ',' +
               QuotedStr(gettoken(slinea,'|',4)) +','+ gettoken(slinea,'|',5) + ',' + QuotedStr(gettoken(slinea,'|',6)) +',' + QuotedStr(gettoken(slinea,'|',7)) + ',' + gettoken(slinea,'|',8) + ',' +
               QuotedStr(gettoken(slinea,'|',9)) + ',' + stringreplace(gettoken(slinea,'|',10),',','.',[rfReplaceAll]) + ',' + StringReplace(gettoken(slinea,'|',11),',','.',[rfReplaceAll]) + ',' +
               QuotedStr(gettoken(slinea,'|',12)) + ',' + QuotedStr(gettoken(slinea,'|',13)) + ')';

Pero hasta ahora confiaba más en parámetros.

Casimiro Notevi 02-07-2020 17:41:10

Falta información, suponemos que estás haciendo un bucle al leer de un fichero de texto.
Seguramente es una línea de ese fichero de texto que tiene datos que no son correctos.
Además, si es así, o sea, es un bucle, por lógica, ese código no debería ser así, sino así:
Código Delphi [-]
Q.SQL.Text := 'INSERT INTO AGENTES (AGENTE,NOM_AGENTE,DIR_AGENTE,POB_AGENTE,' +
              'CPOS_AGENTE,TELEFONO1,FAX,PROVIN,OBSERVACIONES,POR_RETE,POR_COMIS, ' +
              'CTA_SUPLIDOS,CTA_CLIENTE)' +
              ' VALUES (:IAGENTE,:INOM_AGENTE,:IDIR_AGENTE,:IPOB_AGENTE, ' +
              ':ICPOS_AGENTE,:ITELEFONO1,:IFAX,:IPROVIN,:IOBSERVAC,:IPOR_RETE,:IPOR_COMIS, ' +
              ':ICTA_SUPLIDOS,:ICTA_CLIENTE)';

Aquí bucle de lectura del fichero de texto
  Readln(f,slinea);
  Q.Close;
  Q.ParamByName('IAGENTE').AsInteger := StrToInt(GetToken(slinea,'|',1));
  Q.ParamByName('INOM_AGENTE').AsString := StringReplace(getToken(slinea,'|',2),',',' ',[rfReplaceAll]);
  Q.ParamByName('IDIR_AGENTE').AsString := StringReplace(getToken(slinea,'|',3),',',' ',[rfReplaceAll]);
  ...
  Q.ExecSQL;

fin del bucle.

identsoft 02-07-2020 18:23:59

Tienes razón Casimiro y ya está arreglado, pero el error es otro: "Assertion failure (c:\user\code\....\firebird.sql.pas, line 1004).
Voy a seguir tu consejo y revisar el fichero por si viene alguna linea con datos no correctos.

Gracias a ambos

Casimiro Notevi 02-07-2020 18:37:09

Pon un simple contador y muéstralo para saber en qué línea ocurre, algo temporal, como esto:
Código:

iContador:=0;

inicio bucle
  lee línea;
  inc(iContador);
  label1.caption := intTostr(icontador);
  application.processmessages;
  q.close;
  q.param...
  q.param...
  q.exec
fin de bucle


Neftali [Germán.Estévez] 03-07-2020 09:35:57

Cita:

Empezado por identsoft (Mensaje 537851)
Pero hasta ahora confiaba más en parámetros.


Correcto, es lo recomendable. Siempre utilizar parámetros.
El hacer la prueba sin ellos es simplemente para ver si la misma consulta directamente da algún problema y descartar así otros errores.

delphi.com.ar 03-07-2020 17:21:44

Mi segundo offtopic del día:

1. ¿El archivo "firebird.sql.pas" es tuyo?... De ser así, ¿Cuál es la línea 1004?
2. ¿Tienes alguna garantía, o has validado anteriormente que "slinea" tenga 14 elementos?

PD: A simple vista parecería mucho mas óptimo hacer un "SplitString" por única vez por línea, para luego tomar cada uno de los elementos del array.

identsoft 07-07-2020 11:08:20

Cita:

Empezado por delphi.com.ar (Mensaje 537865)
Mi segundo offtopic del día:

1. ¿El archivo "firebird.sql.pas" es tuyo?... De ser así, ¿Cuál es la línea 1004?
2. ¿Tienes alguna garantía, o has validado anteriormente que "slinea" tenga 14 elementos?

PD: A simple vista parecería mucho mas óptimo hacer un "SplitString" por única vez por línea, para luego tomar cada uno de los elementos del array.

1- El archivo no es mio.Debe ser de Delphi.
2.- Sí, está validado y con valores correctos, no viene ningún carácter extraño.

Después de mucho probar conseguí saber donde está el error.
El error me da en los campos POR_RETE y POR_COMIS. Si quito estos campos, el proceso de inserción lo hace correctamente.
Estos campos están definidos en la BD. como campos decimal(5,2)
En slinea vienen (ambos) con valor 0,0.
El parámetro los defino como asFloat:
Código Delphi [-]
 (SQLInsertar.ParamByName('IPOR_RETE').AsFloat := StrToFloat(getToken(slinea,'|',10));
  SQLInsertar.ParamByName('IPOR_COMIS').AsFloat := StrToFloat(getToken(slinea,'|',11));

Y aquí es cuando se produce el error en el momento de insertar (sqlinsertar.execsql). No da ningún error cuando se hace la asignación.
¿Que es lo que estoy haciendo mal?

Gracias a todos por vuestro tiempo

Casimiro Notevi 07-07-2020 11:16:33

Pues haz lo que te comenté para saber en qué línea del fichero de texto ocurre.
Seguramente esté vacío, tenga punto en lugar de coma, etc.

identsoft 07-07-2020 11:31:15

He revisado el texto. He reducido el fichero a una sola linea para probar.
No da error al leer o asignar a parámetros. La asignación la hace correctamente (comprobado paso a paso).
A los parámetros de tipo float les asigna el valor 0 (cero).
Pero sigue sigue dando el mismo error al hacer el execSql.

No es que de error en una linea cualquiera, lo da ya en la primera.

Casimiro Notevi 07-07-2020 11:39:12

¿El error firebirdsqlpas, o así?
Revisa el proyecto, a ver si has metido algo raro por ahí.

identsoft 07-07-2020 12:07:40

1 Archivos Adjunto(s)
El proyecto, que yo sepa, no tiene nada raro.
Es un único formulario que tiene que leer de diferente ficheros de texto separados por '|' e insertarlos en diferentes tablas de una base de datos Firebird previamente creada.
El error me da en los campos que hay definidos como decimal(xx,xx) y que intento cargarlos con parámetros tipo Float.
Si quito de la instruccion Insert los campos que ,en la BD están definidos como decimal, el insert se ejecuta perfectamente.
La conexión con la BD se hace a través de SQLConnection.

El fichero ..\firebird.sql.pas line 1004 no se donde está ni que es. No tengo una carpeta c:\user\source\...

Adjunto el mensaje de error

Casimiro Notevi 07-07-2020 12:21:48

Pues qué es ese fichero, en algún sitio debe de estar, o es de algún componente que estás usando, porque el project\moon\core\source\firebird no es ningún directorio de firebird.

identsoft 07-07-2020 13:42:18

Parece que se ha solucionado copiando los ficheros fbclient.dll y dbx4fb.dll a la carpeta del ejecutable.
Gracias a todos y siento el tiempo perdido con esta estupidez.


La franja horaria es GMT +2. Ahora son las 05:00:32.

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