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)
-   -   ultimo generador que ingrese (https://www.clubdelphi.com/foros/showthread.php?t=71771)

JAI_ME 09-01-2011 20:23:32

ultimo generador que ingrese
 
buenas tardes, tengo dos tablas relacionadas, una de estas tiene un generator y al momento de ingresar un registro en delphi incremento este por medio de gen_id, ok.

Como hago para saber exactamente cual numero generó tomarlo en una variable en delphi para luego ingresarlo en la otra tabla ?

mil gracias por cualquier ayuda que me puedan brindar.

Casimiro Notevi 09-01-2011 20:44:18

Si está en una tabla, entonces te vale un select de la misma, no?

JAI_ME 09-01-2011 21:04:28

Cita:

Empezado por Casimiro Notevi (Mensaje 387047)
Si está en una tabla, entonces te vale un select de la misma, no?


gracias por la anotacion casimiro, el problema es que si en ese mismo instante otro usuario por casualidad inserta tambien un registro con el mismo numero de documento (este puede ser igual) podria provocar un error en los datos.

Casimiro Notevi 09-01-2011 21:45:07

Falta información por tu parte, ¿cómo aumentas el generador?, trigger, store procedure, desde delphi...

JAI_ME 09-01-2011 21:47:54

Cita:

Empezado por Casimiro Notevi (Mensaje 387049)
Falta información por tu parte, ¿cómo aumentas el generador?, trigger, store procedure, desde delphi...

gracias casimiro, todo lo hago desde delphi.

guillotmarc 09-01-2011 22:09:00

Hola.

Para conocer el valor actual de un generador, puedes usar la función gen_id con un incremento de 0.

Ejplo.

select gen_id(gen_clientes, 0) from rdb$database

NOTA: Utilizo rdb$database porqué sé que un select de esa tabla siempre va a devolver un único registro.

Saludos.

JAI_ME 09-01-2011 22:17:39

gracias guillotemarc enseguida lo pruebo.

marcoszorrilla 09-01-2011 22:18:04

Al estar relacionadas entiendo que por cada registro en la Tabla A puede haber x en la Tabla B, en este caso podrías utilizar el evento OnNewRecord de la tabla B.

Código Delphi [-]
....
Tablab_Campoxxx.Value := TablaAID.Value;
.....

Un Saludo.

Casimiro Notevi 09-01-2011 22:49:07

Cita:

Empezado por JAI_ME (Mensaje 387050)
gracias casimiro, todo lo hago desde delphi.

Das la información con cuentagotas ;)

Desde delphi, sí, vale, pero ?cómo?.

El método propuesto por el compañero guillotmarc te devuelve, evidentemente, el último valor generado, pero si estás en un entorno multiusuario entonces puede no valerte si otro usuario ha pedido un nuevo número.

Chris 09-01-2011 23:12:53

Si trabajas con Firebird 2.1 o posterior puedes utlizar la clausula RETURNING.

Código SQL [-]
Insert into mi_tabla (nombre, apellido) values (:new_nombre, :new_apellido) returning id

No es recomendable que tú asignes el valor del campo ID, o de cualquier otro campo que obtiene su valor del próximo estado del generador. Para asignar los valores en este tipo de campos, es mejor dejar el código de asignación en un stored procedure -ejecutado en un AFTER INSERT-. A cómo tú lo has dicho, nunca sabes si un usuario va a ingresar un registro al mismo tiempo que lo haga otro usuario.

Saludos,
Chris

Delphius 10-01-2011 01:49:17

Cita:

Empezado por Chris (Mensaje 387055)
Si trabajas con Firebird 2.1 o posterior puedes utlizar la clausula RETURNING.

Código SQL [-]
Insert into mi_tabla (nombre, apellido) values (:new_nombre, :new_apellido) returning id

Tengo una pregunta. ¿Cómo haces para leer o recuperar el valor devuelto por esa instrucción desde Delphi? Porque en una ocasión en DelphiAccess salió el tema y algunos intentaron darle rosca al asunto y no han podido acceder a ese valor. Según parece no hay todavía soporte en los drivers para Firebird sobre esto.

Saludos,

Chris 10-01-2011 01:58:17

No estoy muy seguro, pero creo que con los componentes que soporten Firebird 2.1 llamas al procedimiento Open, en lugar de llamar al ExecSQL como lo harías normalmente. Desconozco si esta funcionalidad es soportada por los componentes que no han sido desarrollados teniendo en cuanta las mejoras en la versión 2.1 de firebird.

Delphius 10-01-2011 02:13:05

Así parece ser Cris. Debería emplearse componentes o drivers que trabajen con las nuevas características de Firebird... Yo uso D6 y FB 1.5 por lo que no se mucho, pero otras personas que trabajan con Firebird 2.0 y 2.1 y cuentan con versiones modernas de Delphi no pueden leer el RETURNING con los componentes estándares.

Desconozco si Zeos ya soporta esto, creo yo que ni siquiera el nuevo Driver para DBX disponible en Delphi 2010 y XE Enterprise tiene soporte para esto.

Saludos,

Casimiro Notevi 10-01-2011 02:26:05

Cita:

Empezado por Delphius (Mensaje 387061)
[..] creo yo que ni siquiera el nuevo Driver para DBX disponible en Delphi 2010 y XE Enterprise tiene soporte para esto.
Saludos,

Pues con el dineral que cuesta, ya podían haberlo puesto.

guillotmarc 10-01-2011 11:32:08

Sí, es una vergüenza que este driver solo esté en la versión Enterprise, debería estar a partir de la versión Professional.

NOTA: No sé si permite recuperar el valor returning de un insert, puesto que como no he podido pagar la burrada que cuesta un Enterprise, no tengo este driver.

Chris 10-01-2011 17:05:26

No necesitas un driver tan caro. Yo esto del RETURNING lo hago con los componentes IUB. Son muy buenos, rápidos y estables. Lo mejor de todo es que son gratis :)

Delphius 10-01-2011 17:13:12

Cita:

Empezado por Chris (Mensaje 387099)
No necesitas un driver tan caro. Yo esto del RETURNING lo hago con los componentes IUB. Son muy buenos, rápidos y estables. Lo mejor de todo es que son gratis :)

Gracias por el dato.

El punto es que debería haber soporte desde fábrica :mad: y no estar siempre dependiendo de componentes externos.

Saludos,

rastafarey 27-01-2011 00:46:26

Resp
 
desde delhpi has un select. select gen_id(gen_clientes, 1) from rdb$database
ese valo lo insertar en tabla base y si necesitas insertalo en otra tabla ya lo tienes.

ljvenegas 14-10-2011 22:43:35

gracias creo que esa es la respuesta ahorita la pruebo
 
Cita:

Empezado por guillotmarc (Mensaje 387051)
Hola.

Para conocer el valor actual de un generador, puedes usar la función gen_id con un incremento de 0.

Ejplo.

select gen_id(gen_clientes, 0) from rdb$database

NOTA: Utilizo rdb$database porqué sé que un select de esa tabla siempre va a devolver un único registro.

Saludos.



gracias voy a probar

Chris 18-10-2011 23:32:12

Cita:

Empezado por rastafarey (Mensaje 388976)
desde delhpi has un select. select gen_id(gen_clientes, 1) from rdb$database
ese valo lo insertar en tabla base y si necesitas insertalo en otra tabla ya lo tienes.

Existe una posibilidad de introducir un bug al sistema al basarte del valor del generador para determinar el ID del registro recién agregado.

Supón el siguiente escenario:
Haces un inserción en la tabla facturas. El ID asignado a la nueva factura es #1,000. Sin embargo, por sinsustancias de la red u otro componente intermedio, hay un pequeño retraso en llegarle la notificación a tu aplicación de que la inserción fue exitosa. Mientras tu esperabas las respuesta del servidor, otro usuario factura y obtiene el número de factura siguiente. Al momento que tu aplicación ha recibido la respuesta y llama a gen_id, el valo devuelto será #1,002 y terminarás asociando productos a la factura que realmente no debiste hacerlo.

El escenario anterior es mucho más probable de suceder en relación al número de usuarios que requieren la funcionalidad con el bug que te acabo de describir. Si son diez usuarios que esporadicamente facturan será poco probable que suceda, pero lo hará. Todo lo que puede salir mal saldrá mal, eso no hay que olvidarlo.

Saludos,
Chris

EDITO: No me había fijado que habías sugerido utilizar "select gen_id(gen_clientes, 1)" para obtener un identificador único y luego utilizarlo para asignárselo a una nueva factura y sus detalles por ejemplo. De hecho esta es la solución adecuada para el problema. Es lo más seguro en términos de integridad de datos. Aunque te arriesgas a dejar números de facturas no consecutivos si ocurren errores posteriores. Pero eso no es tan grave como asociar productos a una factura a la que no van y dejar a otra sin descendencia.


La franja horaria es GMT +2. Ahora son las 13:04: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