Ir al contenido


Foto

Error Code = -104


  • Por favor identifícate para responder
13 respuestas en este tema

#1 coruxito

coruxito

    Advanced Member

  • Miembros
  • PipPipPip
  • 55 mensajes

Escrito 23 abril 2012 - 09:11

Hola a todos, soy nuevo por el foro e peor aún, nuevo en Delphi !!!  :D
Intento com Delphi 7 + Firebird 2.5 hacer una funciona dentro de un botón para guardar unos datos de prueba y me dá en error:
Dynamic SQL Error SQL Error Code = -104

El código que tiene el botón es:


delphi
  1. IBQueryGuardar.SQL.Text:='Insert into Ficha (id_ficha,id_cliente,titulo,fecha_entrega,creador,'+
  2.                             'prioridad,departamento,'+
  3.                             'tipo_fallo,version) Values (2,1,Segunda Ficha,'+DateToStr(fecha)+',1,Alta,Prueba,Error,1.7)';
  4. IBQueryGuardar.ExecSQL;



La base de datos tiene los campos id_ficha y id_cliente como integer, el campo fecha_entrega el de tipo Date, todos los campos restantes son de tipo String.
Que creeis que puede ser ?
Estoy dando vueltas pero nada.
  • 0

#2 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 23 abril 2012 - 09:27

Bienvenido a DelphiAccess coruxito y bienvenido a Delphi !!!  (y)

Para insertar datos de tipo string, éstos deben ir entre comillas simples... 'Texto', igual que la fecha... '12/31/2011' con formato de mm/dd/yyyy

Intenta y nos platicas  8-|

Saludox ! :)
  • 0

#3 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.486 mensajes
  • LocationMexico City

Escrito 23 abril 2012 - 09:31

Complementando....



delphi
  1. var
  2. sFecha: String;
  3.  
  4. begin
  5.  
  6. sFecha := QuotedStr(FormatDateTime('mm/dd/yyyy',fecha)); // Da formato y le pone las comillas simples necesarias
  7.  
  8. IBQueryGuardar.SQL.Text:='Insert into Ficha (id_ficha,id_cliente,titulo,fecha_entrega,creador,'+
  9.                                             'prioridad,departamento,'+
  10.                                             'tipo_fallo,version) Values (2,1,''Segunda Ficha'','+sFecha+',''1'',''Alta'',''Prueba'',''Error'',''1.7'')';
  11. IBQueryGuardar.ExecSQL;
  12.  
  13. end;



Saludox ! :)
  • 0

#4 Caral

Caral

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.266 mensajes
  • LocationCosta Rica

Escrito 23 abril 2012 - 10:01

Hola
Siempre es mejor usar parametros para evitar errores:


delphi
  1. IBQueryGuardar.SQL.Text:='Insert into Ficha (id_ficha,id_cliente,titulo,fecha_entrega,creador,'+
  2.                             'prioridad,departamento, tipo_fallo,version) '+
  3.                           ' Values ( :idficha, :idClient,  :tit, :Fehc, :crea, :prio, :dep, :tipo, :vers )';
  4. IBQueryGuardar.Params[0].Value:= 2;
  5. IBQueryGuardar.Params[1].Value:= 1;
  6. IBQueryGuardar.Params[2].Value:= 'Segunda Ficha';
  7. IBQueryGuardar.Params[3].Value:=  DateToStr(Fecha);
  8. IBQueryGuardar.Params[4].Value:= 1;
  9. IBQueryGuardar.Params[5].Value:= 'Alta';
  10. IBQueryGuardar.Params[6].Value:= 'Prueba';
  11. IBQueryGuardar.Params[7].Value:= 'Error';
  12. IBQueryGuardar.Params[8].Value:= 1.7;
  13. IBQueryGuardar.ExecSQL;



Saludos
  • 0

#5 coruxito

coruxito

    Advanced Member

  • Miembros
  • PipPipPip
  • 55 mensajes

Escrito 23 abril 2012 - 10:30

Muchisimas Gracias Fenareth y Caral.
Eficacia total de vosotros.
Ahora ya no estoy en el trabajo, donde estoy con el Delphi 7, mañana voy probar.

Abrazos
  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.301 mensajes
  • LocationArgentina

Escrito 23 abril 2012 - 12:31

Hola coruxito,
Recuerda también que junto a ese número de error viene una descripción que aclara en que parte se ha producido. Concretamente para el caso del -104 se indica la fila y columna en donde se detecta la incongruencia.  ;)

Es de mucha importancia señalar el error exacto y completo para poder entender donde está realmente el problema.

Saludos,
  • 0

#7 coruxito

coruxito

    Advanced Member

  • Miembros
  • PipPipPip
  • 55 mensajes

Escrito 24 abril 2012 - 01:15

Delphius tienes razón, la verdad ya posté ayer despues de toda una tarde luchando contra Delphi con la ayuda de Google y estaba medio ciego.
El fallo a parte de lo que cité antes me dice:
Token Unknown - line 1, column 132 Ficha. Process stopped.

Ficha es la table que intento insertar los datos, creo que lo habia citado ya antes, pero bueno mejor que lo repita que no estea el dato.

Estoy probando la solucción de Fenareth, sigo con el fallo, pero bueno aun mla me he sentado.
  • 0

#8 coruxito

coruxito

    Advanced Member

  • Miembros
  • PipPipPip
  • 55 mensajes

Escrito 24 abril 2012 - 01:53

Estuve probando con la sugerencia de Caral, más que nada pq me pareció más acequible para escribir grandes instrucciones SQL, me parece que puedes hacer todo más ordenado, pero ahora me dá el fallo:
Violation of PRIMARY or UNIQUE KEY constraint "PKFICHAS" on Table "FICHAS"

Mi código está así:


delphi
  1. procedure TForm1.BGuardarClick(Sender: TObject);
  2. Var
  3.   fecha : TDateTime;
  4. begin
  5.   IBQueryCarga_Fichas.Last;
  6.   fecha:=EncodeDateTime(2012, 04, 24, 00, 00, 00, 000);
  7.  
  8.   IBQueryGuardar.SQL.Text:='Insert into Fichas (id_ficha,id_cliente,titulo,fecha_entrega,creador,'+
  9.                             'prioridad,departamento, tipo_fallo,version) '+
  10.                           ' Values ( :idficha, :idClient,  :tit, :Fehc, :crea, :prio, :dep, :tipo, :vers )';
  11.   IBQueryGuardar.Params[0].Value:= 2;
  12.   IBQueryGuardar.Params[1].Value:= 1;
  13.   IBQueryGuardar.Params[2].Value:= 'Segunda Ficha';
  14.   IBQueryGuardar.Params[3].Value:= DateToStr(fecha);
  15.   IBQueryGuardar.Params[4].Value:= 1;
  16.   IBQueryGuardar.Params[5].Value:= 'Alta';
  17.   IBQueryGuardar.Params[6].Value:= 'Prueba';
  18.   IBQueryGuardar.Params[7].Value:= 'Error';
  19.   IBQueryGuardar.Params[8].Value:= 1.7;
  20.  
  21.   IBQueryGuardar.ExecSQL;
  22. end;



Cambié el IBQueryGuardar y puse en SQL la instrunción:

Insert into Fichas (id_ficha,id_cliente,titulo,fecha_entrega,creador,prioridad,departamento, tipo_fallo,version) Values ( :idficha, :idClient,  :tit, :Fehc, :crea, :prio, :dep, :tipo, :vers );


En la propriedad Params del IBQueryGuardar me aparecen los parámetros en la orden correcta.

Mi base de datos tiene las tablas Fichas, Clientes y Empleados.
Fichas tiene claves foráneas tanto de Clientes como de Empleados.

Me recomendaís cambiar la base de datos y poner TODO como varchar ?
O es algun otro tipo de fallo ?
  • 0

#9 coruxito

coruxito

    Advanced Member

  • Miembros
  • PipPipPip
  • 55 mensajes

Escrito 24 abril 2012 - 02:08

Acabo de probar utilizando ParamsByName y sigue el mismo.



delphi
  1. IBQueryGuardar.ParamByName('idficha').Value:=2;
  2.   IBQueryGuardar.ParamByName('idClient').Value:= 1;
  3.   IBQueryGuardar.ParamByName('tit').Value:= 'Segunda Ficha';
  4.   IBQueryGuardar.ParamByName('Fehc').Value:= DateToStr(fecha);
  5.   IBQueryGuardar.ParamByName('crea').Value:= 1;
  6.   IBQueryGuardar.ParamByName('prio').Value:= 'Alta';
  7.   IBQueryGuardar.ParamByName('dep').Value:= 'Prueba';
  8.   IBQueryGuardar.ParamByName('tipo').Value:= 'Error';
  9.   IBQueryGuardar.ParamByName('vers').Value:= 1.7;



Con el fácil que me resultó hacer los Selects me está llevando a desesperación el primer Insert en Delphi !!!  :D
  • 0

#10 coruxito

coruxito

    Advanced Member

  • Miembros
  • PipPipPip
  • 55 mensajes

Escrito 24 abril 2012 - 02:17

Me lo ha hecho !!!

Acabo de mirar que cuando hice los cambios sugeridos por Caral la primera vez que lo ejecuté no me hizo nada, fui em IBExpert y no me aparecía la línea que deberia haber creado, lo probé de nuevo y me apareciá el error de la Primary Key.
Ahora mirando el IBExpert por si habia algo malo con la base, pues miro los datos y AHORA está la línea perfectamente insertada.
Creo que tengo que hacer algo para el commit sea hecho al terminar la instrucción, pq al parecer me lo inserta sin problemas.
  • 0

#11 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.301 mensajes
  • LocationArgentina

Escrito 24 abril 2012 - 06:21

Hola coruxito,
El error de la clave primaria se debe a que ya existe un registro con dicho valor de clave.

Como bien intuyes te hace falta "algo" que confirme la operación. Eso se consigue con el manejo de transacciones. En vista a que utilizas los componentes IBX el componente TIBTransaction es quien encapsula el manejo de las transacciones. Te recomiendo la lectura al paper Transacciones en Interbase y Firebird, que lo puedes encontrar en la zona de descarga/Bases de Datos/Firebird.

Te aclarará muchas dudas. Básicamente la idea es:

1) iniciar transacción
2) Realizar la operación
3) ¿Tuvo éxito?
3.1 SI: Confirmar operación, confirmar transacción
3.2 NO: [Opcional: algo que tranquilice o revierta algunas operaciones], cancelar transacción

Saludos,
  • 0

#12 coruxito

coruxito

    Advanced Member

  • Miembros
  • PipPipPip
  • 55 mensajes

Escrito 24 abril 2012 - 07:37

Gracias Delphius, vou leer el documento que me recomiendas, de cualquier manera ya me lo está haciendo.
Ahora estoy cambiando la base, porque ahora me han informado que todos combos que tengo en el formulário van venir de bases de datos, así que a parte he decidido jugar un poco PageControl para le dar un toque mais ordenado a tanta información.
  • 0

#13 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 24 abril 2012 - 08:18

Ya tienes una ficha con id=2, la segunda vez que lo intentas, te dice que la clave principal está duplicada.

Normalmente se usa un generador para obtener la siguiente Id válida, que es una manera de decirle a firebird "dame tú el siguiente id_ficha y aumenta el contador para la siguiente vez y ocupate de que nunca se le da el mismo id a dos sesiones simultaneas".

Tienes toda la información aquí: http://www.firebirds...ratorguide.html
  • 0

#14 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.301 mensajes
  • LocationArgentina

Escrito 24 abril 2012 - 11:56

Normalmente se usa un generador para obtener la siguiente Id válida, que es una manera de decirle a firebird "dame tú el siguiente id_ficha y aumenta el contador para la siguiente vez y ocupate de que nunca se le da el mismo id a dos sesiones simultaneas".

Tienes toda la información aquí: http://www.firebirds...ratorguide.html

También es muy importante recalcar, sobre todo a los nuevos en Firebird, de que se debe hacer uso de los generadores con mucho cuidado y en forma apropiada debido a que éstos no son sencibles a las transacciones. Recuerden que cancelar una transacción NO regresa al generador el valor anterior.

Ahora si se me permite quisiera hacer una aclaración un tanto fuera de tópico: hoy en día se debería fomentar más el término secuenciador  ;) ...que es el término adoptado en el estándar SQL-2008. Firebird 2.x ya cuenta con el SEQUENCE y es el recomendado. Para aquellos que usan 1.5.x e inferiores, debemos utilizar los GENERATOR.
El concepto de secuencia en el estándar es una propuesta que ha llevado tanto Firebird como de Oracle; según tengo entendido.

Saludos,
  • 0




IP.Board spam blocked by CleanTalk.