Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros temas > Trucos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Los mejores trucos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-06-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Más trucos con generadores

Ahora que ya sabe como crear y destruir un generador nos queda conocer cómo podemos obtener el valor actual del generador. ¡Elemental, Watson!, pensará usted. Hasta el alcalde de mi pueblo sabe que existe la función gen_id, que recibe un nombre de generador y un incremento, lo aplica al generador y devuelve el valor del mismo. Casi siempre el generador se utiliza en triggers o procedimientos como los siguientes:

Código Delphi [-]
create trigger AsignarCodigoFormaPago for FormasPago
   active before insert position 0 as
begin
   if (new.Codigo is null) then
      new.Codigo = gen_id(FormaPagoGen);
end!

create procedure DameUnNumero returns(Codigo integer) as
begin
   Codigo = gen_id(OtroGenerador, 1);
end!

Ante tanta sabiduría me siento obligado a preguntarle algo: ¿qué valor devuelve gen_id, el que tenía el generador antes del incremento, o el valor posterior? Pues es el valor posterior al incremento el que se retorno. Claro, no esperaba otra cosa de usted...

¿Y cómo puedo obtener el valor actual del generador, pero sin modificarlo? La primera vez que me lo preguntaron, contesté algo que aún me avergüenza recordar:

Código Delphi [-]
// ¡¡¡MUY MALO!!!
create procedure ValorActual returns(Codigo integer) as
begin
   Codigo = gen_id(OtroGenerador, 1);
   Codigo = gen_id(OtroGenerador, -1);
end!

¿Funcionar? Creo que sí, pero funciona a lo bestia. Con más experiencia sobre mis espaldas, ahora me doy cuenta de que el siguiente procedimiento es más racional:

Código Delphi [-]
create procedure ValorActual returns(Codigo integer) as
begin
   Codigo = gen_id(OtroGenerador, 0);
end!

De todos modos sigue existiendo un problema. Supongamos que estamos desarrollando una herramienta de diseño, al estilo de SQL Explorer, o de Marathon. En tal caso, no tendremos a mano un procedimiento como el anterior para cada uno de los generadores de la base de datos. Pero el problema no es grave: gen_id es una función como cualquier otra (aunque causa un efecto secundario), y puede colocarse en una cláusula select. Inmediatamente me viene a la mente la tabla Dual de Oracle: una tabla predefinida que siempre contiene una sóla fila. Si tuviésemos esta tabla en InterBase, nos bastaría ejecutar la siguiente instrucción para conocer el valor actual de un generador:

Código SQL [-]
// ¡¡¡NO FUNCIONA, LA TABLA Dual ES DE ORACLE, NO DE INTERBASE!!!
select gen_id(OtroGenerador, 0) from Dual

Bien, no existirá Dual en InterBase, pero sí tenemos la tabla interna del sistema RDB$DATABASE, que hasta donde conozco, siempre tiene una sola fila. Entonces podemos utilizar esta variante:

Código SQL [-]
// VARIANTE CORRECTA
select gen_id(OtroGenerador, 0) from RDB$DATABASE

En realidad, SQL Explorer utiliza este otro truco:

Código SQL [-]
// VARIANTE DE SQL EXPLORER
select distinct gen_id(OtroGenerador, 0) from RDB$GENERATORS

Por supuesto, el resultado del select anterior ¡siempre tiene una sola fila!.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 21:33:32.


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
Copyright 1996-2007 Club Delphi