MIT OpenCourseWare


6.171 Ingeniería de software para aplicaciones web. Otoño 2003

Página principal
¿Qué es OCW?
Ayuda
Feedback
Preguntas frecuentes
Glosario
 
 
Página principal del curso
Programa
Calendario
Lecturas
Trabajos
Exámenes
  Otras fuentes

   MIT

   
 
Sitios web básicos con respaldo de bases de datos, AOLserver, Tcl, SQL

Se requieren aplicaciones de descompresión de archivos, como Winzip® o StuffIt®, para poder abrir los archivos .tar incluidos en el sitio del curso. Para importar los archivos .csv del curso es suficiente contar con cualquier herramienta de software.

Lectura para esta semana

Archivos de ayuda y de ejemplo (si no realiza este curso en el MIT): 6916.ps1.tar (TAR
(Este archivo .tar incluye 1 archivo .txt, 1 archivo .adp, 1 archivo .csv y 10 archivos .tcl.)

Objetivos

Intentaremos comprobar si todos los estudiantes conocen lo siguiente:

  • Cómo iniciar sesión en el servidor de desarrollo.
  • Nociones básicas de Tcl.
  • Cómo ejecutar Tcl a través de tclsh.
  • Nociones de la utilidad de plantillas ADP de AOLserver.
  • Cómo crear, ejecutar, probar y depurar una página .tcl.
  • Cómo diseñar una página .tcl que realice consultas en un servidor externo.
  • Nociones básicas de SQL.
  • Cómo realizar consultas en Oracle a partir del shell con SQL*Plus.
  • Cómo diseñar una página .tcl que realice consultas en Oracle.
  • Cómo personalizar servicios web emitiendo y leyendo cookies.
  • Cómo leer y escribir datos en XML.
  • Cómo utilizar SQL*Loader.

Para realizar este primer boletín de problemas deberá aprender a utilizar muchos programas nuevos de software, por lo que es necesario que se familiarice con estos programas cuanto antes: prevea dedicar al menos dos o tres sesiones. No entrañan gran dificultad, pero queremos que sea capaz de entender la mecánica de Tcl, SQL y cómo ejecutar el servidor Web.

Principios básicos de Tcl
Principios básicos de SQL*Plus
Trabajo con AOLserver y Oracle
Personalización de servicios web con cookies
Compartición de datos con XML
El vasto mundo de Oracle
Arquitectura de la información e interfaz de usuario

Principios básicos de Tcl

Comience por leer  Using the LCS Web/db Computing Facility y siga las instrucciones para iniciar sesión en el servidor.

Ejercicio 1: Ejecutar Tcl desde el shell

Ejecute Emacs. Escriba "m-x shell" para obtener un shell de Unix®. Escriba "tclsh" para iniciar el programa del shell de Tcl. Defina un procedimiento de Fibonacci recursivo en Tcl. Ejecútelo y pruébelo.

Sugerencia: si escribe programas Tcl de más de dos o tres líneas, tal vez le resulte más cómodo escribir el código en un búfer Emacs independiente (definido en modo tcl) y, después, cortar y pegar desde ahí en el búfer del shell de Tcl.

Escriba la información de la versión de tcl en la línea de comandos de tclsh para comprobar que está ejecutando Tcl 8.2, la misma versión que está compilada en AOLserver.

Ejercicio 2: Ejecutar Tcl desde una página (casi) HTML

Consulte el archivo two-plus-two.adp (HTM) y su fuente (TXT). Se trata de un ejemplo de la utilidad de plantillas ADP de AOLserver.

Aumente la página de tal forma que (1) agregue un acuario suramericano Cichlid de 4.000 $ como opción, (2) utilice un procedimiento de constructores para crear cada elemento del acuario (que no se limite simplemente a una lista de llamadas), (3) agregue un elemento al acuario para el número de tipos de acuarios que se instalarán, (4) utilice procedimientos para extraer el tipo, el coste y la cantidad de un elemento del acuario (que no se limite simplemente a un índice de llamadas), (5) imprima los subtotales que dependen de la cantidad y el total al final.

Ejercicio 3: Páginas Tcl sencillas

Desde el navegador web de su equipo local, vaya a la página
http://yourvirtualserver/psets/ps1/simple-tcl-page.tcl. Utilizando Emacs en el servidor, analice el código fuente de esta página en /web/yourvirtualserver/www/psets/ps1/simple-tcl-page.tcl. Observe también el código fuente del formulario ubicado en /web/yourvirtualserver/psets/ps1/simple-tcl-page-2.tcl. (Si no dispone de estos archivos, descárguelos del archivo 6916.ps1.tar (TAR) (Este archivo .tar incluye 1 archivo .txt, 2 archivos .adp, 1 archivo .csv y 10 archivos .tcl.) y colóquelos en /web/yourvirtualserver/www). Tenga en cuenta cómo se utiliza Tcl para leer las variables del formulario. Intente abrir el formulario un par de veces desde su navegador. Ahora, depure la expresión común de simple-tcl-page-2.tcl de tal forma que gestione correctamente los nombres "Tammy Faye Baker" y "William H. Gates III".

Sugerencia 1: es más sencillo si no intenta hacer esto en un regexp. Recurra a if then else if then else if...

Sugerencia 2: regexp tiene un "efecto secundario". Si utiliza una sentencia con varias cláusulas, no olvide agrupar las llamadas a regexp entre corchetes para que no se calculen todas de forma inmediata.

Ejercicio 4: Páginas Tcl que realizan consultas en servidores externos

Desde el navegador web de su equipo local, vaya a Seeq. Lea el análisis de este programa en el
Capítulo 10
 de Philip and Alex's Guide to Web Publishing. Tomando dicho programa como modelo, cree un nuevo servicio web que tome el ISBN de un libro desde un formulario y que, a continuación, utilice
ns_httpget para realizar varias consultas en librerías en línea para encontrar información de precios y existencias, y muestre los resultados en una tabla HTML. Guarde el programa en los archivos llamados /web/yourvirtualserver/www/psets/ps1/books.tcl y books-2.tcl de tal forma que el resto de usuarios puedan tener acceso al servicio en la web.

Recomendamos que realice las consultas en empresas como wordsworth.com, barnesandnoble.com o www.1bookstreet.com (amazon.com suele responder con un mensaje de redirección 302 si el cliente no otorga un ID de sesión en la consulta). El programa deberá ser sólido ante tiempos de espera, errores en sitios externos y problemas de red. Puede conseguir esta solidez agrupando una sentencia de captura Tcl en la llamada a ns_httpget. Pruebe el programa con los siguientes números de ISBN: 0385494238, 0062514792, 0140260404, 0679762906.

Calificación adicional: ¿De cuál de los siguientes libros se ha extraído esta cita? (en inglés)

"The obvious mathematical breakthrough would be development of an easy way to factor large prime numbers."

Es buen momento para tomarnos un descanso.

Principios básicos de SQL*Plus

Inicie de nuevo Emacs (se ha tomado un descanso, ¿verdad?) e inicie un shell de Tcl tal como lo hizo anteriormente (primero "M-x shell" y después "tclsh"). Escriba "M-x rename-buffer" para cambiar el nombre del shell a "tcl-shell". Escriba "M-x shell" para obtener un nuevo shell de Unix®. Cambie el nombre de este búfer a "sql-shell". En el shell de SQL, escriba "sqlplus" para iniciar SQL*Plus, el cliente del shell de Oracle. Se recomienda trabajar utilizando dos shell: uno para Tcl y otro para SQL.

Ejercicio 5: Comunicación con Oracle desde el shell

En SQL*Plus, escriba lo siguiente en una tabla para llevar un seguimiento de las clases de este semestre:

create table my_courses ( course_number varchar(20));

Tenga en cuenta que debe terminar los comandos de SQL con punto y coma en SQL*Plus. Éstos no forman parte del lenguaje SQL y no debe utilizarlos al escribir SQL en los programas Tcl de AOLserver.

Inserte varias filas, por ejemplo,

insert into my_courses (course_number) values ('6.916');

Envíe los cambios:

commit;


Compruebe el resultado:

select * from my_courses;

Una de las múltiples ventajas de utilizar un RDBMS es la persistencia. Todo lo que cree seguirá ahí incluso cuando cierre la sesión. Normalmente, se trata de una ventaja, pero tal vez quiera limpiar el registro una
vez terminado este experimento:

drop table my_courses;

Salga de SQL*Plus escribiendo "c-c c-d".

Ejercicio 6: Páginas Tcl que se comunican con Oracle

Consulte el archivo /web/yourvirtualserver/www/psets/ps1/quotations.tcl, que es el código fuente de una página que muestra citas almacenadas en la base de datos de Oracle. Si visita esta página desde su navegador web, debería obtener un error. El motivo de este error es que el programa llama a un procedimiento que no existe: ad_header ("Encabezado ArsDigita"). Puede confirmar sus sospechas utilizando Emacs para leer /home/nsadmin/log/yourvirtualserver-error.log, ubicación en la que AOLserver registra todos los avisos y problemas.

Para que AOLserver cargue las definiciones del procedimiento en el inicio del servidor, debe colocar archivos .tcl en la biblioteca Tcl privada del servidor: /web/yourvirtualserver/tcl/. Cree un archivo llamado "ps1-defs.tcl" en este directorio y defina los siguientes procedimientos Tcl:

ad_header page_title -- devuelve etiquetas HTML, HEAD, TITLE y BODY con el argumento encerrado entre etiquetas TITLE

ad_footer -- devuelve una cadena que cerrará las etiquetas BODY y HTML

Vuelva a cargar la página quotations.tcl y obtendrá... ¡el mismo error! AOLserver no sabe que ha agregado un archivo a la biblioteca privada; esto sólo se comprueba en el inicio del servidor. Vaya a un shell de
Unix® y escriba "restart-aolserver yourservername" (ésta es la acción definitiva: aniquila el proceso
Unix® del servidor de tal forma que Unix® reinicie AOLserver automáticamente). Si no se restablece el reinicio al escribir "Killing 10234" o cualquier otro ID de proceso, sabrá que no ha conseguido hacerlo correctamente (tal vez haya cometido algún error tipográfico al escribir el nombre del servidor).

Vuelva a cargar la página quotations.tcl y obtendrá... ¡un error sensiblemente distinto! El programa está intentando realizar una consulta en una tabla que no existe: quotations (citas).

Vuelva al shell sql y reinicie SQL*Plus. Copie la definición de la tabla en los comentarios situados en la parte superior del archivo quotations.tcl e introduzca esta definición en Oracle. Regrese al navegador web y vuelva a cargar la página con la que anteriormente obtenía un error. Ahora sí debería funcionar, aunque la tabla de citas estará vacía.

Utilice el formulario de la página web para agregar manualmente la siguiente cita en la categoría correspondiente que decida: "640K ought to be enough for anybody" (Bill Gates). Tenga en cuenta que sería interesante que en la tabla existiese una columna para registrar la fecha de la cita (1981), pero hemos limitado al máximo la complejidad del modelo de datos a propósito.

Vuelva a SQL*Plus y seleccione * en la tabla para ver la cita registrada. El formato tan horroroso se debe a que ha declarado la columna de la cita con una longitud de 4000 caracteres.

En SQL*Plus, inserte una cita con código manual de SQL (si le da pereza, puede cortar y pegar algo de SQL desde el registro de errores de AOLserver; todas las sentencias de SQL que AOLserver envía a Oracle se registran aquí). Ahora, vuelva a cargar la URL de quotations.tcl desde el navegador web. Si no ve la nueva cita es porque no escribió COMMIT; en SQL*Plus. Ésta es una de las características más importantes de un sistema de administración de bases de datos relacionales: los usuarios conectados simultáneamente no pueden ver las transacciones incompletas del resto.

Cargar tablas desde archivos .csv

Ha llegado el momento de precargar la base de datos de citas con material interesante. Cargue /web/yourvirtualserver/www/psets/ps1/quotations.csv en Emacs y eche un vistazo al formato del archivo (es el formato habitual que puede obtener en cualquier programa de hojas de cálculo). Con SQL*Loader (consulte el oraejercicio 1 más adelante), cargue estos datos en la tabla de citas.

Trabajo con AOLserver y Oracle

Veamos cómo acceder a la base de datos desde programas Tcl. La idea básica es que AOLServer incluye una abstracción de datos denominada conjunto (set), definida por las operaciones enumeradas en la API ns_set. Un conjunto es una colección de pares (clave, valor), concepto que debería resultarle familiar, ya que se estudió en el curso 6.001. Al seleccionar desde una tabla con ns_db select se devuelve un identificador para un conjunto, cuyas claves son los nombres de las columnas seleccionadas. Las llamadas siguientes con
ns_db getrow rellenarán los valores de este conjunto con valores de filas sucesivas seleccionadas. Por ejemplo, supongamos que obtiene un identificador de conjunto al seleccionar la siguiente tabla con
ns_select:

ESCRITORES OBRAS
Tolstoy Anna Karenina
Steinbeck Grapes of Wrath
Greenspun Guide to Web Publishing
 

A continuación, tras la primera llamada a ns_db getrow, el conjunto será:


{{writer Tolstoy} {book "Anna Karenina"}}
Tras la segunda llamada a ns_db getrow, el conjunto será
{writer Steinbeck} {book "Grapes of Wrath"}}
Y tras la tercera llamada, el conjunto será:
{{writer Greenspun} {book "Guide to Web Publishing"}}

Los programas de los archivos quotations.tcl y quotation-add.tcl ilustran estas ideas. Le merecerá la pena estudiarlos bien hasta que entienda cómo funcionan, ya que serán muchos los programas de este tipo que tendrá que realizar durante el semestre.

Ejercicio 6a: Eliminación de la tabla de bloqueo mediante una secuencia

Lea lo referente al objeto de la base de datos de secuencias de Oracle en la sección Data Modeling
(Modelado de datos). Mediante la creación de una secuencia, debería poder editar el archivo quotation-add.tcl para:

  • Eliminar la tabla de bloqueo.
  • Eliminar la transacción de inicio y finalización (ya no va a unir varias sentencias SQL).
  • Generar una clave para la nueva cita dentro de la sentencia INSERT.

Ejercicio 7: Mejora de la interfaz de usuario para la introducción de datos

Vuelva a la página principal de quotations.tcl y modifíquela de tal forma que la introducción de categorías se realice a través de un cuadro de selección de las categorías existentes (deberá utilizar el comando "SELECT DISTINCT" de SQL). Para las nuevas categorías, proporcione un cuadro de entrada de texto alternativo denominado "new category" (nueva categoría). No olvide modificar quotation-add.tcl para que pueda detectar la definición de las nuevas categorías.

Ejercicio 8: Búsquedas

Agregue un breve formulario en la parte superior de quotations.tcl que acepte una palabra de consulta sencilla del usuario. Diseñe un objetivo para este formulario que devuelva todas las citas que contengan la palabra especificada. La búsqueda deberá realizarse con distinción entre mayúsculas y minúsculas y también buscará en la columna de autores. Sugerencia: similar a '%foo%'.

Personalización de servicios web con cookies

Nos gustaría que diseñase un sistema para implementar la personalización de la base de datos de citas en función de cada usuario. En general, el objetivo sería:

  • Un usuario puede "aniquilar" una cita y conseguir que no aparezca nunca en la página principal o en la página de búsquedas.
  • Aniquilar una cita es una acción permanente y no queda cancelada al cerrar o reiniciar el navegador.
  • Las citas aniquiladas por un usuario no afectan a lo que el resto de usuarios pueden ver.
  • Los usuarios pueden borrar sus personalizaciones y ver toda la base de datos de citas otra vez
    haciendo clic en el vínculo "borrar mi personalización" de la página principal. Este vínculo sólo debe aparecer si el usuario ha personalizado la base de datos de citas.

Puede personalizar los servicios web con ayuda de las mágicas cookies. Una cookie emitida por el servidor guía al navegador para que almacene datos en el equipo. Para emitir una cookie, el servidor incluye una línea como ésta:

Set-Cookie: cookie_name=value; path=/ ; expires=Fri, 01-Jan-2010 01:00:00 GMT

en el encabezado HTTP enviado al navegador. En este caso, cookie_name es el nombre de la cookie y "value" es el valor asociado que puede contener cualquier carácter excepto un punto y coma (reservado para finalizar la cookie). La ruta de acceso especifica a qué URL del servidor se aplica la cookie. Si la ruta se designa con una barra (/), se incluirán todas las URL del servidor.

Una vez que el navegador ha aceptado una cookie del servidor, incluirá su nombre y su valor como parte de las peticiones HTTP cada vez que solicite al servidor una URL aplicable. Sus programas Tcl pueden leer esta información gracias a la API AOLServer

[ns_set get [ns_conn headers] Cookie]
Una vez cumplida la fecha de caducidad, el navegador ya no enviará la información de la cookie. El servidor también puede emitir cookies sin fecha de caducidad especificada, en cuyo caso, la cookie no sería permanente: el navegador la utilizaría únicamente para esa sesión.

Puede ver un ejemplo sobre la emisión y lectura de cookies en la URL
http://yourvirtualserver/psets/ps1/set-cookies.tcl y analizar el Tcl para el archivo y las URL asociadas
check-cookies.tcl y expire-cookies.tcl. Observe el modo en que expire-cookies se deshace de las cookies volviendo a emitirlas con una fecha de caducidad ya pasada.

Referencia: la información sobre las cookies mágicas está disponible (en inglés) en Persistent Client State HTTP Cookies (Cookies HTTP persistentes de estado de cliente).

Ejercicio 9

Implemente el sistema de citas personalizado descrito anteriormente.

Sugerencia 1: es posible crear este sistema utilizando un identificador de cookies para el navegador y conservando el conjunto de citas aniquiladas de Oracle. No obstante, si no pretende permitir que los usuarios inicien sesión y diseñen su perfil, no tiene mucho sentido conservar estos datos en el servidor. De hecho, al conservar los ID de las citas aniquiladas en las cookies del navegador de los usuarios, habrá conseguido el santo grial de los investigadores de sistemas de administración de bases de datos académicas: ¡una base de datos distribuida!

Sugerencia 2: esto no está estrictamente relacionado con las cookies, pero puede hacer que una de ellas contenga espacios. Tcl almacena una lista de enteros internamente como números separados por espacios. Así, la forma más sencilla de almacenar las citas aniquiladas es en forma de lista separada por espacios.

Sugerencia 3: no filtre las citas en Tcl; esto suele ser un indicio de programación incompleta al consultar más datos de Oracle de los que se podrán mostrar al usuario final. SQL es un lenguaje de consulta muy potente. Puede utilizar la función NOT IN para excluir una lista de citas.

¿Qué tal si nos tomamos otro descanso?

Compartición de datos con XML

Tal como ha aprendido anteriormente al realizar consultas en tiendas de libros, no es habitual que los datos de la web estén formateados para su uso en programas informáticos. En teoría, los usuarios que desean intercambiar datos en la web pueden cooperar utilizando XML, una norma de 1997 del Web Consortium. En la práctica, casi nadie utiliza XML actualmente (1999). Le tranquilizará saber que para resolver este boletín de problemas podrá colaborar con sus compañeros: el objetivo final es realizar consultas en su base de datos y exportarlas en un formato estructurado que el resto de estudiantes pueda leer.

Para poder colaborar, necesitará:

  • Una URL consensuada en el servidor de todos los integrantes para obtener la base de datos de citas: "/quotations-xml.tcl"
  • Un formato consensuado para las citas.

Daremos formato a las citas con XML, que no es más que una convención de notación para describir datos estructurados. Las estructuras de XML constan de cadenas de datos encerradas en etiquetas similares a las HTML con la forma <foo> y </foo>, que describen qué tipo de datos deben ser.

A continuación, se muestra un ejemplo informal para estudiar la estructura que utilizaremos en las citas:

<quotations>

<onequote>

<quotation_id>1</quotation_id>

<insertion_date>1999-02-04</insertion_date>

<author_name>Bill Gates</author_name>

<category>Computer Industry Punditry</category>

<quote>640K ought to be enough for anybody.

</quote>

</onequote>

<onequote>

... otra fila de la tabla de citas ...

</onequote>

... algunas filas más

</quotations>
Tenga en cuenta que hay una etiqueta independiente para cada columna de nuestro modelo de datos de SQL:

<quotation_id>

<insertion_date>

<author_name>

<category>

<quote>

También hay una etiqueta "empaquetadora" que identifica cada fila como una estructura <onequote> y un empaquetador externo que identifica una secuencia de estructuras <onequote> como un documento de <quotations>.

Creación de una DTD

Podemos dar una descripción formal de nuestra estructura XML (y no un ejemplo informal) por medio de una definición de tipo de documento de XML (Document Type Definition - DTD).

Nuestra DTD comenzará con la definición de la etiqueta "quotations" (citas):

<!ELEMENT quotations (onequote)+>
Esta sentencia dice que el elemento "quotations" debe contener al menos una instancia de "onequote", pero puede contener más de una. Ahora debemos decir qué conforma un elemento "onequote" válido:
<!ELEMENT onequote (quotation_id,insertion_date,author_name,category,quote)>
Esta sentencia dice que los subelementos como "quotation_id" deben aparecer exactamente una vez y en el orden especificado. Ahora debemos definir un elemento XML que realmente no contenga sólo otros elementos XML:
<!ELEMENT quotation_id (#PCDATA)>
Esta sentencia dice que todo lo que se encuentre entre <quotation_id> y </quotation_id> deberá interpretarse como caracteres brutos y no como elementos con más etiquetas (PCDATA quiere decir "datos de caracteres analizados").

Ésta es nuestra DTD completa:

<!-- quotations.dtd -->

<!ELEMENT quotations (onequote)+>

<!ELEMENT onequote (quotation_id,insertion_date,author_name,category,quote)>

<!ELEMENT quotation_id (#PCDATA)>

<!ELEMENT insertion_date (#PCDATA)>

<!ELEMENT author_name (#PCDATA)>

<!ELEMENT category (#PCDATA)>

<!ELEMENT quote (#PCDATA)>

Le resultará de gran utilidad... Bueno, en realidad esta DTD no le servirá de nada para realizar esta parte del boletín de problemas. Lo único para lo que las DTD son realmente útiles es para alimentar analizadores de XML, ya que con ellas podrá marcar automáticamente un documento XML. Para implementar la página quotations-xml.tcl, sólo necesitará estudiar el ejemplo informal.

Ejercicio 10: Generación de XML

Cree un programa Tcl que realice consultas en la tabla de citas, genere un documento XML en el formulario anterior y lo devuelva al cliente con una "aplicación/xml" de tipo MIME. Inserte el programa en un archivo quotations-xml.tcl de tal forma que los usuarios puedan recuperar los datos al visitar la URL.

Para que pueda comenzar, le ofrecemos el archivo /psets/ps1/example-xml.tcl. Al solicitar esta URL con un navegador web debería poder guardar el documento en un archivo local y, a continuación, analizarlo con un editor de texto en su equipo local. (Asumimos que no ha definido ningún comportamiento especial de su navegador para la aplicación/xml de tipo MIME.) Las diferencias entre nuestro ejemplo y su programa son que necesitará generar un documento que contenga toda la tabla y necesitará hacerlo sobre la marcha.

Ejercicio 11: Importación de XML

Diseñe un programa para importar una base de datos de citas desde la página de salida XML de otro estudiante (si ha realizado el ejercicio 9 pero sus compañeros aún no, tal vez sea ésta una buena oportunidad para que se esfuercen). Su programa deberá:

  • Obtener el archivo /psets/ps1/quotations-xml.tcl desde la base de datos de otro estudiante utilizando ns_httpget
  • Analizar el archivo y convertirlo en registros que, a su vez, deberá convertir en campos.
  • Si el autor y el contenido de la cita de un servidor externo coincide exactamente con los de su propia base de datos, omítalos; de lo contrario, inserte la cita en su base de datos con un nuevo identificador quotation_id (recuerde que no quiere que existan conflictos entre las claves del servidor externo y las que ya existen en su base de datos).

Sugerencia: tal vez desee definir una tabla temporal utilizando el comando create table quotations_temp as select * de las citas y, después, liberarlo tras la depuración. Debería utilizar DoubleApos al presentar los datos en Oracle para las comparaciones.

En lugar de contar con un vínculo en un programa de 100.000 líneas escrito en C (o un programa Lisp de 5.000 líneas) que analice documentos XML basados en una DTD, hemos optado por la simplicidad y hemos predefinido un analizador en Tcl que recoja esta DTD concreta para citas. El procedimiento es parse_all (TXT) (deberá instalar este archivo en la biblioteca Tcl privada de su servidor, /web/yourvirtualserver/tcl/, para poder llamar a esta función desde las páginas .tcl y .adp). El procedimiento parse_all toma una estructura de citas XML como argumento y lo devuelve a una lista Tcl mostrando las secciones y subsecciones de la estructura. Para ver un ejemplo del formato, utilice su navegador para ir a la página http://yourvirtualserver/psets/ps1/xml-parse-test.tcl.

Nota: estos ejercicios están pensados para que se familiarice con XML. En la mayoría de los casos, el procesado de XML complejo debe realizarse dentro de Oracle utilizando las bibliotecas de Java®.

Ejercicio 12: Seguimiento de la popularidad de un libro

Los escritores neuróticos consultan amazon.com constantemente para ver qué puesto ocupan sus libros en la lista de ventas. El hecho de que estas cifras se actualicen cada hora únicamente contribuye a que este hábito se convierta en algo más destructivo. Diseñe un programa para realizar el seguimiento de la obra de un escritor realmente neurótico (ISBN: 1558605347). Necesitará:
  1. Definir una tabla de Oracle en la que incluir el ISBN, la fecha y la hora y el puesto en la lista de ventas.
  2. Escriba un procedimiento que obtenga la página de Amazon, extraiga REGEXP de la lista de ventas y lo coloque en la tabla de Oracle.
  3. Utilice la llamada a la API AOLserver ns_schedule_proc para programar la ejecución de procedimiento cada hora.
  4. Diseñe una página .tcl para poder comparar la popularidad a lo largo del tiempo.

Uno de los aspectos interesantes de Amazon es que a menudo pierden el control de su grupo de servidores y su base de datos (escriben mucho código en C y los descuidos del programador pueden llevar a un fallo catastrófico de todo el servicio). Deberá crear su sistema de tal forma que registre: (a) las horas en las que no es posible acceder a amazon.com y (b) en cuáles de esas horas la página ofrecida contiene la cadena "Our store is closed temporarily for scheduled maintenance" (Nuestro establecimiento está cerrado temporalmente por motivos de mantenimiento programado). A veces este mensaje se obtiene en días de diario en los que, definitivamente, no debería haber ningún mantenimiento programado.

Ejercicio 13: Cómo convertirse en un diseñador de gráficos

¿Por qué imprimir una tabla con los libros más populares si podemos imprimir un gráfico? Está a punto de descubrir las maravillas de los GIF de píxel único y de las etiquetas WIDTH y HEIGHT. Coloque el software en el directorio Tcl privado del servidor (/web/nombre_del_servidor/tcl/). Lea la documentación y, a continuación, escriba el código para generar un gráfico bonito de los datos del ejercicio 12.

Tenga en cuenta que se está adentrando en el kit de herramientas de ArsDigita Community System, el software que le mantendrá bien ocupado en el boletín de problemas 2.

El vasto mundo de Oracle

Vamos a cambiar de tema ahora y adentrarnos en una parte del boletín de problemas pensada para que sepa más de Oracle y SQL.

Oraejercicio 1: SQL*Loader

  • Cree un archivo separado por tabulaciones en Emacs que contenga cinco líneas, cada una con el símbolo del valor que más le guste, el número de acciones en propiedad y la fecha de adquisición (con el formato MM/DD/AAAA).
  • Cree una tabla de Oracle en la que incluir estos datos:

    create table my_stocks (
    symbol varchar(20) not null,
    n_shares integer not null,
    date_acquired date not null
    );

  • Utilice el comando sqlldr para invocar SQL*Loader y convertir el archivo separado por tabulaciones
    en la tabla my_stocks (consulte la página 1183 de Oracle8: The Complete Reference y la documentación oficial de Oracle).

Oraejercicio 2: Copia de datos entre tablas

Este ejercicio existe porque nos hemos dado cuenta de que, al afrontar la tarea de mover datos entre tablas, los programadores arrastraban los datos de SQL*Net desde Oracle hasta AOLserver, los manipulaban en Tcl y, después, los devolvían a Oracle a través de SQL*Net. ¡Así no se hace! SQL es un lenguaje muy potente y no hay necesidad de utilizar otras herramientas si lo que se quiere es mover datos dentro de Oracle.
  • Utilizando una sola sentencia de SQL, cree una tabla llamada stock_prices (precios de valores) con tres columnas: symbol (símbolo), quote_date (fecha de valor), price (precio). Tras esta sentencia, deberá crear la tabla y rellenarla con una fila por símbolo en my_stocks (mis valores). Las columnas de fecha y precio deberán contener la fecha actual y el precio nominal. Sugerencia: seleccione symbol y sysdate como quote_date (fecha de cita) y 31.415 como precio para my_stocks;.
  • Cree una nueva tabla:


    create table newly_acquired_stocks (
    symbol varchar(20) not null,
    n_shares integer not null,
    date_acquired date not null
    );

  • Utilizando una sentencia simple insert into .. select ... (con una cláusula WHERE según sus datos de muestra), copie aproximadamente la mitad de las filas de my_stocks en newly_acquired_stocks (valores de reciente adquisición).

Oraejercicio 3: JOIN

Con una sentencia simple de SQL (JOIN), una my_stocks y stock_prices (precio de los valores), genere un informe que muestre el símbolo, el número de acciones, el precio por acción y el valor actual.

Oraejercicio 4: OUTER JOIN

Inserte una fila en my_stocks. Realice la consulta del oraejercicio 3. Tenga en cuenta que el nuevo valor no aparecerá en el informe. Esto se debe a que los ha unido (JOIN) con la limitación de que el símbolo aparezca en las dos tablas.

Modifique la sentencia para que utilice un OUTER JOIN y poder así obtener un informe completo de todos los valores, pero no obtener la información del precio si no hay ninguno disponible.

Oraejercicio 5: PL/SQL

Inspirándonos en los métodos de Wall Street para evaluar las empresas de Internet, hemos desarrollado nuestro propio método de evaluación para este boletín de problemas: un valor se evalúa como la suma de caracteres ASCII que conforman su símbolo. (Tenga en cuenta que los estudiantes que utilizan minúsculas para representar símbolos tendrán informes con valores mayores que los que utilicen siempre símbolos escritos en mayúsculas; "IBM" sólo tiene un valor de 216 $ mientras que "ibm" tiene un valor de 312 $).
  • Defina una función PL/SQL que tome un símbolo de comercio y su argumento, y que devuelva el valor del valor (sugerencia: la función ASCII incorporada en Oracle le será de gran ayuda).
  • Con una sentencia simple UPDATE, actualice stock_prices para definir el valor de cada valor en el resultado obtenido por este procedimiento PL/SQL.
  • Defina una función PL/SQL que no tome ningún argumento y que devuelva el valor agregado del informe (nº_acciones * precio de cada valor). Deberá definir su JOIN a partir del oraejercicio 3 (más arriba) como un cursor y, a continuación, recurrir a la utilidad FOR LOOP del cursor PL/SQL. Sugerencia: cuando haya terminado, puede ejecutar este procedimiento desde SQL*Plus con select portfolio_value() from dual;.
Sugerencia de SQL*Plus: aunque esto no forma parte del lenguaje SQL, seguro que le resultará útil escribir "/" después de las definiciones PL/SQL si pretende insertarlas en Oracle a través de la aplicación SQL*Plus. A no ser que escriba un código perfecto, también le vendrá bien conocer el comando "show errors" (mostrar errores) de SQL*Plus. Si desea obtener información completa sobre este tipo de oscurantismo, consulte la referencia (en inglés) SQL*Plus User's Guide and Reference.

Oraejercicio 6: Compre más a los ganadores

En vez de compartir los beneficios con los ganadores: ¡compre más!

  • Utilice SELECT AVG() para deducir el precio medio de sus participaciones.
  • Utilizando una sentencia simple INSERT con SELECT, duplique sus participaciones en todas las acciones cuyo precio esté por encima de la media (con date_acquired definida en sysdate).
Vuelva a realizar la consulta del oraejercicio 4. Observe que, en ocasiones, tendrá dos filas para el mismo símbolo. Si lo que realmente le interesa es la posición actual, deberá obtener un informe con una fila por símbolo como máximo.
  • Utilice una consulta SELECT ... GROUP BY desde my_stocks para generar un informe de símbolos y el total de las acciones.
  • Utilice una consulta SELECT .. GROUP BY en combinación (JOIN) con stock_prices para generar un informe de símbolos y el valor total de cada uno de ellos.
  • Utilice una consulta SELECT .. GROUP BY .. HAVING para generar un informe de símbolos, el total de las acciones y el valor total de cada símbolo restringido a los símbolos que tengan, al menos, dos bloques de acciones (esto es, los "ganadores").

Oraejercicio 7: Encapsule las consultas con una vista

Con la consulta final anterior, cree una vista llamada stocks_i_like (acciones que me gustan) que encapsule la consulta final.

Arquitectura de la información e interfaz de usuario

Ya tiene una tabla de base de datos llena de datos de valores. Hay un par de formas de ofrecer una interfaz web a estos datos. El desarrollador web fracasado presentaría una página con opciones para recuperar los datos de los valores:

  • Mostrar adquisiciones recientes.
  • Mostrar mejores actores.
  • Mostrar valores más altos.
  • Mostrar todo el informe.
Lo importante es que el usuario no vea nada en la primera página. Por tanto, desde el punto de vista de la presentación de la información, la primera página no sirve.

Una alternativa es mostrar al usuario una tabla con participaciones en la página principal, con un buen subconjunto de datos predeterminados, y facilitar botones para ajustar lo que se incluye en la visualización. ¿Qué tipo de botones? Podría contar con los descritos más arriba, además de cualquier otra vista que el creador del sitio y los usuarios consideren necesaria. Suponga, no obstante, que puede organizar los botones en dimensiones ortogonales. Si puede hacerlo simplemente con un conjunto de "deslizadores dimensionales", el usuario tendrá ante sí muchas opciones.

Por ejemplo, el sistema de supervisión de tickets de ArsDigita se utiliza para almacenar informes de errores y solicitudes de funciones. Se utilizan las siguientes dimensiones:

  • Involucración del usuario conectado (valores: mío/de todos).
  • Estado del ticket (valores: abierto/+retrasado/+cerrado).
  • Fecha del ticket (valores: ayer/la semana pasada/el mes pasado/todos).
Observe que, aunque éstas se han modelado como dimensiones continuas, el usuario no obtiene
deslizadores continuos. El usuario selecciona un punto discreto entre varios en cada dimensión.
Esta interfaz es compatible con el navegador Netscape 1.1 y ofrece al usuario 24 opciones en total. Aun
así, en vez de ver 24 opciones en una larga lista, el usuario ve una línea en la parte superior del navegador con nueve botones organizados con lógica en tres dimensiones.

Si no bastase con estas 24 opciones, el sistema de supervisión de tickets permite que el usuario
reorganice la tabla en función de cualquiera de las columnas haciendo clic en el encabezado de la columna
en cuestión.

Intente crear algo parecido con su informe de valores. Deberá obtener una página .tcl que muestre el contenido de my_stocks y stock_prices. Incluya botones en la parte superior (sugerencia: TABLE WIDTH=100% y TD ALIGN= RIGHT le vendrán muy bien) para las siguientes dimensiones:

  • Fecha de las adquisiciones (en la semana pasada/mes pasado/año pasado/todos).
  • Valor de la participación (más del 10% del informe total/más del 2%/todos).
Permita que los usuarios puedan ordenar cualquiera de las columnas que aparecen (sugerencia: export_ns_set_vars en $SERVER_HOME/tcl/00-ad-utilities.tcl le será de ayuda, sobre todo por el argumento exclusion_list), por ejemplo, símbolo, número de acciones, precio por acción, valor de la participación.

Puede crear esto desde el principio o utilizar las llamadas de la API del kit de herramientas de ArsDigita Community System como bloque principal.

Quién ha redactado esto y cuándo

Este boletín de problemas lo escribieron  Philip Greenspun y Hal Abelson en enero de 1999. El copyright es
de 1999 pero puede reutilizarse siempre y cuando se haga mención a los autores originales.

Massachusetts Institute of Technology © 2003 MIT | Información Jurídica | Privacidad
Todo uso del sitio de MIT OpenCourseWare y sus materiales de curso queda sujeto a las condiciones y términos de uso detallados
en la sección sobre Información Jurídica
Copyright © 2003 Portal Universia S.A. Todos los derechos reservados
(Avda. de Cantabria s/n - Edif. Arrecife, planta 00.28660 Boadilla del Monte) - Madrid. España.
Contacta con nosotros: Usuarios | Empresas-Instituciones-Medios comunicación
Código Ético | Aviso Legal | Política de confidencialidad | Quiénes somos: Sala de Prensa