Return Message

ORAPOST ORAPOST@santandersupernet.com
29 Sep 98 04:08:01 +0200


--=_ORCL_1049273_0_0
Content-Transfer-Encoding:quoted-printable
Content-Type:text/plain; charset="iso-8859-1"

The included message could not be delivered to the following invalid mail
names.  Please verify these names and try them again.

Bad name:  oscarap

--=_ORCL_1049273_0_0
Content-Type:message/rfc822

Date: 29 Sep 98 03:24:08
From:La Mancha de la Calabaza que Ladra <mancha@galois.baras.ml.org>
To:pgsql-ayuda@tlali.iztacala.unam.mx
Subject:Re: Mensaje inicial
Reply-to:BSN.PERSEUS:pgsql-ayuda@tlali.iztacala.unam.mx 
Return-Path:<pgsql-ayuda-owner@tlali.iztacala.unam.mx>
Received:from tlali.iztacala.unam.mx by santandersupernet.com (SMI-8.6/SMI-SVR4) id EAA10110; Tue, 29 Sep 1998 04:05:57 +0200
Received:(from majordom@localhost) by tlali.iztacala.unam.mx (8.8.7/8.8.7) id UAA04434 for pgsql-ayuda-outgoing; Mon, 28 Sep 1998 20:26:01 -0500
X-Authentication-Warning:tlali.iztacala.unam.mx: majordom set sender to owner-pgsql-ayuda using -f
Received:from ce.ife.org.mx (uucp@ce.ife.org.mx [200.34.164.166]) by tlali.iztacala.unam.mx (8.8.7/8.8.7) with ESMTP id UAA04430 for <pgsql-ayuda@tlali.iztacala.unam.mx>; Mon, 28 Sep 1998 20:25:58 -0500
Received:(from uucp@localhost) by ce.ife.org.mx (8.8.5/8.8.5) with UUCP id UAA00415 for pgsql-ayuda@tlali.iztacala.unam.mx; Mon, 28 Sep 1998 20:25:15 -0500
Received:(from mancha@localhost) by galois.dgst.ddf.gob.mx (8.8.7/8.8.5) id UAA00459; Mon, 28 Sep 1998 20:24:08 -0500
Message-Id:<199809290124.UAA00459@galois.dgst.ddf.gob.mx>
In-reply-to:<3.0.1.32.19980924094607.010f0860@correo.ival.es> (enrique@ival.es)
References:<3.0.1.32.19980924094607.010f0860@correo.ival.es>
Sender:owner-pgsql-ayuda@tlali.iztacala.unam.mx
Precedence: bulk
MIME-Version: 1.0
Content-Transfer-Encoding:quoted-printable
Content-Type:text/plain; charset="iso-8859-1"


Hola, acabo de ver el mensaje de respuesta a la pregunta de Gilberto
Becerril y bueno, yo tambi=E9n ando empezando en esto del PostgreSQL y
las notas que he hecho las tex=ED para poder usarlas el d=EDa que pierda
la memoria por completo.

Las anexo y espero que sean de utilidad a la comunidad y si alguien
tiene sugerencias o le hace a=F1adiduras, agradecer=E9 que manden copia de
regreso. Saludos.

(Para imprimirlo hace falta una instalaci=F3n completa de TeX, como la
que viene con RedHat:

latex archivo.tex; latex archivo.tex; dvips archivo.dvi

)

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D

\documentclass{article}

\usepackage[spanish]{babel}
\usepackage{isolatin1}
\usepackage[dvips,spanish,all,light]{draftcopy}
\usepackage{algorithmic}
\usepackage{algorithm}

\setlength{\textheight}{9in}
\setlength{\textwidth}{6.5in}
\setlength{\topmargin}{-0.5in}
\setlength{\oddsidemargin}{0in}
\setlength{\evensidemargin}{0in}
\renewcommand{\listalgorithmname}{Lista de algoritmos}
\floatname{algorithm}{Algoritmo}

\def\fecha{\number\day\space de\space \ifcase\month\or
 enero\or febrero\or marzo\or abril\or mayo\or junio\or
 julio\or agosto\or septiembre\or octubre\or noviembre\or diciembre\fi
 \space de \space\number\year}

\font\chirris=3Dcmtt10 at 6pt

\title{Peque=F1o manual de algunas de las tripas de PostgreSQL\\ o de
c=F3mo fui aprendiendo a lidiar con la bestia.}

\author{Por La Mancha de la Calabaza que Ladra\thanks{\tt
mancha@breogan.iimas.unam.mx}}

\date{\fecha}

\makeindex

\begin{document}

\maketitle

\tableofcontents
\listofalgorithms

\section{Introducci=F3n}

=BFA qui=E9n va dirigido? Digamos que est=E1 dirigido para el an=F3nimo fula=
no
X que estudi=F3 matem=E1ticas, comenz=F3 a jugar con computadoras y acaba de
descubrir que hay un fulano Y con harta lana que est=E1 dispuesto a
desperdiciarla en la colecci=F3n de CDs del fulano X, h=E9roe de la
historia, a cambio de que =E9ste le masaje=E9 unas bases de datos.

Esto es algo as=ED como un diario de las cosas que he ido aprendiendo de
las tripas de PostgreSQL. Estar=E1 escrito en desorden hasta que me
siente con calma a darle un poco m=E1s de estructura.

El meollo del asunto es saber usar el \verb+select+. Ese es tu mejor
amigo en las bases de datos relacionales con \verb+SQL+\footnote{Que,
por cierto, es un est=E1ndar para platicar con los bichos conocidos como
Bases de Datos. Si leiste esta nota al pie esperando una gran
explicaci=F3n, es que vas mal... Si tan s=F3lo la leiste porque siempre
lees las notas al pie, pues no andas tan perdido.}. De momento,
digamos que basta con tener un poco de sentido com=FAn para aprender de
que se trata el asunto, pero si crees que necesitas saber un poco m=E1s
de lo que describir=E9 por aqu=ED, la mejor referencia es \cite{Bowman} y
nunca, pero realmente \underline{nunca} \cite{Trimble}, que es con el
que aprend=ED.

\section{Si no est=E1s en la compa=F1=EDa de un adulto...}

	En la siguiente secci=F3n veremos como usar el cliente de la
base de datos, pero para esto es necesario tener unas bases de
datos. Aquellos que ya tienen acceso a una base de datos se pueden
pasar a la siguiente secci=F3n. Si no tienes, hay dos opciones: a) ir
con un ni=F1o mayor y que te cree una; b) aprender a hacerlo.

	En primer lugar, para poder crear una base de datos o incluso
para hacer consultas en una existente, es necesario haber sido creado
como usuario del manejador. Esto lo hace el fulano que es conocido en
el medio como el DBA\footnote{En realidad son muchos fulanos y con
suerte hay uno cerca de t=ED.}: {\em Database Administrator}, el
administrador de las bases de datos. Es como el superusuario de UNIX,
pero no puede leer tu correo ni matar tus conexiones a sitios porno,
s=F3lo crear usuarios y realizar las operaciones de administraci=F3n de
las bases y el manejador\footnote{Hummmm... quiz=E1 de ah=ED venga el
nombre.}.

	Como de seguro eres de aquella clase de personas que no se
quedan impasibles ante una figura de autoridad, ah=ED va el secreto: el
DBA correr=E1 en el {\em shell\/} el programa \verb+createuser+ para
darte de alta. =A1J=E1! Ya no es un mago, no puede enga=F1arte, pero a=FAn a=
s=ED
no lo hagas enojar.

	\verb+createuser+ es un programa que si no se le pasan
argumentos se pone en modo interactivo preguntando el nombre de la
cuenta del usuario ---que puede no ser la misma que en el sistema---,
el user ID ---que tiene que ser necesariamente la misma que en el
sistema---, si puede crear bases de datos y si puede a=F1adir
usuarios. Pese  a que el nombre del usuario es independiente del de el
sistema, si uno trata de asignar otro nombre al mismo usuario, no lo
permite\footnote{Este es un momento hist=F3rico, acabo de descubrir que
esto pasa.}.

	En el siguiente ejemplo, tratamos de crear con otro nombre a
un usuario que ya existe. Luego del fracaso, creamos un usuario nuevo
con un nombre diferente al de su cuenta, y sin permiso para crear
bases de datos, as=ED que seguir=E1 dependiendo del DBA para que le cree
una. Por supuesto que tiene sentido que un usuario exista para el
manejador de la base de datos sin que pueda crear una bases de datos,
ya que con esto podr=E1 consultar e incluso modificar o desgraciar una
existente si el DBA se descuida.

\begin{verbatim}

postgres@caserola:psql$ createuser %$
Enter name of user to add ---> lola
Enter user's postgres ID -> 500

createuser: 500 already belongs to mancha , pick another
Enter user's postgres ID -> 518
Is user ``lola''allowed to create databases (y/n) n
Is user ``lola''allowed to add users? (y/n) n
createuser: lola was successfully added
don't forget to create a database for lola

\end{verbatim}

	Independientemente de si el DBA te d=E1 permisos o no para crear
bases de datos\index{bases de datos|crear}, siempre es bueno saber
como se hace\footnote{Sobre todo por si un d=EDa el muy est=FApido deja a
la mano una sesi=F3n abierta.}. \verb+createdb+, as=ED se
hace. \verb+createdb nombre+ crea la base con nombre \verb+nombre+. No
hay m=E1s que decir.


\section{De los tipos de datos}

\subsection{Los que tiene}

En la tabla~\ref{tab:tipos}, robada vilmente del manual, con algunas
a=F1adiduras se incluyen los tipos de datos que tiene construidos
internamente Postgres95 hasta la versi=F3n 6.2.3.

\begin{table}[t]
\begin{center}
\begin{tabular}{|l|l|p{8cm}|}
\hline\hline{\bf Postgres}&{\bf SQL92}&{\bf Descripci=F3n}\\\hline\hline
bool & boolean & Booleano, verdadero o falso. A la entrada puede
recibir los valores: (TRUE,'t','true','y','yes','1') que produce 't' o
(FALSE,'f','false','n','no','0') que produce 'f'\\\hline
box & N/A & Caja rectangular en un plano de dos dimensiones\\\hline
char($n$) & character($n$) & Cadena de $n$ car=E1cteres de tama=F1o fijo\\\h=
line
circle & N/A & C=EDrculo en un plano de dos dimensiones\\\hline
date & date & Fecha sin hora\\\hline
float4 & float($p$) & N=FAmero de punto flotante con precisi=F3n $p$\\\hline
float8 & real, double precision & N=FAmero de punto flotante con doble
precisi=F3n\\\hline
int2 & smallint & Entero de dos bytes con signo\\\hline
int4 & int, integer & Entero de cuatro bytes con signo\\\hline
int4 & decimal($p$, $s$) & Entero preciso para $p \le 9$, $s =3D 0$\\\hline
int4 & numeric($p$, $s$) & Entero preciso para $p =3D 9$, $s =3D 0$\\\hline
line & N/A & L=EDnea infinita en un plano de dos dimensiones\\\hline
lseg & N/A & Segmento de l=EDnea en un plano de dos dimensiones\\\hline
money & decimal($9$, $2$) & Lana, marmaja, dinero en formato
\$1,234.56\\\hline
path & N/A & Recorrido abierto o cerrado en un plano de dos
dimensiones\\\hline
point & N/A & Punto en un plano de dos dimensiones\\\hline
polygon & N/A & Recorrido cerrado en un plano de dos dimensiones (un
pol=EDgono tal cual)\\\hline
time & time & Hora en formato $hh:mm:ss$ \\\hline
timespan & interval & Intervalo de tiempo de prop=F3sito general\\\hline
varchar($n$) & character varying($n$) & Cadena de car=E1cteres con
tama=F1o m=E1ximo de $n$ car=E1cteres\\\hline
\hline\hline
\end{tabular}
\caption{Descripci=F3n de tipos de datos de Postgres.}
\label{tab:tipos}
\end{center}
\end{table}

\section{Algunos trucos}

\subsection{Quiero copiar s=F3lo unos campos de una tabla a otra...}

Supongamos que tenemos una tabla y queremos crear una segunda que
tenga s=F3lo algunos de los campos que est=E1n en la primera, y adem=E1s que
no me repita registros:

\begin{verbatim}

INSERT INTO nomfec SELECT DISTINCT nombre,apepat,apemat,fecnac FROM
licencias;

\end{verbatim}

\subsection{Quiero borrar un determinado registro}

Una opci=F3n es dar un calificador que defina de manera =FAnica al
registro, pero cuando no se puede, est=E1 es la soluci=F3n:

\begin{verbatim}

SELECT nombre,oid FROM nomfec;
DELETE FROM nomfec WHERE OID=3D1223744;

\end{verbatim}

\noindent d=F3nde \verb+OID+ es el {\em Object ID\/} de cada registro, y
seleccionamos el de aqu=E9l que queremos borrar (o hacerle cualquier
otra cosa).

\subsection{Quiero tener un campo que sea un n=FAmero secuencial autom=E1tic=
o}

Bien, la transa es esta: tenemos una tabla donde queremos que uno de
los campos tenga un n=FAmero secuencial =FAnico y que adem=E1s se actualiza
autom=E1ticamente. F=E1cil, creamos una secuencia\footnote{S=ED, postgres
tiene una forma autom=E1tica de hacerlo.}: 

\begin{verbatim}

foo=3D> CREATE SEQUENCE misec INCREMENT 1 START 0 MINVAL 0 MAXVAL 999999;

\end{verbatim}

\noindent crea la secuencia {\tt misec} que comienza en cero, se
incrementa de uno en uno y tiene como valor m=E1ximo $999,999$. En
realidad, salvo por los valores m=EDnimo y m=E1ximo, el resto es el
default. Ahora, c=F3mo se usa. Lo que queremos es que cada vez que
inserto un registro, el valor de un campo sea un n=FAmero secuencial que
se incrementa con respecto al =FAltimo valor insertado, que pudo haber
sido usado hace meses. Esto se consigue as=ED de f=E1cil:

\begin{verbatim}

INSERT INTO mitabla VALUES ('un valorcillo textual', nextval('misec'))

\end{verbatim}

Si lo que queremos es saber el valor actual de la secuencia:
\verb+SELECT currval('misec')+

El empleo de estas bestias es una buena idea para el caso en que uno
quiera automatizar el uso de tablas auxiliares. Por ejemplo, digamos
que tenemos una tabla con $N$ registros y los valores que puede tomar
uno de los campos est=E1 en un dominio con un orden mucho menor a
$N$. De lo que estamos hablando es de normalizar la tabla. Bien, el
asunto es que para cada registro, vamos a tomar el campo en particular
que vamos a guardar en la tabla anexa y en su lugar almacenaremos un
identificador =FAnico para el valor que tiene esa instancia, el
algoritmo r=E1pido y mal hecho se describe en~\ref{alg1}, mientras que
el algoritmo detallado para hacer la creaci=F3n del identificador y la
inserci=F3n en la tabla anexa, se d=E1 en el algoritmo~\ref{alg2}.

\begin{algorithm}
\caption{Para la substituci=F3n de valores por un identificador
obtenido de una tabla anexa.}
\label{alg1}
\begin{algorithmic}[1]
\WHILE{queden registros}
\STATE trae el siguiente registro
\IF{el valor existe en la tabla auxiliar}
\STATE asigna al campo el identificador asociado al valor
\ELSE
\STATE asocia al valor un identificador nuevo y =FAnico
\STATE inserta en la tabla auxiliar el valor
\ENDIF
\ENDWHILE
\end{algorithmic}
\end{algorithm}

\begin{algorithm}
\caption{Para la creaci=F3n del identificador en la tabla anexa.}
\label{alg2}
\begin{algorithmic}[1]
\STATE SELECT idval FROM latabla WHERE campo =3D valor;
\IF{$ntuples > 0$}
\STATE return idval;
\ELSE 
\STATE INSERT INTO $val$ VALUES ($valor$, NEXTVAL('secuencia'));
\STATE return CURRVAL('secuencia');
\ENDIF
\end{algorithmic}
\end{algorithm}


\section{La papa: c=F3mo saber de las tripas en cuanto a bases, tablas,
campos y dem=E1s yerbas}

Para saber que bases de datos hay en el sistema:

\begin{verbatim}

SELECT * FROM pg_database;

\end{verbatim}

Para saber que tablas tengo en la base de datos actual:

\begin{verbatim}

SELECT * FROM pg_class;

\end{verbatim}

Lo mismo, pero solo las mias, excluyendo las del sistema:

\begin{verbatim}

SELECT * FROM pg_class WHERE relname !~~ 'pg%';

\end{verbatim}

Si s=F3lo quiero saber cuantos registros tiene una tabla, basta con
preguntar: 

\begin{verbatim}

SELECT relname,reltuples FROM pg_class WHERE relname=3D'mechitos';

\end{verbatim}

\noindent donde {\tt mechitos} es el nombre de la tabla de la cual me
interesa saber el n=FAmero de registros.

A continuaci=F3n, la sopa de como extraer info de las tablas de la base
de datos. El asunto es el siguiente: \verb+pg_database+ tiene las
bases de datos, \verb+pg_class+ tiene las tablas, y
\verb+pg_attribute+ tiene los campos. Agarra uno y si lo que quiere
saber es el n=FAmero de registros en una tabla determinada, pues basta
con preguntar lo siguiente, conociendo la tabla, con el plus de que
adem=E1s se obtiene cuales son los campos. Para, adem=E1s, saber los tipos
de los campos, habr=EDa que hacer un {\em query\/} a \verb+pg_type+ con
los \verb+oids+ de los campos, pero eso creo que ya es mucho rollo.

\begin{verbatim}

SELECT relname,reltuples,attname,attnum
    FROM pg_class,pg_attribute
    WHERE pg_class.relname=3D'centel'
        AND pg_attribute.attrelid=3Dpg_class.oid
        AND attnum > 0
    ORDER BY attnum;

\end{verbatim}

Si lo quiero saber todo de todas las tablas de la base que no sean del
sistema, sino mias, por supuesto ordenadas por \verb+oid+, se hace lo
siguiente, pero con el problema de que incluye los indices:

\begin{verbatim}

SELECT pg_class.oid,relname,reltuples,attname
    FROM pg_class,pg_attribute
    WHERE pg_class.relname !~~ '%pg%'
        AND pg_attribute.attrelid=3Dpg_class.oid
        AND attnum > 0
    ORDER BY pg_class.oid;

\end{verbatim}

	En el caso de que uno quiera saber cuales son los campos de
todas las tablas que se tienen en una base de datos, esta lindura de
{\em query\/} lo soluciona\footnote{Y adem=E1s dice cu=E1ntos registros
tiene cada tabla. Claro que lo repite para cada campo, pero bueno, SQL
no fue hecho para formatear datos.}.

\begin{verbatim}

SELECT
pg_class.relname,pg_attribute.attname,pg_class.reltuples,pg_type.typname
        FROM pg_attribute
        WHERE attrelid =3D pg_class.oid 
            AND attnum > 0
            AND atttypid=3Dpg_type.oid
            AND pg_class.oid IN
                (SELECT oid FROM pg_class WHERE relname !~~ 'pg%')
            AND pg_type.oid IN (SELECT oid FROM pg_type);

\end{verbatim}

Fin... de momento

\section{La base no est=E1 en esta m=E1quina, sino en la otra}

	=BFY c=F3mo se conecta uno a una base que no es local? Bueno, el
asunto es f=E1cil. Si el operetas del otro sistema configur=F3 bien el
asunto, y da acceso validando al usuario, entonces basta con usar la
bandera \verb+-h+:

\begin{verbatim}

	psql -h maquina

\end{verbatim}

\noindent donde, por supuesto, \verb+maquina+ es la otra m=E1quina.

\section{Algunas tablillas pachangueras y cochinas}

Las tablas que se ponen a continuaci=F3n, son para referencia y aparecen
mencionadas en varias partes del texto.

%\chirris

\vspace{2pc}

\begin{table}[ht]
\begin{center}
\begin{tabular}{|l|l|}
\hline\hline
{\bf Nombre del cat=E1logo}& {\bf Descripci=F3n}\\\hline\hline
pg$\_$database  & Bases de datos\\\hline
pg$\_$class     & Clases o tablas\\\hline
pg$\_$attribute & Atributos o campos de la clase o tabla\\\hline
pg$\_$index     & =CDndices secundarios\\\hline
pg$\_$proc      & Procedimientos (en C y en SQL)\\\hline
pg$\_$type      & Tipos de datos (del sistema y definidos por el 
usuario)\\\hline
pg$\_$operator  & Operadores (del sistema y definidos por el usuario)\\\hlin=
e
pg$\_$aggregate & Agregados y funciones agregadas\\\hline
pg$\_$am        & M=E9todos de acceso\\\hline
pg$\_$amop      & Operadores de m=E9todos de acceso\\\hline
pg$\_$amproc    & Funciones de soporte para m=E9todos de acceso\\\hline
pg$\_$opclass   & Clases de operadores de m=E9todos de acceso\\\hline
\\\hline\hline
\end{tabular}
\caption{Catalogo del sistema PostgreSQL. Cada base de datos tiene
estas mismas tablas, salvo por la primera que es =FAnica, que almacenan
cada una de las partes que componen la base de
datos.}\label{tab:catalogo}
\end{center}
\end{table}

\vspace{2pc}

\begin{table}[ht]
\begin{center}
\begin{tabular}{|l|l|r|p{18pc}|}
\hline\hline
\multicolumn{4}{|c|}{\bf Table =3D pg$\_$database}\\\hline\hline
\bf Field&\bf Type&\bf Length&\bf Description\\\hline
datname&name&32&Nombre de la tabla\\
datdba&int4&4&Uid del dababase admin\\
datpath&text&var&El path para llegar hasta la tabla\\\hline\hline
\end{tabular}
\caption{Tabla que contiene todas las bases de datos que existen en el
sistema. Vale la pena consultarla en aplicaciones que impliquen
explorar diversos aspectos.}\label{tab:database}
\end{center}
\end{table}

\begin{table}[ht]
\begin{center}
\begin{tabular}{|l|l|r|p{18pc}|}
\hline\hline
\multicolumn{4}{|c|}{\bf Table =3D pg$\_$class}\\\hline\hline
\bf Field&\bf Type&\bf Length&\bf Description\\\hline
relname&name&32&Nombre de la tabla\\
reltype&oid&4&Eso, el Object Id de la tabla\\
relowner&oid&4&El UID (postgres) del due=F1o de la tabla\\
relam&oid&4&\\
relpages&int4&4&\\
reltuples&int4&4&\\
relhasindex&bool&1&\\
relisshared&bool&1&\\
relkind&char&1&\\
relnatts&int2&2&\\
relchecks&int2&2&\\
reltriggers&int2&2&\\
relhasrules&bool&1&\\
relacl&aclitem[]&var&\\\hline\hline
\end{tabular}
\caption{Tabla que contiene todas las bases de datos que existen en el
sistema. Vale la pena consultarla en aplicaciones que impliquen
explorar diversos aspectos.}\label{tab:class}
\end{center}
\end{table}


\begin{table}
\begin{center}
\begin{tabular}{|l|l|r|p{18pc}|}
\hline\hline
\multicolumn{4}{|c|}{\bf Table =3D pg$\_$attribute}\\\hline\hline
\bf Field&\bf Type&\bf Length&\bf Description\\\hline
attrelid&oid&4&OID del campo\\
attname&name&32&Nombre del campo\\
atttypid&oid&4&\\
attdisbursion&float4&4&\\
attlen&int2&2&\\
attnum&int2&2&\\
attnelems&int4&4&\\
attcacheoff&int4&4&\\
atttypmod&int2&2&\\
attbyval&bool&1&\\
attisset&bool&1&\\
attalign&char&1&\\
attnotnull&bool&1&\\
atthasdef&bool&1&\\\hline\hline
\end{tabular}
\caption{Tabla que contiene todos los campos de todas las bases de
datos que existen en el sistema. Vale la pena consultarla en
aplicaciones que impliquen explorar diversos
aspectos.}\label{tab:attribute}
\end{center}
\end{table}

\begin{thebibliography}{Bowman}

\bibitem[Bowman]{Bowman} {\bf The Practical SQL Handbook}, Judity
Bowman, Sandra Emerson, and Marcy Damovsky, ISBN: 0-201-44787-8,
Addisson-Wesley, 1997.

\bibitem[Trimble]{Trimble} {\bf A Visual Introduction to SQL},
J. Harvey Trimble Jr., and David Chappell, ISBN: 0-471-61684-2, John
Wiley \& Sons, Inc.

\end{thebibliography}

\end{document}

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D

PD. Gil, m=E1ndame un mensaje porque perd=ED tu direcci=F3n. Saludos.

--
La Mancha, http://breogan.iimas.unam.mx/~mancha
casa://AvRevolucion.1761.depto.5/~mancha
ring://550-2547.df.telmex.com.mx/~pedir.por.mancha
chamba://cubo-320.iimas.unam.cu/~mancha
rechamba://533-3035.df.telmex.com.mx/~pedir.por.el.director
--------- Pie de mensaje -------------------------------------------
Archivo historico: http://tlali.iztacala.unam.mx/maillist/pgsql-ayuda
Cancelar inscripcion:
mail to: majordomo@tlali.iztacala.unam.mx
text   : cancelacion pgsql-ayuda

--=_ORCL_1049273_0_0--

--------- Pie de mensaje -------------------------------------------
Archivo historico: http://tlali.iztacala.unam.mx/maillist/pgsql-ayuda
Cancelar inscripcion:
mail to: majordomo@tlali.iztacala.unam.mx
text   : cancelacion pgsql-ayuda