2011-12-13 16 views
5

Actualmente estoy trabajando en la modificación de una base de datos Firebird v. 1.5.Actualizando el valor del generador

La estructura de la base de datos se modificará ejecutando consultas desde una aplicación delphi utilizando componentes interbase, el problema que tengo es que necesito ejecutar muchas consultas, algunas de las cuales incluyen crear generadores y actualizar el valor del generador, problema es que necesito para lograrlo en el menor número posible de consultas, pero parece (al menos para mí) que esto no es realmente posible, lo que estoy tratando de hacer es la siguiente:

/* this command creates a generator to be used for table TABLENAME */ 
CREATE GENERATOR GEN_TABLENAME; 

Así Creé un generador, ahora necesito establecer su valor en el ID máximo actual de la tabla TABLENAME, así:

/* one would expect that the following command would work, well it doesn't */ 
SET GENERATOR GEN_TABLENAME TO (SELECT MAX(ID) FROM TABLENAME); 

Ahora, ¿hay alguna solución para esto, o estoy obligado a:

  • crear el generador
  • obtener el ID máx
  • actualización del valor del generador

y repita proceso para cada mesa?

También espera que

SELECT 
    SELECT MAX(ID) AS ID_TABLENAME_1 FROM TABLENAME_1, 
    ... 
    SELECT MAX(ID) AS ID_TABLENAME_N FROM TABLENAME_N 

habría una solución para conseguir el máximo de identificación de cada mesa en un comando, pero no es así.

+0

¿Qué componentes estás usando? – rstrelba

+0

@rstrelba interbase – ComputerSaysNo

+0

Me interesaron los nombres de los componentes delphi. TIBDatabase? TIBQuery? TIBDataSet? – rstrelba

Respuesta

6

Declaración

SET GENERATOR GEN_TABLENAME TO (SELECT MAX(ID) FROM TABLENAME); 

mezclas DDL (SET GENERATOR) y LMD (SELECT), que yo sepa esto no se apoya en general y Firebird no lo soporta con seguridad.

Si se puede actualizar a la última versión de Firebird entonces se podría utilizar EXECUTE BLOCK y/o EXECUTE STATEMENT de hacerlo todo "en una declaración" y del lado del servidor, pero con Firebird 1.5 tiene que conformarse con el camino más largo (una declaración para obtener el máximo actual, luego otro actualizar el generador).

+0

+1 gracias ain, no puedo actualizar, porque el código es bastante grande y el tiempo para probar todas las funciones es limitado, por lo tanto, la actualización está descartada. Esperaba que hubiera una solución más elegante): – ComputerSaysNo

+0

Creo que le di suficiente tiempo a esta pregunta, su respuesta es más cercana a mi pregunta, desafortunadamente tengo que ir con la "manera más larga" de resolver el problema, lo que significa múltiples consultas ..., gracias por su respuesta (: – ComputerSaysNo

4

Se puede crear un procedimiento almacenado y llamarlo desde Delphi:

create procedure update_generators 
as 
    declare variable max_id integer; 
    declare variable table_name char(31); 
    declare variable generator_name char(31); 
begin 
    /* assuming generator naming convention GEN_XXX -> table name XXX */ 
    for select 
    trim(g.rdb$generator_name), 
    substring(trim(g.rdb$generator_name) from 5) 
    from rdb$generators g 
    where (coalesce(g.rdb$system_flag, 0) = 0) 
    into 
    :generator_name, 
    :table_name 
    do 
    begin 
    /* assuming that the field name is always ID */ 
    execute statement 'select max(id) from ' || :table_name into :max_id; 
    execute statement 'set generator ' || :generator_name || ' to ' || :max_id; 
    end 
end^ 

Parece que execute statement es supported by Firebird 1.5 ya. En Firebird 2.0 y versiones posteriores, también puede ajustar el código en execute block y evitar crear un procedimiento almacenado.

+0

+1 gracias TOndrej, tenía razón, GEN_TABLENAME es la convención, pero prefiero una solución más simple – ComputerSaysNo

2

Con el siguiente truco que pueda para establecer el valor del generador al valor máximo de ID de una tabla con una sentencia de SQL de Firebird:

SELECT GEN_ID(GEN_TABLENAME, 
    (SELECT MAX(ID) FROM TABLENAME) - GEN_ID(GEN_TABLENAME, 0)) FROM RDB$DATABASE; 

que funciona, porque GEN_ID(<GeneratorName>, <increment>) obtiene el valor del generador y lo incrementa por <increment>. Esto debería funcionar en Firebird 1.5 así como también en versiones más nuevas.

+0

Si sabe que el generador es 0, esto es aún más simple: 'SELECT GEN_ID (GEN_TABLENAME, (SELECCIONE MAX (ID) DE TABLENAME)) FROM RDB $ DATABASE; ' – yonojoy

Cuestiones relacionadas