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)
-   -   Campo autoincrementable en firebird (https://www.clubdelphi.com/foros/showthread.php?t=61196)

Elite237 29-10-2008 17:00:16

Campo autoincrementable en firebird
 
Hola amigos del foro,fijense que tengo una duda al insertar datos a la BD.Tengo un campo que se llama eval_clave, es de tipo numerico y tiene valor autoincrementable.Al momento de insertarlo en la BD, si me incrementa el valor, hasta alli muy bien, pero al momento de borrar todos los registros de ese campo me sigue aumentando el valor desde el ultimo valor que tenia.Por ejemplo, si elimino todos los registros y el ultimo valor que tenia en eval_clave era 3, y despues cuando inserto otro registro en la BD,el valor de eval_clave aumenta a 4 en vez de que me vuelva a generar 0.Alguien sabe como modificarlo para que al momento de insertar un registro empiece desde 0?Saludos

enecumene 29-10-2008 17:12:37

Código SQL [-]
SET GENERATOR NOMBRE_GENERADOR_GEN TO 0;

Creo que es así, :o

Saludos.

Casimiro Notevi 29-10-2008 17:22:27

De todas formas, estos "generadores automáticos" no están pensado para eso, sino para ofrecer siempre un valor DISTINTO en un campo clave, para que no se repita.
Si lo modificas a mano, has perdido su "potencial" y ya lo mismo te da poner cualquier número :confused:

Ana María 29-10-2008 17:34:43

Si de pronto lo que necesitas es un identificador sin saltos (por ejemplo números de factura) lo mas práctico es crear un campo (UNIQUE) que se actualice mediante un trigger desde una tabla que haga de contador, mas o menos así (actualizaremos el campo Numero (UNIQUE) en la tabla Facturas:
Código SQL [-]
create table CONTADORES (
 IDUltimo        Integer NOT NULL);

insert into CONTADORES values(1);

create trigger BIFACTURAS for FACTURAS
    active before insert position 0 as
begin
    update CONTADORES
    set    IDUltimo = IDUltimo + 1;
    select IDUltimo - 1
    from   CONTADORES
    into   new.Numero;
end!

Todo esto se puede hacer manteniendo el campo auntoincremental como clave principal y el generador para obtener el número.

Gracias

Elite237 29-10-2008 18:25:47

Gracias Ana Maria por tu pronta respuesta. Solo que no se en que opcion de firebird hacerlo,uso el sql manager 2008 for interbase and firebird.De hecho es la primera vez que lo uso.Tu me podrias decir donde colocar el codigo que me sugeriste?

enecumene 29-10-2008 18:36:48

Cita:

Empezado por Elite237 (Mensaje 323155)
Gracias Ana Maria por tu pronta respuesta. Solo que no se en que opcion de firebird hacerlo,uso el sql manager 2008 for interbase and firebird.De hecho es la primera vez que lo uso.Tu me podrias decir donde colocar el codigo que me sugeriste?

Hola,

http://img146.imageshack.us/img146/8581/emsoy2.jpg

Saludos.

eduarcol 29-10-2008 18:38:06

yo creo que lo que tu necesitas es averiguar el ultimo valor de la clave y sumarle uno:

Código SQL [-]
Select Max(Clave) + 1 from tabla

enecumene 29-10-2008 18:40:51

Cita:

Empezado por Elite237 (Mensaje 323132)
...Por ejemplo, si elimino todos los registros y el ultimo valor que tenia en eval_clave era 3, y despues cuando inserto otro registro en la BD,el valor de eval_clave aumenta a 4 en vez de que me vuelva a generar 0.Alguien sabe como modificarlo para que al momento de insertar un registro empiece desde 0?

Cita:

Empezado por eduarcol (Mensaje 323158)
yo creo que lo que tu necesitas es averiguar el ultimo valor de la clave y sumarle uno:

Código SQL [-]Select Max(Clave) + 1 from tabla

Ahora estoy más confundido :confused: :confused:, Saludos compadre :D

eduarcol 29-10-2008 18:58:08

Cita:

Empezado por enecumene (Mensaje 323159)
Ahora estoy más confundido :confused: :confused:, Saludos compadre :D

segun logro entender lo que necesita el amigo es saber cual es el ultimo numero utilizado y sumarle uno, si no hay registro lo deja en uno :D

Elite237 29-10-2008 20:56:46

Lo que necesito es que cuando borre todos los registros, empiece de nuevo en 0...y no que empiece en el ultimo valor que le seguia..osea si tenia 5 registros y los borro todos, al momento de volver a insertar en la BD empieza en 6..7...8..9...y eso yo no quiero.

Ana María 29-10-2008 21:20:14

Siendo así, la solución que te da Eduarcol es perfecta.

Ana María 29-10-2008 21:28:30

Trigger
 
Si lo quieres hacer con trigger te quedaría mas o menos así:

Código SQL [-]
create trigger BICLAVES for CLAVES
    active before insert position 0 as
begin
Select Max(Clave) + 1 from Claves
    into   new.Clave;
end!

enecumene 29-10-2008 23:22:05

yo creo que ni eduarcol ni Ana María están entendiendo lo que necesita el amigo aquí, según entiendo (si no es así por favor corrígenme) es si el desea reiniciar la base desde 0 registros borrando todo los datos (vamos a decir a través de una sentencia delete from) es lógico que el generador no empieza desde el 0, si no que quedará el último valor usado, ejemplo, si tengo una tabla de nombres y hay 100 registros, sabemos que el último es no. 100 ¿no?, entonces si el borra los 100 registros el generador todavía sigue en el número 100 y no desde 0 y eso es lo que creo que el amigo aquí es lo que busca hacer, la solución tuya eduardo no empieza desde 0 sino 100 + 1 y el quiere 0 + 1, amigo Elite237 por favor corrígeme si no es así.

Saludos. ;)

PD. Por favor no me maten :)

Ana María 30-10-2008 00:25:03

Tienes razón
 
Tienes razón Enecuneme.

Ante tanta cosa yo haría esto:

No asignar el valor de la clave en cuestión por medio de un generador si no por medio de una una función desde la aplicación, esta función usaría un query (dependiendo de con que te conectas) aquí un ejemplo con TADOQuery:

Código Delphi [-]
function  ID(Tabla: string; Campo: string): Integer;
begin
with Query  do
  try
    Close;
    SQL.Clear ;
    SQL.Add('Select max('+ Campo +')as Nuevo from '+ Tabla);
    Open ;
    if IsEmpty  then
      Result := 1
     else
      Result := FieldByName('Nuevo').AsInteger + 1;
   finally
    Close ;
    end;
end;

// Llamamos la función en BeforePost

procedure TablaBeforePost(DataSet: TDataSet);
begin
Tabla.FielByname('Clave').Value := ID('Tabla','Clave');
end;

boreg 30-10-2008 01:47:56

Saludos, en mi opinión la utilización de generadores es lo mejor para campos "autoincremento" por lo tanto la solución que aporta enecumene es la correcta(repito, en mi opinión), quizas solo para no ajustar "manualmente" el generador a cero con un trigger así se podría hacer:

Código SQL [-]
CREATE OR ALTER TRIGGER PRUEBA_AD0 FOR PRUEBA
ACTIVE AFTER DELETE POSITION 0
AS
declare variable FILAS INTEGER;
begin
  select count(*) from PRUEBA into :FILAS;
  if (filas = 0) then
    execute statement 'SET GENERATOR G_PRUEBA to 0';
end

si después de la eliminacion de registros la tabla esta vacía, el generador se queda con valor cero.
El problema para este metodo sería que se eliminen los registros y posteriormente se haga un rollback ya que aún así el generador estará con valor cero y la siguiente insercion de registros duplicará el campo eval_clave.

Saludos

Elite237 30-10-2008 19:39:15

Cita:

Empezado por enecumene (Mensaje 323203)
yo creo que ni eduarcol ni Ana María están entendiendo lo que necesita el amigo aquí, según entiendo (si no es así por favor corrígenme) es si el desea reiniciar la base desde 0 registros borrando todo los datos (vamos a decir a través de una sentencia delete from) es lógico que el generador no empieza desde el 0, si no que quedará el último valor usado, ejemplo, si tengo una tabla de nombres y hay 100 registros, sabemos que el último es no. 100 ¿no?, entonces si el borra los 100 registros el generador todavía sigue en el número 100 y no desde 0 y eso es lo que creo que el amigo aquí es lo que busca hacer, la solución tuya eduardo no empieza desde 0 sino 100 + 1 y el quiere 0 + 1, amigo Elite237 por favor corrígeme si no es así.

Saludos. ;)

PD. Por favor no me maten :)

Excelente...lo que dice ecueneme es exactamente lo que quiero hacer...yo borro con una sentencia delete..y el generador sigue en el numero 15 y no desde cero..Gracias

enecumene 31-10-2008 00:16:12

Cita:

Empezado por Elite237 (Mensaje 323359)
Excelente...lo que dice ecueneme es exactamente lo que quiero hacer...yo borro con una sentencia delete..y el generador sigue en el numero 15 y no desde cero..Gracias

¿Probaste la sugerencia de boreg?, es un buen código que te soluciona tu problema.

Saludos.

Elite237 31-10-2008 16:26:36

Código SQL [-]
CREATE OR ALTER TRIGGER PRUEBA_AD0 FOR PRUEBA
ACTIVE AFTER DELETE POSITION 0
AS
declare variable FILAS INTEGER;
begin
  select count(*) from PRUEBA into :FILAS;
  if (filas = 0) then
    execute statement 'SET GENERATOR G_PRUEBA to 0';
end
Una pregunta, como es la sintaxis de ese trigger?osea que significa?
Código SQL [-]
CREATE OR ALTER TABLE TRIGGER (aqui es un nombre que le daremos al trigger?) FOR (aqui el nombre de la tabla?)



SET GENERATOR (aqui que es el nombre del campo autoincrementable?) TO 0
Saludos

Lepe 31-10-2008 16:30:55

Si, pleno, lo has acertado todo.

Saludos

boreg 31-10-2008 17:25:03

Cita:

Empezado por Elite237 (Mensaje 323559)
Una pregunta, como es la sintaxis de ese trigger?osea que significa?

Código SQL [-]
CREATE OR ALTER TABLE TRIGGER (aqui es un nombre que le daremos al trigger?) FOR (aqui el nombre de la tabla?)
 
SET GENERATOR (aqui que es el nombre del campo autoincrementable?) TO 0



Saludos

Algo así, solo una aclaración


Código SQL [-]
SET GENERATOR (aquí es el nombre del GENERADOR) to 0
Saludos


La franja horaria es GMT +2. Ahora son las 08:29:10.

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