You are currently browsing the tag archive for the ‘base de datos’ tag.

Este artículo trata de como aprovechar una hoja de cálculo para inicializar tablas en la base de datos.

Dentro de una base de datos guardamos tablas que consideramos “de configuración” ya que no se suelen modificar pero, sí, leerse al menos durante la inicialización del programa. Como estas tablas se modifican pocas veces, es habitual no crear una interfaz gráfica para rellenarlas sino se editan sus datos directamente con una herramienta de administración de la base de datos.

Las tablas de configuración pueden contener datos muy parecidos entre si. Por ejemplo, una tabla de configuración podría definir una red de ordenadores de la siguiente manera:

Ejemplo de una tabla de configuración
Id Nombre Dirección IP
1 Ordenador 1 192.168.0.1
2 Ordenador 2 192.168.0.2
3 Ordenador 3 192.168.0.3
n Ordenador n 192.168.0.n

Como vemos, los datos en cada registro son casi iguales. La parte variable he marcado con una n en la última línea.

Editar una tabla así puede ser pesado cuando se tratan de muchas entradas. Por eso buscamos una manera más sofisticada. Una es crear los comandos INSERT con una hoja de cálculo como Microsoft Excel o Open Office Calc.

Hoja de cálculo para crear comandos INSERT
A B C D
1 Id Nombre Dirección IP Comando SQL
2 1 =”Ordenador ” & A1 =”192.168.0.” & A1 =”insert into mi_tabla values(” & A1 & “, ‘” & B1 & “‘, ‘” & C1 &”‘);”
3 =A1+1 Repite fórmula arriba
4 Repite fórmula arriba

Con “Repite fórmula arriba” me refiero a “copiar hacia abajo” la fórmula de la primera fila.

Con las fórmulas en la hoja de cálculo anterior obtenemos el siguiente resultado.

Hoja de cálculo resultante
A B C D
1 Id Nombre Dirección IP Comando SQL
2 1 Ordenador 1 192.168.0.1 insert into mi_tabla values(1, ‘Ordenador 1’, ‘192.168.0.1’);
3 2 Ordenador 2 192.168.0.2 insert into mi_tabla values(2, ‘Ordenador 2’, ‘192.168.0.2’);
4 3 Ordenador 3 192.168.0.3 insert into mi_tabla values(3, ‘Ordenador 3’, ‘192.168.0.3’);

La última columna podemos copiar y pegar en un fichero de texto y ejecutarlo en el administrador de la base de datos. Así añadimos todas las entradas de golpe sin tener que editar todas las entradas a mano.

insert into mi_tabla values(1, 'Ordenador 1', '192.168.0.1');
insert into mi_tabla values(2, 'Ordenador 2', '192.168.0.2');
insert into mi_tabla values(3, 'Ordenador 3', '192.168.0.3');

Conviene guardar la hoja de cálculo junto con el proyecto para poder fácilmente cambiar la configuración como añadir una nueva fila para un nuevo ordenador o una nueva columna para una característica adicional.

Referencias

Una tarea típica de un programador (o “arquitecto” como se llaman los especialistas en esta tarea) es crear las tablas en una base de datos relacional. En este artículo no quiero hablar de los comandos SQL necesarios para crearlas, sino de las características de las tablas que aparecen a la hora de crear el modelo de datos en la base de datos. En este artículo asumo que el lector ya sabe relacionar objetos del programa con tablas en una base de datos.

En una base de datos nos encontramos típicamente con tablas de las funcionalidades siguientes:

  • Tablas de estado actual. Estas guardan datos parecidos a las variables en un lenguaje de programación.
  • Tablas de entrada y salida. Son tablas que guardan mensajes o trazas y se parecen a ficheros o flujos de datos en un lenguaje de programación.
  • Tablas de historial. En estas tablas guardamos los datos viejos de las tablas de estado o de entrada y salida.
  • Tablas de configuración. Son tablas en que guardamos constantes de enumeración, parámetros de configuración y otros datos, que se suelen cambiar poco o nunca.

Casi todas las tablas en un esquema se dejan clasificar por una de estas categorías y vamos a verlas ahora una en una.

Las tablas de estado actual y las tablas de entrada y salida suelen ser las tablas de “trabajo” ya que contienen la información del procesamiento.

Las tablas del estado actual

Lo que se guarda en una tabla de estado es lo que se guardaría en un objeto variable en un programa. Por eso representan un estado. (Como se puede hacer una correspondencia entre variables y tablas es el tema del artículo “Relación entre objetos y tablas en una base de datos“.)

Igual como las variables en un programa, estas tablas reciben muchas peticiones de lectura y escritura. Por lo tanto importa un acceso rápido. Esto se consigue utilizando una clave primaria numérica y eliminando datos obsoletos que se pueden transferir a tablas de historial.

Las tablas de entrada/salida

Las tablas de entrada y salida son aquellas que de alguna forma guardan mensajes. Se puede utilizar una tabla en la base de datos para enviar mensajes entre varios procesos. Un proceso escribe sus notificaciones y otro los lee y procesa.

A menudo el método que el proceso que lee emplea es un “polling”: comprueba regularmente si ha llegado algún mensaje nuevo con un estado de “no tratado”. Típicamente hay una columna de estado de mensaje en este tipo de tablas. El proceso que escribe pone este estado a “mensaje nuevo” y el que lee les asigna un estado de “tratado”. Por supuesto, se puede evitar este campo de estado si el proceso que lee elimina los mensajes tras tratarlos.

Sin embargo, muchas veces es preferible no borrar datos de una base de datos para facilitar la depuración de errores. Si los mensajes procesados se quedan, todavía se puede averiguar qué información enviaron los procesos entre sí. Si guardo un número de secuencia con cada mensaje, puedo saber en qué orden se han introducido los mensajes. Este número de secuencia puede ser la clave primaria de esta tabla. Se puede omitir el número de secuencia si se guarda la fecha (mejor el timestamp) de creación del mensaje en su lugar. De hecho puede ser recomendable, ya que el timestamp es más informativo e internamente se guarda también como un número. Se puede guardar también la fecha de procesado del mensaje en otra columna para tener la información completa.

Para simplificar el uso de la base de datos, no debería más que un proceso que lee los mensajes de una tabla. Puede haber varios que escriben, pero es recomendable que haya sólo un proceso que escribe y uno que lee. No es costoso crear muchas tablas en un esquema, pero puede ser costoso sacar los mensajes y depurar un fallo cuando sólo hay una tabla de mensajería que actúa como la central nacional de correos.

Es recomendable que los mensaje no estén sobrecargados de información. Si un proceso cambia una tabla de estado basta con notificar con algo como “he hecho algo en la tabla tal” y añadir como mucho la clave primaria en esta tabla. No envíes más datos. El proceso que lee puede hacer su propia consulta a las tablas de estado y obtener toda la información que necesita.

Las trazas de un programa también se pueden guardar en una tabla. En este caso sólo hay un proceso que escribe pero ninguno que lee.

Igual como las tablas de estado, las tablas de entrada y salida suelen tener muchas peticiones de lectura y escritura. Por lo tanto, vale todo lo que ya he mencionado más arriba sobre asuntos de velocidad.

Las tablas de historial

Conviene mantener las tablas de estado y de entrada/salida, es decir, las tablas de “trabajo” con un número de registros reducido, ya que el acceso a sus datos es más rápido cuando menos datos contengan. De otro lado muchas veces se desea guardar los datos antiguos. La solución traen las tablas de historial.

Todos los datos que ya no se necesitan en una tablas de trabajo se pasan a una tabla de historial. Esta tabla suele tener las mismas columnas con los mismos tipos ya que acoge a los mismos datos. Cuando se pasa un registro al historial, se puede borrar en la tabla de trabajo. Hay muchas aplicaciones que todavía permiten visualizar los datos históricos. Por ejemplo, si una tabla de estado contiene las ordenes de compra en curso, la tabla de historial correspondiente contiene las ordenes de compra ya cerradas y permite visualizar estadísticas sobre las ventas en los meses pasados.

No es necesarios pasar los datos de una tabla de trabajo a una tabla de historial justamente después de terminar el trabajo con un registro. Es una tarea que se puede programar una vez al día o una vez al mes en que se pasan todos los registros antiguos de golpe. Por eso las tablas de historial pueden tener pocas pero grandes modificaciones. Por no necesitar un acceso constante, la velocidad no es importante. Algunas bases de datos como Oracle, permiten guardar estas tablas un tablespace diferente.

Las tablas de configuración

Las tablas de configuración contienen parámetros de sólo lectura – aunque una aplicación puede permitir actualizarlos de forma esporádica. Puede ser factible cachear estos datos de configuración en un programa – sobre todo si son muchos y se cambian poco.

Tablas de configuración sustituyen lo que se podría guardar en un fichero “ini”. La ventaja de las tablas es que se guardan todos los datos en un mismo sitio: la base de datos.

A menudo se usan para enlazar identificadores numéricos con un texto descriptivo. Por ejemplo, la tabla de ordenes de trabajo tiene una columna con el estado de la orden. Por ser una tabla de trabajo, la tabla de ordenes sólo guarda un número en el campo de estado, ya que es más rápido que un texto.  En una tabla de configuración se relaciona el número de estado con su significado. Por ejemplo, estado 10 equivale a “en preparación”, estado 20 a “listo para enviar”. Esta construcción permite mantener la velocidad de datos numéricos en las tablas de trabajo pero poder mostrar textos descriptivos al usuario.

Conclusión

Hemos visto diferentes conceptos de uso de tablas de base de datos. Aunque técnicamente la base de datos no distingue estos uso, un programador, sí, puede hacerlo. Puede diferenciarlo por asignar espacio de almacenamiento distinto, por optimizar consultas o por encapsular o cachear la información de forma distinta. Se pueden usar prefijos diferentes como “HIS_” para tablas de históricos para dejar claro de qué tipo de tabla se trata.

A base de las diferentes categorías, se pueden crear clases (abstractas) que se relacionan con uno u otro tipo de tabla. Por ejemplo, una estructura jerárquica como “orden de compra”, “envíos de la orden”, “contenido de los envíos” se parece a una estructura de “paleta”, “caja”, “contenido de caja”: un contenedor que contiene otro contenedor. Cada anidamiento necesita una columna adicional para la clave primaria. Una clase abstracta de “contenedor triple” que usa el nombre de las tablas como parámetro podría cargar la estructura de diferentes datos con el mismo código. Las clases derivadas se ocuparían de extraer los datos particulares de la tabla – dependiendo si es una orden de compra o una paleta de transporte con cajas. Una secuencia SQL modificable podría crear estas estructuras de datos. De esta forma se puede crear código reciclable para varios proyectos.

Y una última nota: Las bases de datos (al menos las de importancia) permiten guardar comentarios descriptivos junto con la definición de las tablas y columnas. Esto es una funcionalidad muy útil ya que permite explicar la utilidad de un campo donde se necesita. Y hay pocos campos que no necesitan una descripción explicativa. Desgraciadamente no se usa esta posibilidad en todos los sitios. Aunque puede ser una alternativa describir los campos en un documento tipo Word, no es tan práctico como guardar el significado directamente en la base de datos. Porque los documentos se pueden perder. Si, en cambio, uno consigue perder la base de datos, las descripciones de los campos van a ser lo de menos.

Referencias

Cuando una aplicación guarda información en una base de datos, entonces aparece la pregunta de como guardar los datos de la memoria RAM en la base de datos. Aquí quiero presentar como poder transformar esta información de objetos a tablas y columnas en una base de datos.

Correspondencia entre tablas y clases

La creación de una tabla consiste en definir los tipos que se guardan en cada columna o campo como se denomina también. Una tabla es, por lo tanto, algo similar a una clase en un lenguaje de programación: un tipo compuesto. Una línea en una tabla se llama registro (record en inglés). Un registro contiene los datos y es, por lo tanto, parecido a una instancia de una clase.

Porque una tabla y sus registros tienen una relación similar a una clase y las instancias de esta clase, se encapsula a menudo una tabla de la base de datos con una clase en el lenguaje de programación. Esta correspondencia surge de forma natural si has diseñado bien tu programa. Cada objeto guarda “sus” datos; sólo que las guarda en la base de datos en lugar de la memoria RAM. Lo lógico es que los datos de todas las instancias de una clase se encuentran en una tabla y todas las instancias de otra clase en otra tabla.

Clave primaria

Un concepto importante en las bases de datos son las claves primarias. Una clave primaria es un identificador único a cada registro. Un objeto de programa que guarda sus datos en una base de datos meramente necesita guardar este identificador para obtener un acceso rápido a sus datos.

Es una buena práctica en la programación de guardar cada dato en sólo un sitio. Por eso, un objeto, que encapsula un registro de una a tabla, no debería guardar los datos en variables miembro sino solamente en la base de datos – excepto la clave primaria, por supuesto. Excepciones se pueden justificar por un aumento de la velocidad o porque el objeto usa los datos para calcular algo.

Hay pocas situaciones en que una tabla no tiene una o varias columnas que representan la clave primaria igual como hay pocos objetos dentro de un proyecto a que no se hace referencia alguna. No sorprende que un nombre popular y recomendable para la columna que contiene la clave primaria es “Id”.

Una clave primaria es normalmente un número entero. A veces este número es también un índice. Por ejemplo, el número de una orden de compra puede ser la clave primaria en una tabla. En tablas con poco tráfico también puede ser recomendable usar cadenas de texto, ya que son más inteligibles. Un ejemplo puede ser una tabla de configuración con atributos y valores.

Estructuras jerárquicas

Como ya hemos dicho, cada tabla en la base de datos corresponde normalmente a una clase. Un problema surgen con las variables miembro de una clase que no tienen un tipo simple, ya que no se pueden definir tipos propios para un campo en una base de datos. No puedo definir que una columna que contenga otra tabla. Esta falta de jerarquía es una restricción importante de las base de datos relacionales. Hay formas de guardar datos que no tienen esta limitación. Por ejemplo, un elemento XML puede contener muchos otros elementos anidados.

Si nos enfrentamos con estructuras de datos complejos, podemos tener tres soluciones posibles:

  1. Un objeto contiene otro objeto por orden y claridad y podemos “aplanar” la estructura de datos.
  2. Dos objetos “colaboran” y guardan referencias entre sí.
  3. Un objeto es contenedor del otro.

A continuación detallaremos como se pueden implementar estas estructuras en una base de datos.

Aplanar la jerarquía

Un objeto contiene otro objeto por orden y claridad y podemos “aplanar” la estructura de datos. Por ejemplo, una clase coche puede contener una clase motor. La clase motor contiene los elementos tipo de combustible y cilindrada. Como cada coche sólo usa un tipo de combustible y tiene una cilindrada, podemos considerar que estas características del motor son también características del coche. Una tabla que corresponde a la clase coche tendría una columna para el tipo de combustible y otra para la cilindrada. El nivel de jerarquía de la clase motor ya no aparece. La hemos aplanado.

Colaboración de objetos

Otro caso tenemos cuando no guardamos los datos dentro de nuestro objeto sino meramente una referencia a otro objeto que contiene estos datos. Por ejemplo, tenemos una clase combustible que guarda las características del combustible. La clase coche, en lugar de guardar estos datos, sólo guarda una referencia, es decir, un puntero a una instancia de combustible. Esta construcción se usa típicamente cuando la relación de datos no es uno a uno. Un coche usa un tipo de combustible, pero un tipo de combustible puede ser usado por varios coches.

Otra característica de esta construcción es que un componente puede cambiarse de forma independiente. Si cambiamos el tipo de motor, entonces la referencia de combustible de este coche apuntaría a otra instancia de la clase combustible. En cambio, si cambiamos la composición del combustible, todos los coches usarían esta nueva versión sin ningún cambio en sus datos. En términos de programación orientado a objetos se diría que la clase coche y combustiblecolaboran“: sus instancias pueden existir de forma independiente pero mantienen enlaces.

La implementación de una estructura de colaboración se hace mediante dos tablas. Cada tabla representa los datos de una clase. La referencia se establece por un campo en que se guarda la clave primaria del registro relacionado en la otra tabla. Por ejemplo, en la tabla COCHES hay una columna combustible_id que guarda el valor del campo id de la tabla COMBUSTIBLES. El campo COMBUSTIBLES.id es la clave primaria de la tabla COMBUSTIBLES. De esta forma, un registro que guarda los datos de un coche tiene un enlace con los datos del combustible que usa.

Mediante el siguiente comando en SQL se pueden obtener los datos de las dos tablas como se fuera una:

select * from COCHES, COMBUSTIBLES
        where COCHES.id = <aquí mi id de coche guardado en la memoria RAM>
          and COMBUSTIBLE.id = COCHES.combustible_id

Contenedor de objetos

Ya hemos visto un tipo de contenedor trivial: el coche contiene un motor. Es trivial porque la relación es uno a uno. Sin embargo, un contenedor generalmente contiene un número variable de elementos. Nuestra clase coche puede contener una lista de factura. Cada vez que el coche sale del taller, se añade una nueva factura a la lista.

La relación entre contenedor es uno a n. A contrario de una colaboración, el contenedor no guarda referencias sino alberga las instancias de los elementos que contiene. Muchas veces no tiene sentido que uno de estos elemento exista fuera del contenedor. Por ejemplo, las facturas están asociados al coche que fue reparado.

La implementación en la base de datos sería también mediante dos tablas: la tabla COCHES para la clase coche y otra tabla FACTURAS para la clase factura. La tabla COCHES no guardaría nada sobre las facturas. Lo que, sí, debe tener es un identificador para cada coche. Esto sería la clave primaria de esta tabla. En la tabla FACTURAS se guardarían las facturas de todos los coches. (Recuerda que una tabla guarda todas las instancias de un objeto.) Una de las columnas de esta tabla guarda la clave primaria del coche. Este datos sería obligatorio ya que una factura no puede existir sin coche.

Nótese una diferencia entre el lenguaje de programación y la base de datos: En el lenguaje de programación es el contenedor que tiene una referencia a sus elementos – en forma de una variable miembro. En la base de datos es al revés: es el elemento que tiene una referencia al contenedor. Esta referencia es la clave primario del contenedor del elemento.

En esta construcción se encuentra a menudo, que la clave primaria de un elemento está constituido por varios campos. Cada coche tiene uno a n facturas. Así los números de facturas está repetido en varios coches – muchos coches tendrán al menos una factura con el número de factura uno. Sin embargo, cada coche sólo tiene cada número de factura una vez. Así la clave primaria de la tabla FACTURAS, que identifica un registro particular, sería la unión de la clave primaria del coche a que se refiere la factura y el número de factura de este coche.

Conclusión

Hemos visto que la correspondencia entre tablas en la base de datos y datos de objetos es relativamente directa. Una tabla es como una clase que sólo permite tipos simples para las variables miembro. Una jerarquía de datos se establece mediante las claves primarias. Las bases de datos relacionales obligan a que esta referencia va del contenido al contenedor y no al revés como en un lenguaje de programación.

Referencias

Se puede acceder a una base de datos Firebird/InterBase desde PHP de forma directa. Sin embargo, considera usar una conexión ODBC, ya que hace el programa más independiente de la base de datos usado. Si quieres conectarte directamente desde PHP, primero debes habilitar la extensión php_interbase.dll. De otra forma, PHP te devuelve un error “Call to undefined function”. Puedes establecer la conexión con

// Una base de datos en un PC con dirección IP
$host = "127.0.0.1:C:\\usr\\my database.fdb";

// El administrador de la base de datos
$username='SYSDBA';

// La contraseña pricipal
$password='masterkey';

// El rol no es requerido si ya soy un sysdba
$role = 'sysdba';

// El comando de conexión
$conn = ibase_connect($host,
                      $username,
                      $password,
                      NULL,
                      0,
                      NULL,
                      $role);

Se cierra una conexión con ibase_close.

Referencias

Las tablas de sistema de Firebird contienen todas las informaciones sobre las tablas de usuario. Como estos datos son a veces un poco críptico, conviene reunir los datos de interés en vistas propias. Muchos comandos SQL útiles para extraer información de las tablas de sistemas se encuentran en el artículo “Extracting META information from Interbase/Firebird SQL […]

Obtener información de tablas

Con esta vista puedes obtener información sobre las columnas de las tablas y sus tipos. Esta información puede ser útil a la hora de comprobar si un dato a guardar en la base de datos está en un formato correcto – por ejemplo que un campo de texto no excede la longitud máxima.

CREATE VIEW V_TABLES (TABLE_NAME, FIELD_NAME, FIELD_DESCRIPTION, FIELD_DEFAULT_VALUE, FIELD_NOT_NULL_CONSTRAINT, FIELD_LENGTH, FIELD_PRECISION, FIELD_SCALE, FIELD_TYPE, FIELD_SUBTYPE, FIELD_COLLATION, FIELD_CHARSET)AS 
SELECT  r.RDB$RELATION_NAME as table_name, 
        r.RDB$FIELD_POSITION as field_position, 
        r.RDB$FIELD_NAME AS field_name, 
        r.RDB$DESCRIPTION AS field_description, 
        r.RDB$DEFAULT_VALUE AS field_default_value, 
        r.RDB$NULL_FLAG AS field_not_null_constraint, 
        f.RDB$FIELD_LENGTH AS field_length, 
        f.RDB$FIELD_PRECISION AS field_precision, 
        f.RDB$FIELD_SCALE AS field_scale, 
        CASE f.RDB$FIELD_TYPE 
          WHEN 261 THEN 'BLOB' 
          WHEN 14 THEN 'CHAR' 
          WHEN 40 THEN 'CSTRING' 
          WHEN 11 THEN 'D_FLOAT' 
          WHEN 27 THEN 'DOUBLE' 
          WHEN 10 THEN 'FLOAT' 
          WHEN 16 THEN 'INT64' 
          WHEN 8 THEN 'INTEGER' 
          WHEN 9 THEN 'QUAD' 
          WHEN 7 THEN 'SMALLINT' 
          WHEN 12 THEN 'DATE' 
          WHEN 13 THEN 'TIME' 
          WHEN 35 THEN 'TIMESTAMP' 
          WHEN 37 THEN 'VARCHAR' 
          ELSE 'UNKNOWN' 
        END AS field_type, 
        f.RDB$FIELD_SUB_TYPE AS field_subtype, 
        coll.RDB$COLLATION_NAME AS field_collation, 
        cset.RDB$CHARACTER_SET_NAME AS field_charset 
   FROM RDB$RELATION_FIELDS r 
   LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME 
   LEFT JOIN RDB$COLLATIONS coll ON r.RDB$COLLATION_ID = coll.RDB$COLLATION_ID 
    AND f.RDB$CHARACTER_SET_ID = coll.RDB$CHARACTER_SET_ID 
   LEFT JOIN RDB$CHARACTER_SETS cset ON f.RDB$CHARACTER_SET_ID = cset.RDB$CHARACTER_SET_ID 
ORDER BY r.RDB$RELATION_NAME, r.RDB$FIELD_POSITION;

Información sobre claves externas

Con la vista siguiente puedes extraer información sobre claves externas (foreign keys).

CREATE VIEW V_FOREIGN_KEYS (TABLE_NAME, FIELD_NAME, REFERENCED_TABLE_NAME, REFERENCED_FIELD_NAME, ON_UPDATE, ON_DELETE)AS       
  SELECT DISTINCT  
--          rc.RDB$CONSTRAINT_NAME AS constraint_name,  
          rc.RDB$RELATION_NAME AS table_name,  
          d1.RDB$FIELD_NAME AS field_name,  
          d2.RDB$DEPENDED_ON_NAME AS referenced_table_name,  
          d2.RDB$FIELD_NAME AS referenced_field_name,  
          refc.RDB$UPDATE_RULE AS on_update,  
          refc.RDB$DELETE_RULE AS on_delete  
     FROM RDB$RELATION_CONSTRAINTS AS rc  
LEFT JOIN RDB$REF_CONSTRAINTS refc ON rc.RDB$CONSTRAINT_NAME = refc.RDB$CONSTRAINT_NAME  
LEFT JOIN RDB$DEPENDENCIES d1 ON d1.RDB$DEPENDED_ON_NAME = rc.RDB$RELATION_NAME  
LEFT JOIN RDB$DEPENDENCIES d2 ON d1.RDB$DEPENDENT_NAME = d2.RDB$DEPENDENT_NAME  
    WHERE rc.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'  
      AND d1.RDB$DEPENDED_ON_NAME <> d2.RDB$DEPENDED_ON_NAME  
      AND d1.RDB$FIELD_NAME <> d2.RDB$FIELD_NAME  
;
GRANT DELETE, INSERT, REFERENCES, SELECT, UPDATE
 ON V_FOREIGN_KEYS TO SYSDBA WITH GRANT OPTION;
UPDATE RDB$RELATION_FIELDS set
  RDB$DESCRIPTION = 'Table that uses the foreign key'
  where RDB$FIELD_NAME = 'TABLE_NAME' AND RDB$RELATION_NAME = 'V_FOREIGN_KEYS';
UPDATE RDB$RELATION_FIELDS set
  RDB$DESCRIPTION = 'Field whose values are restricted to the referenced field'
  where RDB$FIELD_NAME = 'FIELD_NAME' AND RDB$RELATION_NAME = 'V_FOREIGN_KEYS';
UPDATE RDB$RELATION_FIELDS set
  RDB$DESCRIPTION = 'The table which is referenced by the foreign key'
  where RDB$FIELD_NAME = 'REFERENCED_TABLE_NAME' AND RDB$RELATION_NAME = 'V_FOREIGN_KEYS';
UPDATE RDB$RELATION_FIELDS set
  RDB$DESCRIPTION = 'The field whose values are the permitted ones for the target field'
  where RDB$FIELD_NAME = 'REFERENCED_FIELD_NAME' AND RDB$RELATION_NAME = 'V_FOREIGN_KEYS';
UPDATE RDB$RELATION_FIELDS set
  RDB$DESCRIPTION = 'What to do when the referenced field value is updated'
  where RDB$FIELD_NAME = 'ON_UPDATE' AND RDB$RELATION_NAME = 'V_FOREIGN_KEYS';
UPDATE RDB$RELATION_FIELDS set
  RDB$DESCRIPTION = 'What to do when the referenced field value is deleted'
  where RDB$FIELD_NAME = 'ON_DELETE' AND RDB$RELATION_NAME = 'V_FOREIGN_KEYS';

Copiar comentarios de columnas de una tabla a una vista

Si creo una vista, entonces me gustaría tener los mismos comentarios en la vista que en las columnas correspondientes de las tablas a partir de las cuales creo la vista. Por supuesto, esto es un problema trivial para aquellos que nunca ponen comentarios en ningún sitio, pero para los demás, el siguiente comando podría ser de utilidad.

UPDATE RDB$RELATION_FIELDS set RDB$DESCRIPTION = 
       (select RDB$DESCRIPTION from RDB$RELATION_FIELDS 
         where RDB$RELATION_NAME = 'SOURCE_TABLE'
           and RDB$FIELD_NAME = 'SOURCE_COLUMN')
  where RDB$FIELD_NAME = 'TARGET_FIELD' 
    AND RDB$RELATION_NAME = 'TARGET_NAME';

El select interior lee de la tabla de la cual queremos obtener los comentarios. Podemos sustituir el paréntesis por un string si queremos asignar un comentario a medida. SOURCE_TABLE y SOURCE_COLUMN se refieren a la tabla de donde quiero copiar los comentarios y TARGET_NAME y TARGET_FIELD a la vista a donde los quiero copiar. Los nombres de las tablas, vistas y columnas deben estar en mayúsculas. De otra forma la comparación = no funcionará.

Por supuesto, antes de usar este comando SQL hay que crear la tabla y la vista a que se refieren. La herramienta de extracción de DDL (Data Definition Language) no guarda referencias a comentarios de otras tablas. Sólo presenta el comentario actualmente asignado. Por eso, conviene guardarse un fichero SQL con los comandos de copia de comentarios junto con la creación de la vista, ya que se puede ejecutar cada vez se cambia la vista.

Referencias

Firebird

Firebird, que no tiene que ver con los programas populares Firefox y Thunderbird, ha surgido de la base de datos InterBase cuyo código fue liberado por la empresa Borland ya hace tiempo. Hoy en día, Firebird es una base de datos con buenas prestaciones y que se puede usar gratis. Recomiendo echar un vistazo a la página principal de Firebird, a quienes están buscando una alternativa a otras bases de datos libres de coste como MySQL o PostgreSQL.

Como Firebird no es una de las base de datos más populares, conviene comprobar que existen los controladores necesarios para acceder a ellos. “Borland” e “InterBase” pueden ser dos palabras claves a la hora de buscar una solución.

FlameRobin

Firebird no viene con una herramenta gráfica de administración. De este rol se ocupa otro proyecto que se llama
FlameRobin. Habitualmente se instala FlameRobin junto con la base de datos Firebird.

Para registrar una base de datos existente, sigue los siguientes pasos:

  1. En el menú “Server”, selecciona “Register server”
  2. Edita la dirección y el puerto del servidor y ponle un nombre. El nombre sólo sirve como identificador en FlameRobin. Con este paso hemos registrado un ordenador, pero todavía no la base de datos.
  3. Pincha con el botón secundario en el servidor que acabamos de crear y selecciona “Register existing database”.
  4. Rellena el nombre y la base de datos (o alias) como si lo pusieras en el ordenador en que se encuentra la base de datos. Conviene rellenar también el usuario y la contraseña.

Firebird utiliza el puerto 3050 por defecto. Asegura que este está seleccionado (o el que hayas elegido).

Por cierto, al contrario de otras base de datos, hay que hacer un commit con los cambios en la data definition language (DDL = lenguaje de definición de datos).

Referencias

Escribe tu dirección de correo electrónico para suscribirte a este blog, y recibir notificaciones de nuevos mensajes por correo.

Únete a otros 52 seguidores

Archivos

noviembre 2018
L M X J V S D
« Ago    
 1234
567891011
12131415161718
19202122232425
2627282930