Una tabla con una sola fila
Este es un truco muy sencillo, pero que le será de utilidad para mantener a raya a algunos clientes sabihondos. ¿Ha necesitado alguna vez una tabla con una sola fila? Yo sí, normalmente para almacenar algún contador global. ¿Para qué demonios utilizo una tabla? ¿No me vale un generador (InterBase) o una secuencia (Oracle)? No cuando lo que quiero es un contador sin saltos entre sus valores. Normalmente, si tengo una tabla de facturas en una aplicación, los números secuenciales de facturas los genero mediante esa técnica.
¿Adivina lo que me pasó? Tenía una aplicación de este tipo, en SQL Server. Después de funcionar sin mayor novedad durante cuatro meses, un buen día suena el teléfono en IntSight, y una voz llena de angustia me dice que la aplicación lleva una hora sin funcionar (una tienda en Internet), ¡toda una hora sin poder recibir pedidos!
Voy a ahorrarle los detalles sangrientos. La voz agitada pertenecía a un buen señor al que el gerente de la empresa había nombrado su "Administrador de Bases de Datos", con el mismo criterio con que el Rey Arturo armaba sus caballeros: porque le salía de sus pelotas. El administrador novicio, para más escarnio, estaba pasando por un curso de certificación en SQL Server. Y el muy listo se puso a hacer prácticas... con la base de datos real.
Lo curioso es que montó el estropicio al insertar una nueva fila en la tabla de contadores. Si yo defino una tabla con una sola fila, pienso que no tengo porqué preocuparme de comprobar esa condición cada vez que necesite acceder a ella. Pero, evidentemente, no contaba con las fuerzas de la naturaleza.
Ahora voy a serle sincero: resolví el problema de una forma muy sencilla. Añadí un trigger para impedir borrados en la tabla, y otro para impedir inserciones. Basta con que el cuerpo de ambos contenga una instrucción que genere un error (raiserror, en el caso de SQL Server, exception, en el de InterBase).
...pero si impedimos las inserciones, ¿cómo insertamos la primera fila? En el caso que narro, la fila ya existía. Y en un script de creación se puede crear el trigger después de que insertemos esa primera fila.
Pero se me ha ocurrido una idea igual de sencilla para impedir que se inserten filas adicionales. Y creo que es un poco más elegante:
create table CONTADORES (
NumeroFila integer not null,
Proximo integer not null,
primary key (NumeroFila),
check (NumeroFila = 1)
);
insert into CONTADORES values(1, 1);
La tabla ahora tiene una clave primaria, y no se pueden repetir los valores de la columna NumeroFila. ¡Pero a la misma vez estamos diciendo que el valor de NumeroFila solamente puede ser 1! Como a continuación de la definición de la tabla se inserta una fila con esa clave primaria, hemos agotado entonces las posibilidades existentes. No se puede insertar ni una sola fila más. Naturalmente, eso no evita que sigamos necesitando el trigger de borrado.
|