|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Una columna de un tipo en punto flotante (float) a veces puede desplegarse en formato exponencial en lugar del formato numérico usual. Para aplicaciones de negocios esto suele ser inapropiado. Por ejemplo, db=# SELECT CAST('0.00001' AS float8); float8 -------- 1e-05 (1 row)Usando la función to_char() se trunca el valor, por lo que en muchos casos esta tampoco es una solución aceptable. db=# SELECT to_char(CAST('0.000000000000001' AS float8), CAST('0.9999999999999999999999999' AS text)); to_char ------------------- 0.00000000000000 (1 row) La mejor manera de presentar un float es convertirlo a numeric. Esto conservará el valor y será más fácil de leer. =# SELECT CAST('0.9999999999999999999999999' AS numeric); numeric ----------------------------- 0.9999999999999999999999999 (1 row)
Constraints son restricciones en alguna columna en la definición de una tabla. Hay varios tipos de restricciones disponibles tanto para las tablas como para las columnas, y se implementan de varias maneras. Algunas restricciones son implementadas como triggers, algunas como índices, y otras son atributos de la definición de una columna. Hay algunas indicaciones cuando se crea una tabla acerca de los triggers e índices que se crean para llaves primarias y foráneas. Son estos mensajes NOTICE: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 't1_pkey' for table 't1' NOTICE: CREATE TABLE / UNIQUE will create implicit index 't1_unq_key' for table 't1' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)Pero cuando el momento en que se entregaron estos mensajes pasó hace mucho, es bueno poder saber exactamente cómo se implementan las restricciones definidas. Aquí hay una lista de las posibles restricciones y cómo se implementan. Las letras entre paréntesis indican el tipo de restricción:
References y Foreign Keys Una tabla que define una llave foránea también instala implícitamente triggers en update y delete en la tabla a la que se hace referencia. En el caso de arriba, el trigger implementa el comportamiento NO ACTION por omisión en las tablas a las que se hace referencia. Si la llave foránea se definiera con directivas diferentes, se instalaría una de las otras funciones. Estas son las funciones que se usan para las restricciones de integridad referencial:
Las restricciones de llaves foráneas tienen nombre del estilo $1, $2, etc. Los triggers tienen nombres que se construyen usando números basados en los OIDs.
Checks y otras restricciones Los valores DEFAULT y las condiciones NOT NULL son, conceptualmente, restricciones, pero no son implementadas como otras restricciones, sino que son atributos de las columnas y se almacenan en las tablas pg_attributes y pg_attrdef.
Restricciones con Nombre create table showconstraints ( id integer PRIMARY KEY, unq integer CONSTRAINT sc_unq UNIQUE, checkme integer CONSTRAINT posval CHECK ( checkme > 0 ) );
Consultas Informativas -- ¿Qué índices tiene la tabla? select * from pg_indexes where tablename = 'tabla'; -- ¿Qué triggers hay en la tabla? select c.relname as "Table", t.tgname as "Nombre de Trigger", t.tgconstrname as "Nombre de Restricción", t.tgenabled as "Activado", t.tgisconstraint as "Es Restricción", cc.relname as "Tabla Referida", p.proname as "Nombre de Función" from pg_trigger t, pg_class c, pg_class cc, pg_proc p where t.tgfoid = p.oid and t.tgrelid = c.oid and t.tgconstrrelid = cc.oid and c.relname = 'tabla'; -- ¿Qué restricciones hay en la tabla? select r.relname as "Tabla", c.conname as "Nombre de Restricción", contype as "Tipo de Restricción", conkey as "Columnas de Llave", confkey as "Columnas Referidas", consrc as "Fuente" from pg_class r, pg_constraint c where r.oid = c.conrelid and relname = 'tabla';
Este es un buen momento para mencionar que el formato de entrada de las fechas cambia entre las versiones 7.3 y 7.4. En 7.4, el formato de entrada de las fechas se controlará con el parámetro de configuracion datestyle, que puede ser definido en postgresql.conf o usando una sentencia SET en un guión SQL. En 7.3 y anteriores, el servidor intentaba adivinar el formato de la fecha en la entrada basado en los valores. Esto llevaba a posibles datos erróneos cuando el formato era ambiguo. Por ejemplo, en la primera consulta del ejemplo de abajo, la fecha es interpretada como mes/día/año. En la segunda se interpreta como día/mes/año, debido a los valores. Es posible que alguna de las dos estuviera errónea, pero no lo sabría porque no genera errores. =# select date('01/10/03'),to_char( date('01/10/03'), 'dd-mon-yyyy'); date | to_char ------------+------------- 2003-01-10 | 10-jan-2003 (1 row) =# select date('20/10/03'),to_char( date('20/10/03'), 'dd-mon-yyyy'); date | to_char ------------+------------- 2003-10-20 | 20-oct-2003 (1 row)A pesar de que el algoritmo de fechas ha sido de esta manera en PostgreSQL durante mucho tiempo, al final la gente se convenció que las entradas de fechas no deben ser adivinadas, sino interpretadas usando datestyle y en los casos donde la fecha no es válida, se debe enviar un mensaje de ERROR.
Postgres 7.3.3: test=# select '18/03/71'::date; date ------------ 1971-03-18 (1 row) Postgres 7.4head regression=# select '18/03/71'::date; ERROR: invalid input syntax for date: "18/03/71" regression=# show DateStyle ; DateStyle ----------- ISO, MDY (1 row) regression=# set datestyle = dmy; SET regression=# select '18/03/71'::date; date ------------ 1971-03-18 (1 row)
Las funciones en pltcl pueden ser muy versátiles. La siguiente función es una función de trigger que muestra varias características particulares de pltcl. Es una función de trigger genérica que puede forzar una o más columnas de una tabla a minúsculas. Puede ser usada en un trigger en una amplia variedad de tablas. create or replace function force_lower () returns trigger as ' foreach key $args { if {[info exists NEW($key)]} { set NEW($key) [string tolower $NEW($key)] } } return [array get NEW] ' language pltcl; create trigger force_lower before insert or update on mytable for each row execute procedure force_lower('field_1', 'field_n'); Las características claves que esta función demuestra son que correctamente ignora valores NULL, que toma argumentos incluso siendo una función de trigger, y que el número de argumentos es variable. Usando esta función y la definición de trigger como modelo, puede implementar casi cualquier clase de filtrado, formateo o cálculo en los valores de entrada para sus tablas.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comments and Corrections are welcome. Suggestions and contributions of items are also welcome. Send them in!. Copyright A. Elein Mustain 2003, 2004,2005 |