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)
-   -   Obtener campo autoinc con Firedac (https://www.clubdelphi.com/foros/showthread.php?t=92367)

lbidi 09-10-2017 16:08:54

Obtener campo autoinc con Firedac
 
Hola, como comente en otros post, estoy migrando una bd a FireBird.

He creado algunas tablas con algun campo autoinc con su correspondiente trigger.

Mi consulta es luego de terminar el insert en una tabla, necesito obtener cual es el numero "autogenerado" para insertar en otra tabla como referencia.

He leido algunos post donde indican que el componente firedac trae alguna propiedad para ello pero no he podido acceder a ella.

Es esta la mejor solucion ?

Saludos y gracias.

ecfisa 09-10-2017 21:07:50

Hola.

No he usado los componentes, pero revisa si el método GetLastAutoGenValue del la clase TADCustomConnection te sirve.

Saludos :)

lbidi 10-10-2017 15:47:16

Gracias ecfisa, pruebo y comento.

Saludos

botones67 10-10-2017 21:59:10

Hola compañeros.
Supondo que tendrás un tigger before insert.
Yo además tengo un procedimiento almacenado que pasa a una variable antes del Post o de ApplyUpdates en nuevo valor generado por el generador al lado del servidor luego con ese
valor sería fácil pasarlo a otra tabla.
// lado del ejecutable antes de post o ApplyUpdates
Código SQL [-]
datos.modulodb.proce.ExecProc;
      datos.modulodb.Cliente_Maestro.FieldByName('id').AsInteger := datos.modulodb.PROCE.ParamByName('CODD3').AsInteger;
// lado del servidor procedimiento almacanedo
Código SQL [-]
CREATE PROCEDURE NUEVO
      RETURNS( CODD3 INTEGER)
      AS
        BEGIN
          CODD3=GEN_ID(MAESTRO_ID_GEN,1);
          SUSPEND;
       END


Un saludo y suerte.

bulc 13-03-2018 10:06:47

Sí, usa la función GetLastAutoGenValue con FDConnection
 
Te indicará el número del Generador en la actualidad, como te han dicho ya.
Código Delphi [-]
Var nGen : Integer;
Begin
  nGen :=  DataModuleX.FDConnection1.GetLastAutoGenValue('Gen_aTable')
Me pregunto si existe una función parecida para el caso de haber definido un campo IDentificador con Firebird 3.0 mediante:
ID Integer Generated by Default as Identity Primary Key;
Saludos,
bulc

bulc 13-03-2018 10:11:25

Cita:

Empezado por botones67 (Mensaje 521665)
Hola compañeros.
Supondo que tendrás un tigger before insert.
Yo además tengo un procedimiento almacenado que pasa a una variable antes del Post o de ApplyUpdates en nuevo valor generado por el generador al lado del servidor luego con ese
valor sería fácil pasarlo a otra tabla.
// lado del ejecutable antes de post o ApplyUpdates
Código SQL [-]
datos.modulodb.proce.ExecProc;
      datos.modulodb.Cliente_Maestro.FieldByName('id').AsInteger := datos.modulodb.PROCE.ParamByName('CODD3').AsInteger;
// lado del servidor procedimiento almacanedo
Código SQL [-]
CREATE PROCEDURE NUEVO
      RETURNS( CODD3 INTEGER)
      AS
        BEGIN
          CODD3=GEN_ID(MAESTRO_ID_GEN,1);
          SUSPEND;
       END


Un saludo y suerte.

No entiendo cómo se ejecuta el SP 'NUEVO' en las dos primeras líneas. ¿Puedes ampliarlo, por favor?

amadis 14-03-2019 20:46:22

¿alguien ha conseguido obtener el ultimo ID desde in INSERT/SELECT??

Cita:

Empezado por bulc (Mensaje 525060)
Te indicará el número del Generador en la actualidad, como te han dicho ya.
Código Delphi [-]
Var nGen : Integer;
Begin
  nGen :=  DataModuleX.FDConnection1.GetLastAutoGenValue('Gen_aTable')
Me pregunto si existe una función parecida para el caso de haber definido un campo IDentificador con Firebird 3.0 mediante:
ID Integer Generated by Default as Identity Primary Key;
Saludos,
bulc


Casimiro Notevi 14-03-2019 21:32:44

¿No te sirven las respuestas que han dado?

bulc 14-03-2019 22:29:35

Sí, gracias
 
Lo daba por terminado. Los siento.

Casimiro Notevi 14-03-2019 22:35:05

Cita:

Empezado por bulc (Mensaje 531078)
Lo daba por terminado. Los siento.

Pero tú no eres quien ha preguntado :D

amadis 15-03-2019 13:03:37

Si en IBEXPERT ejecuto el siguiente codigo

Código SQL [-]
insert into tabla
(campo)
values
('prueba')
returning id

Inserta y me devuelve el ID que es un AUTOINCREMENT IDENTITY COLUMN

Ahora si lo ejecuto desde un FDQUERY

Tengo el siguiente error:

[FireDAC][Phys][FB]Dynamic SQL Error
SQL error code = -104
Token unknown - line 5, column 1
returning


Soy nuevo con firebird y estoy aprendiendo muchas cosas aún.

Con Sybase Advantage Database lo hacía de forma similar, pero en lugar del returning ejecutaba SELECT LASTAUTOINC( STATEMENT ) as id from tabla

Casimiro Notevi 15-03-2019 13:20:23

Aparentemente con los "FD" será algo similar, llamas a:
Código Delphi [-]
FDConnection1.GetLastAutoGenValue('Gen_aTable')

amadis 15-03-2019 13:24:04

Bluc

¿como hiciste para obtener el campo Identity?

Ya que por lo visto esa función GetLastAutoGenValue sólo es para Generators, o bien a mi no me anda.

Si la ejecuto me da error

Código Delphi [-]
[FireDAC][Phys][FB]invalid request BLR at offset 55
generator TABLA is not defined

Cita:

Empezado por bulc (Mensaje 525060)
Te indicará el número del Generador en la actualidad, como te han dicho ya.
Código Delphi [-]
Var nGen : Integer;
Begin
  nGen :=  DataModuleX.FDConnection1.GetLastAutoGenValue('Gen_aTable')
Me pregunto si existe una función parecida para el caso de haber definido un campo IDentificador con Firebird 3.0 mediante:
ID Integer Generated by Default as Identity Primary Key;
Saludos,
bulc


Casimiro Notevi 15-03-2019 13:43:35

Cita:

Empezado por amadis (Mensaje 531090)
Bluc
¿como hiciste para obtener el campo Identity?
Ya que por lo visto esa función GetLastAutoGenValue sólo es para Generators, o bien a mi no me anda.
Si la ejecuto me da error

¿Qué código estás usando? ¿y cuál es el error? :confused:

bulc 15-03-2019 13:46:52

No existe esa función
 
si no se ha usado el sistema de autoincremento mediante Trigger y Generador.
Cabe pensar que usando Firebird 3.0 sería más cómodo usar un Incremento de contador automático. Bueno, claramente es posible. Pero con el sistema de Trigger y Generador se tiene esa ventaja.
Yo me he decantado por usar esa última modalidad.
Desconozco si en caso de usar el novedoso sistema automático de Firebird 3.0, se puede recoger el último número generado mediante esa función GetLastAutoGenValue.
¿Alguien lo sabe?

Casimiro Notevi 15-03-2019 14:02:36

Cita:

Empezado por bulc (Mensaje 531092)
si no se ha usado el sistema de autoincremento mediante Trigger y Generador.
Cabe pensar que usando Firebird 3.0 sería más cómodo usar un Incremento de contador automático. Bueno, claramente es posible. Pero con el sistema de Trigger y Generador se tiene esa ventaja.
Yo me he decantado por usar esa última modalidad.
Desconozco si en caso de usar el novedoso sistema automático de Firebird 3.0, se puede recoger el último número generado mediante esa función GetLastAutoGenValue.
¿Alguien lo sabe?

Eso está disponible desde firebird 2, creo recordar.
Otra cosa distinta es que los componentes que está usando permita hacer uso de ello.
De todas formas, si no pone el código que está usando, ni da más información, es difícil ayudar.

amadis 15-03-2019 14:49:40

Utilizo Firebird 3, y el campo clave ID es un AUTOINCREMENT IDENTITY COLUMN

El código que utilizo, lo puse antes arriba, es el siguiente, lo ejecuto en un FDQuery

Código SQL [-]
insert into tabla
(campo)
values
('prueba')
returning id


Cita:

Empezado por Casimiro Notevi (Mensaje 531093)
Eso está disponible desde firebird 2, creo recordar.
Otra cosa distinta es que los componentes que está usando permita hacer uso de ello.
De todas formas, si no pone el código que está usando, ni da más información, es difícil ayudar.


Casimiro Notevi 15-03-2019 17:18:14

Cita:

Empezado por amadis (Mensaje 531094)
Utilizo Firebird 3, y el campo clave ID es un AUTOINCREMENT IDENTITY COLUMN
El código que utilizo, lo puse antes arriba, es el siguiente, lo ejecuto en un FDQuery
Código SQL [-]insert into tabla (campo) values ('prueba') returning id

Vale, entonces ese es el código que usas, bien.

fduron.mx 17-06-2020 06:25:13

Firebird 3.0 Generalidades de las columnas tipo IDENTITY
 
En firebird 3.0 se introdujo el uso de las columnas tipo IDENTITY, este tipo de campos producen identificadores únicos en la columna declarada utilizando un generador interno; para soportar este tipo de columnas se han agregado un par de campos a la tabla RDB$RELATION_FIELDS:
  • RDB$GENERATOR_NAME (almacena el nombre del generador que se ha creado automáticamente en RDB$GENERATORS)
  • RDB$IDENTITY_TYPE (almacena un 0 para las columnas definidas como IDENTITY y NULL para las demás)
Hasta el momento la única manera de obtener el valor actual de un generador, es a través de la la función GEN_ID(<nombreDelGenerador>, 0) no entraré en detalles en el uso de esta función.

Ahora bien, al momento de declarar una columna de tipo IDENTITY no es necesario crear el disparador, tampoco creamos un generador por nuestra cuenta, todo esto se realiza internamente por el motor de Firebird 3. Sin embargo, el generador existe, y para obtener el valor actual del generador que le fue asignado a nuestro columna, primero debemos averiguar que nombre le ha puesto Firebird a dicho generador, para lo cual, realizamos una consulta a la tabla RDB$RELATION_FIELDS de la siguiente manera:
Código SQL [-]
select rdb$generator_name

from rdb$relation_fields

where rdb$relation_name = 'TABLA_X'
and rdb$field_name = 'ID'
El resultado de esta consulta nos arrojará el nombre del generador que se le ha asignado a la columna ID en la tabla TABLA_X (supongamos que el resultado fue RDB$3), enseguida solo resta ejecutar las instrucciones ya conocidas para el manejo e incremento de generadores:


Para obtener el valor actual del generador
usando instrucciones SQL:

Código SQL [-]
 select GEN_ID(RDB$3, 0) from RDB$DATABASE
Desde Delphi:

Código Delphi [-]
FDQuery1.Connection.GetLastAutoGenValue('RDB$3');


Para obtener el siguiente valor del generador
Código SQL [-]
 select NEXT VALUE FOR RDB$3 from RDB$DATABASE

A partir de Firebird 2.0 se recomienda usar NEXT VALUE FOR en lugar de GEN_ID(<NombreGenerador>, <Incremento>) a menos que se desee incrementar el generador en un valor diferente a 1

Finalmente, una vez que hemos identificado el nombre del generador de nuestra columna IDENTITY podemos obtener el valor del generador mientras se ejecuta la sentencia INSERT, por ejemplo:

Código SQL [-]
insert into tabla
(id, campo)
values
(next value for RDB$3, 'prueba')
 returning id


Desde delphi usando las propiedades del componente FDQuery
Código Delphi [-]
FDQuery1.UpdateOptions.AutoIncFields := 'ID';
FDQuery1.UpdateOptions.FetchGeneratorsPoint := gpImmediate;
FDQuery1.UpdateOptions.GeneratorName := 'RDB$3';

gpImmediate incrementa en 1 el valor del generador RDB$3 justo en el momento en el que se inserta un nuevo registro en la tabla, y le asigna el valor obtenido al campo ID, sin la necesidad de incluir la instrucción NEXT VALUE FOR en la sentencia SQL


La franja horaria es GMT +2. Ahora son las 01:10:25.

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