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)
-   -   autoincrement en firebird con rollback (https://www.clubdelphi.com/foros/showthread.php?t=81171)

anubis 18-10-2012 03:45:56

autoincrement en firebird con rollback
 
buenas,

En el tema de campo autoincrement en firebird, ya he conseguido que funcione gracias a vosotros, el problema surge cuando meto un nuevo registro, y al final lo cancelo con rollback, si meto un nuevo registro y ya lo guardo definitivamente, me encuentro que se ha saltado un número.

ya vi en otro post esto pero no se como usarlo:

Código SQL [-]
select gen_id(MiTabla_Gen, 1) NuevoID from rdb$database;

Por otro lado en el libro de la cara oculta 4, hay un cuadro sobre no usar generadoresk y viene a decir que si necesitamos valores únicos o consecutivos no usemos generadores y la explicación la da cuando, por ejemplo, 2 personas queiren dar de alta un registro y una de ellas hace un rollback y la otra no, quedaría un hueco en la secuencia.

esto que significa, que se puede usar otra forma de aplicar un autoincremento? porque en la cara oculta no lo resuelve.

gracias amigos

MartinS 18-10-2012 04:44:07

Cita:

Empezado por anubis (Mensaje 447366)
...
esto que significa, que se puede usar otra forma de aplicar un autoincremento? porque en la cara oculta no lo resuelve.

Hola: La otra forma de aplicar el autoincremento es a traves de los trigger creados en la base de datos:

Código SQL [-]
CREATE TRIGGER BI_INTERNOS_ID FOR INTERNOS
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
  IF ((NEW.ID IS NULL) Or (New.id = 0)) THEN
      NEW.ID = GEN_ID(INTERNOS_ID_GEN, 1);
END
^

y generadores

Código SQL [-]
CREATE GENERATOR INTERNOS_ID_GEN;

SET GENERATOR INTERNOS_ID_GEN TO 6368;

a eso te referias...?

Saludos.-

Casimiro Notevi 18-10-2012 11:42:45

Cita:

Empezado por anubis (Mensaje 447366)
Por otro lado en el libro de la cara oculta 4, hay un cuadro sobre no usar generadoresk y viene a decir que si necesitamos valores únicos o consecutivos no usemos generadores y la explicación la da cuando, por ejemplo, 2 personas queiren dar de alta un registro y una de ellas hace un rollback y la otra no, quedaría un hueco en la secuencia.
esto que significa, que se puede usar otra forma de aplicar un autoincremento? porque en la cara oculta no lo resuelve.
gracias amigos

Ian Marteens lo explica bien, los generadores no se usan para lo que tú quieres usarlo. Un generador debe darte siempre un número distinto para que no existan repeticiones, por ejemplo, una tabla típica de facturas:
Código SQL [-]
create table tbFacturas (
  id integer not null, // lo crea el generador, el número que sea, lo usamos internamente, no lo ve el usuario
  numero integer not null,  // número único, no repetible, el que ve el usuario
  cliente integer,
  fecha date,
  total numeric(15,2),
  etc
)
El generador se usaría en este caso para el campo id que diferencia a todos los registros de la tabla de facturas, y que si se borra alguna, no importa que se salten números porque no se usa para el tratamiento de los datos que "ve" el usuario, es un código interno para nosotros.
Sin embargo, luego, el campo numero sí que debe ser un número consecutivo, para ello no usamos un generador, en todo caso buscamos el último número y le sumamos 1:
Código SQL [-]
select max(numero)+1 from tbFacturas
En ese caso, si hacemos un rollback no pasa nada, el siguiente usuario que vaya a tomar un numero de factura le saldrá el que realmente toca.
Antes de grabar debes de asegurarte y comprobar que otro usuario no haya hecho otra factura mientras tanto y ya haya usado ese número.

anubis 18-10-2012 16:44:49

Gracias por las respuestas.

correcto, me queda totalmente claro. El id como clave autoincremental y que el usuario no tiene por que ver y que es lo mismo que estaba haciendo en sqlite pero este lo daba en automatico ahora uso generador y trigger que al final, esl lo mismo para bases de datos autoincrementales.

el otro que comentas sobre consecutivos, efectivamente, ese lo controlo yo y solo se aumenta cuando haces commit.

gracias de nuevo

Evidentemente, si es clave autoincremental y va a sobrepasar del los 32000 registros ya toca cambiar el integer ;)

Casimiro Notevi 18-10-2012 17:08:16

Cita:

Empezado por anubis (Mensaje 447398)
Evidentemente, si es clave autoincremental y va a sobrepasar del los 32000 registros ya toca cambiar el integer ;)

El integer de firebird es de 32 bits: *2^31 Signed long (longword)
Por lo tanto sería 20000000000000000000000000000000
Y creo recordar que el generador guarda 64 bits, así que no tienes de qué preocuparte :)

cointec 19-10-2012 00:13:20

Cita:

Empezado por Casimiro Notevi (Mensaje 447399)
El integer de firebird es de 32 bits: *2^31 Signed long (longword)
Por lo tanto sería 20000000000000000000000000000000

Creo que 2^31 no es un 2 con 31 ceros es 2,147,483,648, que es sensiblemente inferior.

Casimiro Notevi 19-10-2012 00:46:21

Por supuesto, me pudo la emoción de poner ceros sin parar :D

Sin embargo, el generador es de 64 bits, por lo tanto, si no me equivoco esta vez sería: 9,223,372,036,854,775,807

En efecto, copio y pego de Firebird Generator Guide
Cita:

Generators store and return 64-bit values in all versions of Firebird. This gives us a value range of:
-2^63 .. 2^63-1 or -9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807

anubis 12-10-2014 07:26:15

Perdonad que retome este post,

El tema del autoincrement esta resuelto, la pregunta es, si aplico un rollback como recupero el incremento que se ha generado para que no se pierda el consecutivo.

gracias y saludos amigos

Casimiro Notevi 12-10-2014 09:42:50

El generador autoincrementable es "independiente" de todo, cada vez que lo llamas aumenta en 1 (predeterminado), está fuera de las transacciones, no vuelve atrás.
Cualquier otro cambio que quieras, tendrás que hacerlo por tus propios medios, modificándolo manualmente.

El generador autoincrementable se usa para obtener SIEMPRE un número nuevo y diferente a los utilizados antes, que nunca pueda repetirse, no controla si tú luego borras alguno o haces cualquier otra cosa. No sirve y no se usa para llevar, por ejemplo, un contador de números de facturas si luego vas a borrar una factura, ese número se pierde. Salvo que tú quieras controlarlo manualmente, pero entonces ya no es la función para lo que se creó el generador.

anubis 13-10-2014 02:07:17

gracias casimiro


La franja horaria es GMT +2. Ahora son las 23:43:20.

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