varlena
varlena
PostgreSQL Training,
Consulting & Support
General Bits
By A. Elein Mustain


12-Oct-2003 Edición: 47

Archives | General Tidbits | Google General Bits | Docs | Castellano | Português | Subscriptions | Notifications

General Bits General Bits es una publicación periódica escrita con información desde la lista de PostgreSQL, pgsql-general.
Para saber más sobre pgsql-general y PostgreSQL, visite www.PostgreSQL.org.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Mostrando Valores en Punto Flotante
[GENERAL] Displaying a float8 as a full-length number 08-Oct-2003

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)

Contribuyeron: Grant Rutherford grutherford at iders.ca, Julie May julie at ccorb.com, Bruno Wolff III bruno at wolff.to

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Implementación de Restricciones (Constraints)
[GENERAL] Unique Index vs. Unique Constraint 10-Oct-2003

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: (p)rimary key, (u)nique, (f)function, (c)heck.

Cláusula de ConstraintNombre de ConstraintUsosNombre de Índice/TriggerFunción de Trigger
PRIMARY KEY table_pkey (p) índice table_pkey  
UNIQUE table_column_key (u)índice table_column_key  
FOREIGN KEY $n (f)trigger RI_ConstraintTrigger_nRI_FKey_check_ins
tabla referida $n (f)trigger RI_ConstraintTrigger_nRI_FKey_noaction_del
tabla referida $n (f)trigger RI_ConstraintTrigger_nRI_FKey_noaction_upd
CHECK table_column (c)check ninguno  

References y Foreign Keys
Para los propósitos de estas descripciones, REFERENCES y FOREIGN KEYS (llaves foráneas) son intercambiables, puesto que tienen la misma implementación. Las referencias y llaves foráneas usan el mismo conjunto de funciones internas para hacer las verificaciones, cuyos nombres comienzan con RI_FKey_.

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:

RI_FKey_cascade_del RI_FKey_check_ins RI_FKey_noaction_del
RI_FKey_cascade_upd RI_FKey_check_upd RI_FKey_noaction_upd
RI_FKey_restrict_del RI_FKey_setdefault_del RI_FKey_setnull_del
RI_FKey_restrict_upd RI_FKey_setdefault_upd RI_FKey_setnull_upd

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
La restricción CHECK se almacena como una restricción específica del atributo: no es una función ni un índice. La expresión compilada de CHECK, junto con su código fuente, se almacenan en la tabla pg_constraint.

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
Los nombres por omisión de FOREIGN KEY, UNIQUE y CHECK pueden ser reemplazados. Para darle un nombre a una restricción, preceda su definición con CONSTRAINT nombre como se ilustra en el siguiente ejemplo.

	create table showconstraints (
	   id	integer PRIMARY KEY,
	   unq integer CONSTRAINT sc_unq UNIQUE,
	   checkme integer CONSTRAINT posval CHECK ( checkme > 0 )
	);

Consultas Informativas
A continuación presentamos algunas consultas para mostrar las restricciones en sus tablas. Para usar estas consultas, sustituya el nombre de la tabla en cuestión en cada una de las cláusulas WHERE, o use una función que reemplace el nombre de la tabla.

	-- ¿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';

Contribuyeron: Thomas LeBlanc thomasatiem at hotmail.com, Manfred Koizar mkoi-pg at aon.at, scott.marlowe scott.marlowe at ihs.com, elein at varlena.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Entrada de Fechas Cambió en 7.4
[HACKERS] Date input changed in 7.4 ? 26-Aug-2003

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)

Contribuyeron: Mendola Gaetano mendola@bigfoot.com, Bruce Momjian pgman@candle.pha.pa.us, Tom Lane tgl@sss.pgh.pa.us, Andrew Dunstan andrew@dunslane.net, Kevin Brown kevin@sysexperts.com, Christopher Kings-Lynne chriskl@familyhealth.com.au, Dennis Björklund db@zigo.dhs.org, Scott Lamb slamb@slamb.org

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Trucos Tcl
[GENERAL] pl/tcl trigger question 26-Aug-2003

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.

Contribuyeron: Jules Alberts jules.alberts at arbodienst-limburg.nl, Robert Treat xzilla at users.sourceforge.net, darren at crystalballinc.com, Jan Wieck JanWieck at Yahoo.com


Comments and Corrections are welcome. Suggestions and contributions of items are also welcome. Send them in!.
Copyright A. Elein Mustain 2003, 2004,2005

Google
Search General Bits & varlena.com Search WWW