Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Conocer el campo autoincremento después de hacer la inserción (https://www.clubdelphi.com/foros/showthread.php?t=94354)

servicomp 21-12-2019 02:36:01

Conocer el campo autoincremento después de hacer la inserción
 
cordial saludo compañeros

Tengo una aplicación, realizada en embarcadero X2, usando la base de datos Firebird 3.0. Su primer campo es un campo ID de autoincremento, donde voy a llevar los consecutivos de los registros, y necesito saber como conocer este valor después de la inserción. La tabla esta compuesta por más campos.

Usando el código SQL en el IBExpert funciona perfecto
Código SQL [-]
Insert into TABLA (valor1, valor2) values ('xxx', 'ccc') returning ID
Pero al momento de llevarlo al aplicativo usando el TSQLQuery, no hay forma de que nos de el valor ya que no reconoce la instrucción
Código Delphi [-]
ValorID:=SQLQuery.FieldByName('ID').AsInteger;

De que otra forma se podría conocer el valor del ID después de hacer la inserción.

Agradeciendo de antemano su colaboración

orodriguezca 21-12-2019 16:39:24

Eso debería funcionar correctamente. ¿El error es durante la compilación o en ejecución?. ¿Cual es exactamente el error?

servicomp 21-12-2019 17:20:34

Después de solicitar, sale el error con el siguiente mensaje
Código:

Project autoincremento.exe raised  exception class eDataBaseError
 'SQLQuery: Field 'ID' not found'

Al parecer el componente TSQLQuery no devuelve la información.

Que otra solución se podría tener para afrontar este tropiezo.

Casimiro Notevi 21-12-2019 19:10:33

¿Y el campo se llama ID?

dec 21-12-2019 19:30:50

Hola a todos,

Me meto donde no debería acaso... pero... ¿qué tal algo así?

Código SQL [-]
Insert into TABLA (valor1, valor2) values ('xxx', 'ccc') returning ID into :ID

... o en todo caso, comprobar que la inserción se lleva a cabo, pues, parece que, sino es así, no se retornará nada o se retornará "null".

https://firebirdsql.org/refdocs/lang...21-insert.html

servicomp 21-12-2019 21:59:33

De antemano muchas gracias por su colaboración

En primera medida ID es el nombre del campo que se autoincrementa cada vez que hacemos la inserción con su respectivo disparador. En segunda media usando Into :ID, da error ya que desconoce el Into en esta instrucción. Si colocamos la instrucción en el IBExpert funciona perfecto, pero con el Into nos da un error.

servicomp 21-12-2019 23:12:18

Compañeros se pudo hace funcionar la instrucción cono el siguiente código, aunque no es aplicable ya que no se puede capturar la variable.

Código Delphi [-]
SQLPrueba.SQL.Clear;
SQLPrueba.SQL.Add('INSERT INTO TABLA (VALOR1, VALOR2) VALUES (:V1, :V2) RETURNING ID');
SQLPrueba.ParamByName('V1').AsString:='PRUEBA';
SQLPrueba.ParamByName('V2').AsString:='MAS DE PRUEBA';
SQLPrueba.ExecSQL(False);

Al tratar de recoger el valor de Id con el siguiente codigo da el error

Código Delphi [-]
j:=SQLPrueba.FieldByName('ID').AsInteger;

Se presenta el error

Cita:

Field 'ID' not found

Caminante 21-12-2019 23:15:31

Hola


Y si pruebas usando parambyname en vez de fieldbyname. Nunca he usado returning asi que no se si sera correcto hacerlo asi. Pero no pierdes nada probando.


Saludos

servicomp 21-12-2019 23:23:36

El mensaje es el mismo del anterior. Error

Usando el anterior código, efectivamente se inserta los campos, pero seguimos sin poder capturar el valor que retorna de la variable ID

De nuevo muchas gracias por sus respuestas

servicomp 22-12-2019 00:34:57

El problema al parecer se presenta es en el Delphi, bueno en el Embarcadero, ya que desde la consola de Firebird, inserta los campos y devuelve el valor del campo incrementado.

Al parecer desconozco la técnica para capturar el ID de una campo auto incremento al momento de insertar algunos campos.

orodriguezca 22-12-2019 03:58:41

Cita:

Empezado por servicomp (Mensaje 534941)

Código Delphi [-]
SQLPrueba.SQL.Clear;
SQLPrueba.SQL.Add('INSERT INTO TABLA (VALOR1, VALOR2) VALUES (:V1, :V2) RETURNING ID');
SQLPrueba.ParamByName('V1').AsString:='PRUEBA';
SQLPrueba.ParamByName('V2').AsString:='MAS DE PRUEBA';
SQLPrueba.ExecSQL(False);


Creo que el problema está en
Código Delphi [-]
SQLPrueba.ExecSQL(False);
En su lugar utiliza
Código Delphi [-]
SQLPrueba.Open;

Casimiro Notevi 22-12-2019 20:13:20

Creo que debes usar Fields:
Código Delphi [-]
iValor := Query.Fields[0].AsInteger;

Kiranov 23-12-2019 20:31:14

Buenos dias,

si estas usando los componentes de FireDAC, revisa la funcion GetLastAutoGenValue del componente TFDConnection, yo lo utilizo de la siguiente manera para recuperar el ultimo registro insertado:

Código Delphi [-]
fdquery1.SQL.Text:='insert into laboralperiods(useropening,iniamount,cajaopening) values(: paramuser,: paraminiamount,: paramcajaopenin)';
fdquery1.ParamByName('paramuser').AsString:=rzlabel8.Caption;
fdquery1.ParamByName('paraminiamount').AsFloat:=AdvMoneyEdit1.Value;
fdquery1.ParamByName('paramcajaopenin').AsString:=rzlabel3.Caption;
fdquery1.ExecSQL;
fdquery1.SQL.Text:='Select * from laboralperiods where control=: paramcontrol';
fdquery1.ParamByName('paramcontrol').AsInteger:= fdconnection1.GetLastAutoGenValue('Control');
fdquery1.Open();

"control" es el campo autoincrementado en la tabla de la base datos mysql.

Espero te sirva de algo,
Saludos.

servicomp 03-01-2020 00:02:25

Cordial saludo compañeros y un feliz 2020 para todos

Acerca del RETURN en Firebird, este solo funciona en la consola o en el IBExpert, según el catalogo.

Al parecer para que funcione, lo tenemos que hacer desde un procedimiento en la base de datos que envíe el valor de return a una variable de nuestro programa y así poder grabar los registros de la tabla detalle. Claro esta que hasta el momento no he necesitado un procedimiento de estos, no lo he realizado, así que me tocará ensayar y luego les comento.

Otro compañero me dice que también se puede realizar de forma automática usando un SQLDataset, un DataSetprovide y un ClientDataSet para el maestro, y un SQLDataset y un ClientDataset con el Detalle, y que se enlazan con un DataSource. Funciona muy bien de forma automática.

Esperamos hacer las prácticas suficientes y su comportamiento para saber como trabajan mejor

orodriguezca 03-01-2020 00:10:48

Yo insisto en que el problema es que estas ejecutando la consulta con ExecSQL y deberías hacerlo con Open. Revisa la entrada #11 de este hilo.

Casimiro Notevi 03-01-2020 10:50:41

Insisto :) que un simple insert retorna el campo indicado.
Ejemplo, tenemos una tabla 'tbEjemplo' con los campos id y texto, hacemos:
Código SQL [-]
insert into tbEjemplo values (2,'hola') returning id
Retorna '2'
Código SQL [-]
insert into tbEjemplo values (5,'saludos') returning texto
Retorna 'saludos'

Y un 'insert' es 'execute', no es 'open', ya que este último es solamente para 'select'.

servicomp 03-01-2020 21:36:11

La instrucción que nos das, funciona perfectamente en la consola de Firebird o el el IBExpert, pero si lo queremos hacer en muestro programa y llevarlo a una variable, este no se puede realizar.

Me comentan compañeros que cambie a OPEN, pero cuando el procedimiento se compila, tampoco funciona. solo funciona con EXECSQL.

Exploraré la forma automática que me hicieron llegar y también la forma de un procedimiento en la Firebird que me pase la variable al programa. Esta última opción nunca la he usado, así que me tocará estudiarla primero, de como es pasar una variable que devuelve un procedimiento de la base de datos firebird a una variable entera en DElphi.

De antemano muchas gracias por toda su colaboración, y es grato saber que el delphi sigue muy vivo como lenguaje de programación.

Casimiro Notevi 04-01-2020 00:14:09

Tengo una tabla tbDebug con los campos id, texto. El primero se autoincrementa mediante un generador y su correspondiente trigger. El segundo es un campo de texto.

En un proyecto he añadido un IBsql de los componentes IBX y el código:
Código SQL [-]
'insert into tbDebug (texto) values (:text) returning id';

He añadido un botón para ejecutarlo y, como puedes ver en el video enlazado, retorna el ID creado, como era de esperar.
Si no funciona con los componentes que estás usando, será problema de esos componentes.
Enlace a video captura.

El código es tan simple como:
Código Delphi [-]
  ibsql2.Close;
  ibsql2.SQL.Text := 'insert into tbdebug (texto) values (:text) returning id';
  ibsql2.Params[0].AsString := ed2.Text;
  ibsql2.ExecQuery;
  ed1.Text := ibsql2.Fields[0].AsString;


La franja horaria es GMT +2. Ahora son las 10:04:43.

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