diazenriquezalandejesus investigacion u3

33
1 INGENIERÍA EN SISTEMAS COMPUTACIONALES Materia: Programación De Base De Datos Semestre - Grupo - Sistema: 6° Semestre – Semiescolarizado. Producto Académico: Investigacion Tema: U3.- Programación del lado del servidor Presenta: Alan De Jesús Díaz Enriquez, 106Z0085 Docente: I.S.C. Rafael Zamudio Reyes H. ALVARADO, VER. AGO. – DIC. 2015 INSTITUTO TECNOLOGICO SUPERIOR DE ALVARADO

Upload: alan-de-jesus-diaz-enriquez

Post on 05-Dec-2015

13 views

Category:

Documents


0 download

DESCRIPTION

investigacion

TRANSCRIPT

Page 1: DiazEnriquezAlanDeJesus Investigacion U3

1

INGENIERÍA EN

SISTEMAS COMPUTACIONALES

Materia:

Programación De Base De Datos

Semestre - Grupo - Sistema:

6° Semestre – Semiescolarizado.

Producto Académico:

Investigacion

Tema:

U3.- Programación del lado del servidor

Presenta:

Alan De Jesús Díaz Enriquez, 106Z0085

Docente:

I.S.C. Rafael Zamudio Reyes

H. ALVARADO, VER. AGO. – DIC. 2015

INSTITUTO TECNOLOGICO SUPERIOR

DE ALVARADO

Page 2: DiazEnriquezAlanDeJesus Investigacion U3

2

INDICE

Introducción ................................................................................................................................................... 3

U3.- Programación del lado del servidor ................................................................................................ 4

3.1.1.- Creación De Vistas ........................................................................................................................... 5

3.1.2. - Creación De Cursores .................................................................................................................. 11

3.1.3. – Creación de funciones ................................................................................................................ 15

3.1.4.- Elementos de un lenguaje de programación (Transact – SQL, PL/SQL, etc.) ................ 19

3.1.5.- Disparadores (Triggers) ................................................................................................................ 22

3.1.6.- Procedimientos almacenados (Stored Procedures) ............................................................. 23

3.2.- Programación del lado del cliente ................................................................................................. 25

Compilación.......................................................................................................................................... 25

Comunicación con el DBMS ............................................................................................................ 26

Correspondencia entre tipos de C y tipos de SQL .................................................................... 27

Impedance Mistmatch ........................................................................................................................ 29

La Captura de Mensajes del DBMS ........................................................................................................ 30

La Estructura SQLCA ......................................................................................................................... 30

La Instrucción WHENEVER .............................................................................................................. 30

3.2.2 JDBC con Java .................................................................................................................................. 31

Conclusión .................................................................................................................................................... 31

Fuentes .......................................................................................................................................................... 32

Page 3: DiazEnriquezAlanDeJesus Investigacion U3

3

Introducción

La Programación del lado del servidor es una tecnología que consiste en el procesamiento

de una petición de un usuario mediante la interpretación de un script en el servidor web

para generar páginas HTML dinámicamente como respuesta. Todo lo que suceda dentro

del servidor es llamado procesamiento del lado del servidor, o server-side processing.

Cuando tu aplicación necesita interactuar con el servidor (por ejemplo, para cargar o

guardar datos), ésta realiza una petición del lado del cliente (client-side request) desde el

navegador, a través de la red usando invocaciones remotas a métodos (remote procedure

call, RPC). Mientras se está procesando una llamada RPC, tu servidor está ejecutando

código del lado del servidor.

Page 4: DiazEnriquezAlanDeJesus Investigacion U3

4

U3.- Programación del lado del servidor

Todo lo que suceda dentro del servidor es llamado procesamiento del lado del servidor, o

server-side processing. Cuando tu aplicación necesita interactuar con el servidor (por

ejemplo, para cargar o guardar datos), ésta realiza una petición del lado del cliente (client-

side request) desde el navegador, a través de la red usando invocaciones remotas a

métodos (remote procedure call, RPC). Mientras se está procesando una llamada RPC, tu

servidor está ejecutando código del lado del servidor.

Los primeros servidores web permitían visualizar exclusivamente información estática. Esto

representó bien pronto una limitación; sobre todo desde el momento en el que la actividad

publicitaria y comercial comenzó a concentrarse también en la red Internet.

La unificación de tareas, que inicialmente parecía una ventaja para el desarrollo de páginas

web, se convirtió en realidad en una fuerte limitación para el desarrollo de aplicaciones web.

La programación del lado del servidor es un elemento agregado muy importante en el

diseño o construcción de sitios Web, ya que permite de una u otra forma el manejo de datos

de forma dinámica. Los primeros servidores Web que permitían construir páginas dinámicas

utilizaban CGI. CGI es aún muy común en la actualidad y los servicios de IIS de Microsoft

pueden usar CGI al igual que las páginas ASP. CGI es una tecnología que nos permite

invocar programas compilados o guiones en el servidor Web. CGI se ve a menudo en los

servidores Web de sistemas UNIX, y muchos de los programas CGI son guiones Perl.

Page 5: DiazEnriquezAlanDeJesus Investigacion U3

5

3.1.1.- Creación De Vistas

Esta sentencia crea una vista nueva o reemplaza una existente si se incluye la cláusula OR

REPLACE. La sentencia_select es una sentencia SELECT que proporciona la definición de

la vista. Puede estar dirigida a tablas de la base o a otras vistas.

Se requiere que posea el permiso CREATE VIEW para la vista, y algún privilegio en cada

columna seleccionada por la sentencia SELECT. Para columnas incluidas en otra parte de

la sentencia SELECT debe poseer el privilegio SELECT. Si está presente la cláusula OR

REPLACE, también deberá tenerse el privilegio DELETE para la vista.

Toda vista pertenece a una base de datos. Por defecto, las vistas se crean en la base de

datos actual. Pera crear una vista en una base de datos específica, indíquela

con base_de_datos.nombre_vista al momento de crearla.

mysql> CREATE VIEW test.v AS SELECT * FROM t;

Las tablas y las vistas comparten el mismo espacio de nombres en la base de datos, por

eso, una base de datos no puede contener una tabla y una vista con el mismo nombre.

Al igual que las tablas, las vistas no pueden tener nombres de columnas duplicados. Por

defecto, los nombres de las columnas devueltos por la sentencia SELECT se usan para las

columnas de la vista. Para dar explícitamente un nombre a las columnas de la vista utilice

la clásula columnaspara indicar una lista de nombres separados con comas. La cantidad

de nombres indicados en columnas debe ser igual a la cantidad de columnas devueltas por

la sentencia SELECT.

Las columnas devueltas por la sentencia SELECT pueden ser simples referencias a

columnas de la tabla, pero tambien pueden ser expresiones conteniendo funciones,

constantes, operadores, etc.

Los nombres de tablas o vistas sin calificar en la sentencia SELECT se interpretan como

pertenecientes a la base de datos actual. Una vista puede hacer referencia a tablas o vistas

en otras bases de datos precediendo el nombre de la tabla o vista con el nombre de la base

de datos apropiada.

Las vistas pueden crearse a partir de varios tipos de sentencias SELECT. Pueden hacer

referencia a tablas o a otras vistas. Pueden usar combinaciones, UNION, y subconsultas.

El SELECT inclusive no necesita hacer referencia a otras tablas. En el siguiente ejemplo se

define una vista que selecciona dos columnas de otra tabla, así como una expresión

calculada a partir de ellas:

Page 6: DiazEnriquezAlanDeJesus Investigacion U3

6

mysql> CREATE TABLE t (qty INT, price INT);

mysql> INSERT INTO t VALUES(3, 50);

mysql> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;

mysql> SELECT * FROM v;

+------+-------+-------+

| qty | price | value |

+------+-------+-------+

| 3 | 50 | 150 |

+------+-------+-------+

La definición de una vista está sujeta a las siguientes limitaciones:

La sentencia SELECT no puede contener una subconsulta en su cláusula FROM.

La sentencia SELECT no puede hacer referencia a variables del sistema o del usuario.

La sentencia SELECT no puede hacer referencia a parámetros de sentencia preparados.

Dentro de una rutina almacenada, la definición no puede hacer referencia a parámetros de

la rutina o a variables locales.

Cualquier tabla o vista referenciada por la definición debe existir. Sin embargo, es posible

que después de crear una vista, se elimine alguna tabla o vista a la que se hace referencia.

Para comprobar la definición de una vista en busca de problemas de este tipo, utilice la

sentencia CHECK TABLE.

La definición no puede hacer referencia a una tabla TEMPORARY, y tampoco se puede

crear una vista TEMPORARY.

Las tablas mencionadas en la definición de la vista deben existir siempre.

No se puede asociar un disparador con una vista.

En la definición de una vista está permitido ORDER BY, pero es ignorado si se seleccionan

columnas de una vista que tiene su propio ORDER BY.

Con respecto a otras opciones o cláusulas incluidas en la definición, las mismas se agregan

a las opciones o cláusulas de cualquier sentencia que haga referencia a la vista creada,

pero el efecto es indefinido. Por ejemplo, si la definición de una vista incluye una cláusula

LIMIT, y se hace una selección desde la vista utilizando una sentencia que tiene su propia

cláusula LIMIT, no está definido cuál se aplicará. El mismo principio se extiende a otras

opciones como ALL, DISTINCT, o SQL_SMALL_RESULT que se ubican a continuación de

la palabra reservada SELECT, y a cláusulas como INTO, FOR UPDATE, LOCK IN SHARE

MODE, y PROCEDURE.

Si se crea una vista y luego se modifica el entorno de proceso de la consulta a traves de la

modificación de variables del sistema, puede afectar los resultados devueltos por la vista:

mysql> CREATE VIEW v AS SELECT CHARSET(CHAR(65)), COLLATION(CHAR(65));

Page 7: DiazEnriquezAlanDeJesus Investigacion U3

7

Query OK, 0 rows affected (0.00 sec)

mysql> SET NAMES 'latin1';

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM v;

+-------------------+---------------------+

| CHARSET(CHAR(65)) | COLLATION(CHAR(65)) |

+-------------------+---------------------+

| latin1 | latin1_swedish_ci |

+-------------------+---------------------+

1 row in set (0.00 sec)

mysql> SET NAMES 'utf8';

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM v;

+-------------------+---------------------+

| CHARSET(CHAR(65)) | COLLATION(CHAR(65)) |

+-------------------+---------------------+

| utf8 | utf8_general_ci |

+-------------------+---------------------+

1 row in set (0.00 sec)

La cláusula opcional ALGORITHM es una extensión de MySQL al SQL estándar.

ALGORITHM puede tomar tres valores: MERGE, TEMPTABLE, o UNDEFINED. El

algoritmo por defecto es UNDEFINED si no se encuentra presente la cláusula ALGORITHM.

El algoritmo afecta la manera en que MySQL procesa la vista.

Para MERGE, el texto de una sentencia que haga referencia a la vista y la definición de la

vista son mezclados de forma que parte de la definición de la vista reemplaza las partes

correspondientes de la consulta.

Para TEMPTABLE, los resultados devueltos por la vista son colocados en una tabla

temporal, la cual es luego utilizada para ejecutar la sentencia.

Para UNDEFINED, MySQL determina el algoritmo que utilizará. En ese caso se prefiere

MERGE por sobre TEMPTABLE si es posible, ya que MERGE por lo general es más

eficiente y porque la vista no puede ser actualizable si se emplea una tabla temporal.

Una razón para elegir explícitamente TEMPTABLE es que los bloqueos en tablas

subyacentes pueden ser liberados despues que la tabla temporal fue creada, y antes de

Page 8: DiazEnriquezAlanDeJesus Investigacion U3

8

que sea usada para terminar el procesamiento de la sentencia. Esto podría resultar en una

liberación del bloqueo más rápida que en el algoritmo MERGE, de modo que otros clientes

que utilicen la vista no estarán bloqueados mucho tiempo.

El algoritmo de una vista puede ser UNDEFINED en tres situaciones:

No se encuentra presente una cláusula ALGORITHMen la sentencia CREATE VIEW.

La sentencia CREATE VIEW tiene explícitamente una cláusula ALGORITHM =

UNDEFINED.

Se especificó ALGORITHM = MERGE para una vista que solamente puede ser procesada

usando una tabla temporal. En este caso, MySQL emite una advertencia y establece el

algoritmo en UNDEFINED.

Como se dijo anteriormente, MERGE provoca que las partes correspondientes de la

definición de la vista se combinen dentro de la sentencia que hace referencia a la vista. El

siguiente ejemplo muestra brevemente cómo funciona el algoritmo MERGE. El ejemplo

asume que hay una vista v_merge con esta definición:

CREATE ALGORITHM = MERGE VIEW v_merge (vc1, vc2) AS

SELECT c1, c2 FROM t WHERE c3 > 100;

Ejemplo 1: Suponiendo que se utilice esta sentencia:

SELECT * FROM v_merge;

MySQL la gestiona del siguiente modo:

v_merge se convierte en t

* se convierte en vc1, vc2, que corresponden a c1, c2

Se agrega la cláusula WHERE de la vista

La sentencia ejecutada resulta ser:

SELECT c1, c2 FROM t WHERE c3 > 100;

Ejemplo 2: Suponiendo que se utilice esta sentencia:

SELECT * FROM v_merge WHERE vc1 < 100;

Esta sentencia se gestiona en forma similar a la anterior, a excepción de que vc1 < 100 se

convierte en c1 < 100 y la cláusula WHERE de la vista se agrega a la cláusula WHERE de

la sentencia empleando un conector AND (y se agregan paréntesis para asegurarse que

Page 9: DiazEnriquezAlanDeJesus Investigacion U3

9

las partes de la cláusula se ejecutarán en el orden de precedencia correcto). La sentencia

ejecutada resulta ser:

SELECT c1, c2 FROM t WHERE (c3 > 100) AND (c1 < 100);

Necesariamente, la sentencia a ejecutar tiene una cláusula WHERE con esta forma:

WHERE (WHERE de la sentencia) AND (WHERE de la vista)

El algoritmo MERGE necesita una relación uno-a-uno entre los registros de la vista y los

registros de la tabla subyacente. Si esta relación no se sostiene, debe emplear una tabla

temporal en su lugar. No se tendrá una relación uno-a-uno si la vista contiene cualquiera

de estos elementos:

Funciones agregadas (SUM(), MIN(), MAX(), COUNT(), etcétera)

DISTINCT

GROUP BY

HAVING

UNION o UNION ALL

Hace referencia solamente a valores literales (en tal caso, no hay una tabla subyacente)

Algunas vistas son actualizables. Esto significa que se las puede emplear en sentencias

como UPDATE, DELETE, o INSERT para actualizar el contenido de la tabla subyacente.

Para que una vista sea actualizable, debe haber una relación uno-a-uno entre los registros

de la vista y los registros de la tabla subyacente. Hay otros elementos que impiden que una

vista sea actualizable. Más específicamente, una vista no será actualizable si contiene:

Funciones agregadas (SUM(), MIN(), MAX(), COUNT(), etcétera)

DISTINCT

GROUP BY

HAVING

UNION o UNION ALL

Una subconsulta en la lista de columnas del SELECT

Join

Una vista no actualizable en la cláusula FROM

Una subconsulta en la cláusula WHERE que hace referencia a una tabla en la cláusula

FROM

Hace referencia solamente a valores literales (en tal caso no hay una) tabla subyacenta

para actualizar.

ALGORITHM = TEMPTABLE (utilizar una tabla temporal siempre resulta en una vista no

actualizable)

Page 10: DiazEnriquezAlanDeJesus Investigacion U3

10

Con respecto a la posibilidad de agregar registros mediante sentencias INSERT, es

necesario que las columnas de la vista actualizable también cumplan los siguientes

requisitos adicionales:

No debe haber nombres duplicados entre las columnas de la vista.

La vista debe contemplar todas las columnas de la tabla en la base de datos que no tengan

indicado un valor por defecto.

Las columnas de la vista deben ser referencias a columnas simples y no columnas

derivadas. Una columna derivada es una que deriva de una expresión. Estos son algunos

ejemplos de columnas derivadas:

3.14159

col1 + 3

UPPER(col2)

col3 / col4

(//subquery//)

No puede insertar registros en una vista conteniendo una combinación de columnas simples

y derivadas, pero puede actualizarla si actualiza únicamente las columnas no derivadas.

Considere esta vista:

CREATE VIEW v AS SELECT col1, 1 AS col2 FROM t;

En esta vista no pueden agregarse registros porque col2 es derivada de una expresión.

Pero será actualizable si no intenta actualizar col2. Esta actualización es posible:

UPDATE v SET col1 = 0;

Esta actualización no es posible porque se intenta realizar sobre una columna derivada:

UPDATE v SET col2 = 0;

A veces, es posible que una vista compuesta por múltiples tablas sea actualizable,

asumiendo que es procesada con el algoritmo MERGE. Para que esto funcione, la vista

debe usar inner join (no outer join o UNION). Además, solamente puede actualizarse una

tabla de la definición de la vista, de forma que la cláusula SET debe contener columnas de

sólo una tabla de la vista. Las vistas que utilizan UNION ALL no se pueden actualizar

aunque teóricamente fuese posible hacerlo, debido a que en la implementación se emplean

tablas temporales para procesarlas.

En vistas compuestas por múltiples tablas, INSERT funcionará si se aplica sobre una única

tabla. DELETE no está soportado.

Page 11: DiazEnriquezAlanDeJesus Investigacion U3

11

La cláusula WITH CHECK OPTION puede utilizarse en una vista actualizable para evitar

inserciones o actualizaciones excepto en los registros en que la cláusula WHERE de

la sentencia_select se evalúe como true.

En la cláusula WITH CHECK OPTION de una vista actualizable, las palabras reservadas

LOCAL y CASCADED determinan el alcance de la verificación cuando la vista está definida

en términos de otras vistas. LOCAL restringe el CHECK OPTION sólo a la vista que está

siendo definida. CASCADED provoca que las vistas subyacentes también sean verificadas.

Si no se indica, el valor por defecto es CASCADED. Considere las siguientes definiciones

de tabla y vistas:

mysql> CREATE TABLE t1 (a INT);

mysql> CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2

-> WITH CHECK OPTION;

mysql> CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0

-> WITH LOCAL CHECK OPTION;

mysql> CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0

-> WITH CASCADED CHECK OPTION;

Las vistas v2 y v3 estan definidas en términos de otra vista, v1. v2 emplea check option

LOCAL, por lo que las inserciones sólo atraviesan la verificación de v2 . v3 emplea check

option CASCADED de modo que las inserciones no solamente atraviesan su propia

verificación sino tambien las de las vistas subyacentes. Las siguientes sentencias

demuestran las diferencias:

ql> INSERT INTO v2 VALUES (2);

Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO v3 VALUES (2);

ERROR 1369 (HY000): CHECK OPTION failed 'test.v3'

3.1.2. - Creación De Cursores

En bases de datos, el término cursor se refiere a una estructura de control utilizada para el

recorrido (y potencial procesamiento) de los registros del resultado de una consulta.

Un cursor se utiliza para el procesamiento individual de las filas devueltas por el sistema

gestor de base de datos para una consulta. Es necesario debido a que muchos lenguajes

de programación sufren de lo que en inglés se conoce como impedance mismatch. Por

norma general los lenguajes de programación son procedurales y no disponen de ningún

mecanismo para manipular conjuntos de datos en una sola instrucción. Debido a ello, las

filas deben ser procesadas de forma secuencial por la aplicación. Un cursor puede verse

como un iterador sobre la colección de filas que habrá en el set de resultados.

Page 12: DiazEnriquezAlanDeJesus Investigacion U3

12

Existen sentencias SQL que no requieren del uso de cursores. Ello incluye la

sentencia Insert, así como la mayoría de formas del Update o el Delete. Incluso una

sentencia Select puede no requerir un cursor si se utiliza en la variante de SELECT...INTO,

ya que esta variante sólo devuelve una fila.

Trabajando con cursores

Esta sección introduce la forma en la que los cursores deberían ser utilizados en

aplicaciones con SQL empotrado, según el estándar SQL:2003. No todas las capas de

aplicación para sistemas de bases de datos relacionales siguen este estándar, utilizando

en su lugar una interfaz diferente, como CLI o JDBC.

Un cursor es creado utilizando la sentencia DECLARE CURSOR. Es obligatorio asignarle

un nombre.

DECLARE cursor_name CURSOR FOR SELECT... FROM...

Antes de ser utilizado, el cursor debe ser abierto con una sentencia OPEN . Como resultado

de esta sentencia, el cursor se posiciona antes de la primera fila del set de resultados.

OPEN cursor_name

Un cursor se posiciona en una fila específica del set de resultados con la sentencia FETCH.

Una sentencia fetch transfiere la información de la fila a la aplicación. Una vez todas las

filas han sido procesadas o la sentencia fetch queda posicionada en una fila no existente

(ver cursores de recorrido más abajo), el SGBD devuelve un SQLSTATE '02000'

(acompañado normalmente de un SQLCODE +100) para indicar el final del set de

resultados.

FETCH cursor_name INTO...

El último paso consiste en cerrar el cursor utilizando la sentencia CLOSE .

CLOSE cursor_name

Una vez un cursor está cerrado puede reabrirse de nuevo, lo cual implica que la consulta

es reevaluada y se crea un nuevo set de resultados.

Cursores de recorrido

Los cursores pueden declararse como de recorrido o no. Si son de recorrido, éste indica la

dirección en la que el cursor puede moverse.

Page 13: DiazEnriquezAlanDeJesus Investigacion U3

13

Un cursor sin recorrido (non-scrollable en inglés) también se conoce como

cursor unidireccional (forward-only en inglés). Cada fila puede ser leída como mucho una

vez, y el cursor automáticamente se mueve a la siguiente fila. Una operación de fetch

después de haber recuperado la última fila posiciona el cursor detrás de la misma y

devuelve SQLSTATE 02000 (SQLCODE +100).

Un cursor de recorrido puede posicionarse en cualquier parte del set de resultados

utilizando la sentencia SQL FETCH. La palabra clave debe ser especificada cuando se

declare el cursor. El valor por defecto es NO SCROLL , aunque algunas capas de aplicación

para bases de datos como JDBC pueden aplicar un valor por defecto diferente.

DECLARE cursor_name sensitivity SCROLL CURSOR FOR SELECT... FROM...

La posición de un cursor de recorrido puede especificarse de forma relativa a la posición

actual del cursor o de forma absoluta a partir del principio del set de resultados.

FETCH [ NEXT | PRIOR | FIRST | LAST ] FROM cursor_name

FETCH ABSOLUTE n FROM cursor_name

FETCH RELATIVE n FROM cursor_name

Los cursores de recorrido pueden potencialmente acceder a la misma fila del set de

resultados múltiples veces. Por lo tanto, modificaciones de datos (insert, update, delete)

realizadas por otras transacciones podrían tener un impacto en el set de resultados. Un

cursor puede ser sensible o insensible a tales modificaciones. Un cursor sensible

recogería las modificaciones que afectarían al set de resultados, mientras que uno

insensible no. Adicionalmente, un cursor puede ser asensible, en cuyo caso el SGBD

intentará, en la medida de lo posible, aplicar los cambios como si fuera sensible.

WITH HOLD

Por norma general los cursores son cerrados automáticamente al final de una transacción,

es decir, cuando se ejecuta un COMMIT o un ROLLBACK, o bien cuando se da un cierre

implícito de la transacción. Este comportamiento puede ser cambiado si el cursor es

declarado utilizando la cláusula WITH HOLD (por defecto cualquier cursor será WITHOUT

HOLD). Un cursor declarado con esta cláusula se mantiene abierto tras un COMMIT y se

cierra después de un ROLLBACK, aunque algunos SGBD se desvían de este

comportamiento estándar y mantienen abierto estos cursores después de un ROLLBACK.

DECLARE cursor_name CURSOR WITH HOLD FOR SELECT... FROM...

Cuando se ejecuta un COMMIT, el cursor WITH HOLD se posiciona antes de la siguiente

fila o registro. Por lo tanto, una operación UPDATE o DELETE posicionada sólo funcionará

después de haber realizado primero un FETCH en la misma transacción.

Page 14: DiazEnriquezAlanDeJesus Investigacion U3

14

Tomese nota de que JDBC define los cursores como WITH HOLD por defecto. Esto se hace

porque JDBC activa la opción de auto-commit por defecto. Debido a la sobrecarga habitual

relacionada con el auto-commit y los cursores WITH HOLD, ambos deberían estar

explícitamente desactivados en el nivel de conexión.

Sentencias Update/Delete posicionadas

Los cursores no sólo pueden ser utilizados para extraer información de la base de datos a

una aplicación, sino que también sirven para identificar una fila a modificar o borrar en

una tabla. El estándar SQL:2003 define para tal fin las sentencias posicionadas Update y

Delete . Estas sentencias no utilizan una cláusula WHERE normal (con predicados de

condición). En cambio, el cursor identifica la fila, para lo cual debe ser abierto y posicionado

en la misma utilizando la sentencia FETCH .

UPDATE table_name

SET ...

WHERE CURRENT OF cursor_name

DELETE

FROM table_name

WHERE CURRENT OF cursor_name

El cursor debe operar sobre un set de resultados que sea modificable para que una

sentencia posicionada UPDATE o DELETE pueda ejecutarse con éxito. En caso contrario,

el SGBD no sabría como aplicar los cambios en los datos a las tablas subyacentes referidas

en el cursor.

Cursores en transacciones distribuidas

Usar cursores en transacciones distribuidas (entornos X/open XA), que son controladas

utilizando un monitor de transacciones, no es diferente que usar cursores en transacciones

no distribuidas.

Aun así, se debe prestar atención al usar cursores WITH HOLD. Las conexiones pueden

ser usadas por diferentes aplicaciones. Por lo tanto, una vez una transacción ha sido

confirmada y ha terminado, una transacción subsecuente (que fuera de otra aplicación)

podría heredar cursores WITH HOLD ya existentes. Este es un punto que los

programadores de aplicaciones deben tener en cuenta.

Page 15: DiazEnriquezAlanDeJesus Investigacion U3

15

3.1.3. – Creación de funciones

En este tema se describe cómo crear una función definida por el usuario en SQL Server

mediante Transact-SQL.

En este tema

Antes de empezar:

Limitaciones y restricciones

Seguridad

Para crear una función definida por el usuario:

Crear una función escalar

Crear una función con valores de tabla

Antes de empezar

Limitaciones y restricciones

Las funciones definidas por el usuario no se pueden utilizar para realizar acciones

que modifican el estado de la base de datos.

Las funciones definidas por el usuario no pueden tener una cláusula OUTPUT INTO

que tenga una tabla como destino.

Las funciones definidas por el usuario no pueden devolver varios conjuntos de

resultados.Utilice un procedimiento almacenado si necesita devolver varios

conjuntos de resultados.

El control de errores está restringido en una función definida por el usuario.Una UDF

no admite TRY…CATCH, @ERROR o RAISERROR.

Las funciones definidas por el usuario no pueden llamar a un procedimiento

almacenado, pero pueden llamar a un procedimiento almacenado extendido.

Las funciones definidas por el usuario no pueden utilizar tablas temporales o SQL

dinámicas.Se permiten las variables de tabla.

Las instrucciones SET no se permiten en una función definida por el usuario.

No se admite la cláusula FOR XML

Las funciones definidas por el usuario se pueden anidar; es decir, una función

definida por el usuario puede llamar a otra.El nivel de anidamiento aumenta cuando

se empieza a ejecutar la función llamada y disminuye cuando se termina de ejecutar

la función llamada.Las funciones definidas por el usuario se pueden anidar hasta un

máximo de 32 niveles.Si se superan los niveles máximos de anidamiento, la cadena

completa de funciones de llamada produce un error.Cualquier referencia a código

administrado desde una función Transact-SQL definida por el usuario cuenta como

uno de los 32 niveles de anidamiento.Los métodos invocados desde el código

administrado no cuentan para este límite.

Las siguientes instrucciones de Service Broker no se pueden incluir en la definición

de una función Transact-SQL definida por el usuario:

o EMPEZAR CONVERSACIÓN DE DIÁLOGO

o FINALIZAR CONVERSACIÓN

Page 16: DiazEnriquezAlanDeJesus Investigacion U3

16

o GET CONVERSATION GROUP

o MOVE CONVERSATION

o RECEIVE

o SEND

Seguridad

Permisos

Se requiere el permiso CREATE FUNCTION en la base de datos y el permiso ALTER en el

esquema en el que se va a crear la función. Si la función específica un tipo definido por el

usuario, requiere el permiso EXECUTE para ese tipo.

Funciones escalares

En el ejemplo siguiente se crea una función escalar de varias instrucciones en la base de

datos AdventureWorks2012.La función toma un valor de entrada, ProductID, y devuelve un

valor de devolución único, la cantidad agregada del producto especificado en el inventario.

IF OBJECT_ID (N'dbo.ufnGetInventoryStock', N'FN') IS NOT NULL

DROP FUNCTION ufnGetInventoryStock;

GO

CREATE FUNCTION dbo.ufnGetInventoryStock(@ProductID int)

RETURNS int

AS

-- Returns the stock level for the product.

BEGIN

DECLARE @ret int;

SELECT @ret = SUM(p.Quantity)

FROM Production.ProductInventory p

WHERE p.ProductID = @ProductID

AND p.LocationID = '6';

IF (@ret IS NULL)

SET @ret = 0;

RETURN @ret;

END;

GO

En el ejemplo siguiente se utiliza la función ufnGetInventoryStock para devolver la cantidad

de inventario actual de aquellos productos que tienen un ProductModelID entre 75 y 80.

SELECT ProductModelID, Name, dbo.ufnGetInventoryStock(ProductID)AS CurrentSupply

FROM Production.Product

WHERE ProductModelID BETWEEN 75 and 80;

Page 17: DiazEnriquezAlanDeJesus Investigacion U3

17

Funciones con valores de tabla

En el ejemplo siguiente se crea una función insertada con valores de tabla en la base de

datos AdventureWorks2012.La función toma un parámetro de entrada, Id. de cliente

(almacén), y devuelve las columnasProductID, Name, y el agregado de las ventas del año

hasta la fecha como YTD Total para cada producto vendido en el almacén.

IF OBJECT_ID (N'Sales.ufn_SalesByStore', N'IF') IS NOT NULL

DROP FUNCTION Sales.ufn_SalesByStore;

GO

CREATE FUNCTION Sales.ufn_SalesByStore (@storeid int)

RETURNS TABLE

AS

RETURN

(

SELECT P.ProductID, P.Name, SUM(SD.LineTotal) AS 'Total'

FROM Production.Product AS P

JOIN Sales.SalesOrderDetail AS SD ON SD.ProductID = P.ProductID

JOIN Sales.SalesOrderHeader AS SH ON SH.SalesOrderID = SD.SalesOrderID

JOIN Sales.Customer AS C ON SH.CustomerID = C.CustomerID

WHERE C.StoreID = @storeid

GROUP BY P.ProductID, P.Name

);

En el ejemplo siguiente se invoca la función y se especifica el identificador de cliente 602.

SELECT * FROM Sales.ufn_SalesByStore (602);

En el ejemplo siguiente se crea una función con valores de tabla en la base de datos

AdventureWorks2012.La función toma un único parámetro de entrada, EmployeeID, y

devuelve una lista de todos los empleados que dependen directa o indirectamente del

empleado especificado.La función se invoca luego especificando el empleado ID 109.

IF OBJECT_ID (N'dbo.ufn_FindReports', N'TF') IS NOT NULL

DROP FUNCTION dbo.ufn_FindReports;

GO

CREATE FUNCTION dbo.ufn_FindReports (@InEmpID INTEGER)

RETURNS @retFindReports TABLE

(

EmployeeID int primary key NOT NULL,

FirstName nvarchar(255) NOT NULL,

LastName nvarchar(255) NOT NULL,

JobTitle nvarchar(50) NOT NULL,

RecursionLevel int NOT NULL

)

--Returns a result set that lists all the employees who report to the

Page 18: DiazEnriquezAlanDeJesus Investigacion U3

18

--specific employee directly or indirectly.*/

AS

BEGIN

WITH EMP_cte(EmployeeID, OrganizationNode, FirstName, LastName, JobTitle,

RecursionLevel) -- CTE name and columns

AS (

SELECT e.BusinessEntityID, e.OrganizationNode, p.FirstName, p.LastName,

e.JobTitle, 0 -- Get the initial list of Employees for Manager n

FROM HumanResources.Employee e

INNER JOIN Person.Person p

ON p.BusinessEntityID = e.BusinessEntityID

WHERE e.BusinessEntityID = @InEmpID

UNION ALL

SELECT e.BusinessEntityID, e.OrganizationNode, p.FirstName, p.LastName,

e.JobTitle, RecursionLevel + 1 -- Join recursive member to anchor

FROM HumanResources.Employee e

INNER JOIN EMP_cte

ON e.OrganizationNode.GetAncestor(1) = EMP_cte.OrganizationNode

INNER JOIN Person.Person p

ON p.BusinessEntityID = e.BusinessEntityID

)

-- copy the required columns to the result of the function

INSERT @retFindReports

SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel

FROM EMP_cte

RETURN

END;

GO

-- Example invocation

SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel

FROM dbo.ufn_FindReports(1);

Page 19: DiazEnriquezAlanDeJesus Investigacion U3

19

3.1.4.- Elementos de un lenguaje de programación (Transact – SQL, PL/SQL, etc.)

Es un lenguaje para la creación de sitios web dinámicos, acrónimo de Java Server Pages.

Está orientado a desarrollar páginas web en Java. JSP es un lenguaje multiplataforma.

JSP fue desarrollado por Sun Microsystems. Comparte ventajas similares a las de

ASP.NET, desarrollado para la creación de aplicaciones web potentes. Posee un motor de

páginas basado en los servlets de Java. Para su funcionamiento se necesita tener instalado

un servidor Tomcat.

Características:

Código separado de la lógica del programa.

Las páginas son compiladas en la primera petición.

Permite separar la parte dinámica de la estática en las páginas web.

Los archivos se encuentran con la extensión (jsp).

El código JSP puede ser incrustado en código HTML.

Los elementos que pueden ser insertados en las páginas JSP son los siguientes: Código:

se puede incrustar código “Java”.

Directivas: permite controlar parámetros del servlet.

Acciones: permite alterar el flujo normal de ejecución de una página.

Ventajas:

Ejecución rápida del servlets.

Crear páginas del lado del servidor.

Multiplataforma.

Código bien estructurado.

Integridad con los módulos de Java.

La parte dinámica está escrita en Java.

Desventajas:

Complejidad de aprendizaje.

PERL

Perl (Practical Extraction and Report Language) es un lenguaje de programación

desarrollado por Larry Wall (lwall at netlabs.com) inspirado en otras herramientas de UNIX

como son: sed, grep, awk, c-shell, para la administración de tareas propias de sistemas

UNIX. No establece ninguna filosofía de programación concreta. No se puede decir que sea

orientado a objetos, modular o estructurado aunque soporta directamente todos estos

paradigmas; su punto fuerte son las labores de procesamiento de textos y archivos.

Lenguaje de programación basado en scripts portable a casi cualquier plataforma. Es muy

utilizado para escribir CGIs. Uno de sus elementos más potentes son las expresiones

Page 20: DiazEnriquezAlanDeJesus Investigacion U3

20

regulares, que a partir de su versión en Perl han sido adoptadas por otros lenguajes y

plataformas como .NET o Javascript.

Ventajas

Es un buen lenguaje “pegamento”. Se pueden juntar varios programas de una forma

sencilla para alcanzar una meta determinada. Los usuarios de Windows agradecerán

esta propiedad ya que normalmente adolecen de un buen lenguaje tipo “script”.

Es relativamente rápido para un lenguaje tipo “script”.

Está disponible en múltiples plataformas y sistemas operativos (UNIX, Linux y Windows).

Un programa que se escriba teniendo en cuenta la compatibilidad puede ser escrito en

una plataforma y ejecutado en otra.

El desarrollo de aplicaciones es muy rápido.

Hay una colección enorme de módulos que pueden ser incorporados a cualquier “script”

de Perl. Están disponibles en el CPAN (“Comprehensive Perl Archive Network”). En

particular existe una extensión para cálculo numérico denominada PDL.

Perl es gratuito. Mucho más que eso, es “Software Libre”. Esto quiere decir que el código

fuente está disponible para que cualquiera lo pueda ver o modificar, y lo que es más

importante, siempre lo estará. Aunque nunca pretendas cambiar el código, es importante

disponer de la posibilidad de hacerlo, ya que siempre se podrá contratar a una tercera

persona para que lo modifique en el caso de que haya un error, y debería ser posible

solucionarlo.

Le otorga al programador mucha libertad para que haga el programa como quiera. Tal

como dice el eslogan de Perl “Hay más de una forma de hacerlo”.

Desventajas

Es lento para algunas aplicaciones, como programación a bajo nivel, escribiendo un

“driver” para una aplicación o corriendo modelos numéricos de cálculo intensivo. Si bien

se pueden insertar subrutinas FORTRAN o C en Perl, teniendo lo mejor de los dos

mundos, pero con algo más de complejidad.

La libertad que se le otorga al programador puede significar que el resultado sea un

programa ilegible. Si no se escribe con cuidado puede llegar a ser difícil de leer. De hecho

hay un concurso de Perl ofuscado.

Perl es un lenguaje interpretado. Este tema no es tan crítico como suena, los programas

Perl no correrán mucho más rápidos cuando se compilen, la única ventaja está en la

desaparición de la fase inicial de compilación al correr la aplicación.

Utiliza muchos recursos de computó. Esto significa que no es tan ligero como un

programa en C, pero en la práctica es ligero comparado con la potencia de

procesamiento de las computadoras actuales.

Page 21: DiazEnriquezAlanDeJesus Investigacion U3

21

PHP

PHP es el acrónimo de Hipertext Preprocesor. Es un lenguaje de programación del lado del

servidor gratuito e independiente de plataforma, rápido, con una gran librería de funciones

y mucha documentación. Fue creado originalmente en 1994 por Rasmus Lerdorf, pero

como PHP está desarrollado en política de código abierto, a lo largo de su historia ha tenido

muchas contribuciones de otros desarrolladores.

El cliente solamente recibe una página con el código HTML resultante de la ejecución de la

PHP. Como la página resultante contiene únicamente código HTML, es compatible con

todos los navegadores.

Ventajas:

Muy fácil de aprender.

Se caracteriza por ser un lenguaje muy rápido.

Soporta en cierta medida la orientación a objeto. Clases y herencia.

Es un lenguaje multiplataforma: Linux, Windows, entre otros.

Capacidad de conexión con la mayoría de los manejadores de base de datos: MysSQL,

PostgreSQL, Oracle, MS SQL Server, entre otras.

Capacidad de expandir su potencial utilizando módulos.

Posee documentación en su página oficial la cual incluye descripción y ejemplos de cada

una de sus funciones.

Es libre, por lo que se presenta como una alternativa de fácil acceso para todos.

Incluye gran cantidad de funciones.

No requiere definición de tipos de variables ni manejo detallado del bajo nivel.

Desventajas:

Todo el trabajo lo realiza el servidor y no delega al cliente. Por tanto puede ser más

ineficiente a medida que las solicitudes aumenten de número.

La legibilidad del código puede verse afectada al mezclar sentencias HTML y PHP.

La programación orientada a objetos es aún muy deficiente para aplicaciones grandes.

Dificulta la modularización.

Dificulta la organización por capas de la aplicación.

Seguridad:

PHP es un poderoso lenguaje e intérprete, ya sea incluido como parte de un servidor web

en forma de módulo o ejecutado como un binario CGI separado, es capaz de acceder a

archivos, ejecutar comandos y abrir conexiones de red en el servidor. Estas propiedades

hacen que cualquier cosa que sea ejecutada en un servidor web sea insegura por

naturaleza.

Page 22: DiazEnriquezAlanDeJesus Investigacion U3

22

PHP está diseñado específicamente para ser un lenguaje más seguro para escribir

programas CGI que Perl o C, y con la selección correcta de opciones de configuración en

tiempos de compilación y ejecución, y siguiendo algunas prácticas correctas de

programación.

3.1.5.- Disparadores (Triggers)

Un disparador define una acción que la base de datos debe llevar a cabo cuando se produce

algún suceso relacionado con la misma. Los disparadores (triggers) pueden utilizarse para

completar la integridad referencial, también para imponer reglas de negocio complejas o

para auditar cambios en los datos. El código contenido en un disparador,

denominado cuerpo del disparador, está formado por bloques PL/SQL. La ejecución de

disparadores es transparente al usuario.

Para crear un disparador (trigger) en una tabla, el usuario con el que accedamos a Oracle

deberá ser propietario de la misma, teniendo así el privilegio ALTER para la tabla ó ALTER

ANY TABLE. Además, dicho usuario, debe disponer del privilegio CREATE TRIGGER.

Existen varios tipos de disparadores, dependiendo del tipo de transacción de disparo y el

nivel en el que se ejecuta el disparador (trigger):

1.- Disparadores de nivel de fila: se ejecutan una vez para cada fila afectada por una

instrucción DML. Los disparadores de nivel de fila se crean utilizando la cláusula for each

row en el comando create trigger.

2.- Disparadores de nivel de instrucción: se ejecutan una vez para cada intrucción DML.

Por ejemplo, si una única intrucción INSERT inserta 500 filas en una tabla un disparador de

nivel de instrucción para dicha tabla sólo se ejecutará una vez. Los disparadores de nivel

de instrucción son el tipo predeterminado que se crea con el comando create trigger.

3.- Disparadores Before y After: puesto que los disparadores son ejecutados por sucesos,

puede establecerse que se produzcan inmediatamente antes (before) o después (after) de

dichos sucesos.

4.- Disparadores Instead Of: puede utilizar INSTEAD OF para indicar a Oracle lo que tiene

que hacer en lugar de realizar las acciones que invoca el disparador. Por ejemplo, podría

usar un disparador INSTEAD OF en una vista para gestionar las inserciones en una tabla

o para actualizar múltiples tablas que son parte de una vista.

5.- Disparadores de esquema: puede crear disparadores sobre operaciones en el nivel de

esquema tales como create table, alter table, drop table, audit, rename, truncate y revoke.

Puede incluso crear disparadores para impedir que los usuarios eliminen sus propias tablas.

En su mayor parte, los disparadores de nivel de esquema proporcionan dos capacidades:

impedir operaciones DDL y proporcionar una seguridad adicional que controle las

operaciones DDL cuando éstar se producen.

Page 23: DiazEnriquezAlanDeJesus Investigacion U3

23

6.- Disparadores en nivel de base de datos: puede crear disparadores que se activen al

producirse sucesos de la base de datos, incluyendo errores, inicios de sesión, conexiones

y desconexiones. Puede utilizar este tipo de disparador para automatizar el mantenimiento

de la base de datos o las acciones de auditoría.

3.1.6.- Procedimientos almacenados (Stored Procedures)

Un procedimiento almacenado (stored procedure en inglés) es

un programa (o procedimiento) almacenado físicamente en una base de datos. Su

implementación varía de un gestor de bases de datos a otro. La ventaja de un

procedimiento almacenado es que al ser ejecutado, en respuesta a una petición de

usuario, es ejecutado directamente en el motor de bases de datos, el cual usualmente corre

en un servidor separado. Como tal, posee acceso directo a los datos que necesita manipular

y sólo necesita enviar sus resultados de regreso al usuario, deshaciéndose de la sobrecarga

resultante de comunicar grandes cantidades de datos salientes y entrantes.

Usos típicos para procedimientos almacenados incluyen la validación de datos siendo

integrados a la estructura de base de datos (los procedimientos almacenados utilizados

para este propósito a menudo son llamados disparadores; triggers en inglés), o encapsular

un proceso grande y complejo. El último ejemplo generalmente ejecutará más rápido como

un procedimiento almacenado que de haber sido implementado como, por ejemplo, un

programa corriendo en el sistema cliente y comunicándose con la base de datos mediante

el envío de consultas SQL y recibiendo sus resultados.

Los procedimientos pueden ser ventajosos: Cuando una base de datos es manipulada

desde muchos programas externos. Al incluir la lógica de la aplicación en la base de datos

utilizando procedimientos almacenados, la necesidad de embeber la misma lógica en todos

los programas que acceden a los datos es reducida. Esto puede simplificar la creación y,

particularmente, el mantenimiento de los programas involucrados.

Podemos ver un claro ejemplo de estos procedimientos cuando requerimos realizar una

misma operación en un servidor dentro de algunas o todas las bases de datos y a la vez

dentro de todas o algunas de las tablas de las bases de datos del mismo. Para ello podemos

utilizar a los Procedimientos almacenados auto creable que es una forma de generar ciclos

redundantes a través de los procedimientos almacenados.

Implementación

Estos procedimientos, se usan a menudo, pero no siempre, para realizar

consultas SQL sobre los objetos de la base de datos de una manera abstracta, desde el

punto de vista del cliente de la aplicación. Un procedimiento almacenado permite agrupar

en forma exclusiva parte de algo específico que se desee realizar o, mejor dicho, el SQL

apropiado para dicha acción.

Usos

Page 24: DiazEnriquezAlanDeJesus Investigacion U3

24

Los usos 'típicos' de los procedimientos almacenados se aplican en la validación de

datos, integrados dentro de la estructura del banco de datos. Los procedimientos

almacenados usados con tal propósito se llaman comúnmente disparadores, o triggers.

Otro uso común es la 'encapsulación' de un API para un proceso complejo o grande que

podría requerir la 'ejecución' de varias consultas SQL, tales como la manipulación de un

conjunto de datos enorme para producir un resultado resumido.

También pueden ser usados para el control de gestión de operaciones, y ejecutar

procedimientos almacenados dentro de una transacción de tal manera que las

transacciones sean efectivamente transparentes para ellos.

Ventajas

La ventaja de un procedimiento almacenado, en respuesta a una petición de usuario, está

directamente bajo el control del motor del gestor de bases de datos, que corre generalmente

en un servidor distinto del servidor web, aumentando con ello la rapidez de procesamiento

de las peticiones del usuario. El servidor de la base de datos tiene acceso directo a los

datos necesarios para manipular y sólo necesita enviar el resultado final al usuario. Los

procedimientos almacenados pueden permitir que la lógica del negocio se encuentre como

un API en la base de datos, que pueden simplificar la gestión de datos y reducir la necesidad

de codificar la lógica en el resto de los programas cliente. Esto puede reducir la probabilidad

de que los datos se corrompan por el uso de programas clientes defectuosos o erróneos.

De este modo, el motor de base de datos puede asegurar la integridad de los datos y su

consistencia con la ayuda de procedimientos almacenados. Algunos afirman que las bases

de datos deben ser utilizadas para el almacenamiento de datos solamente, y que la lógica

de negocio sólo debería aplicarse en la capa de negocio de código, a través de aplicaciones

cliente que deban acceder a los datos. Sin embargo, el uso de procedimientos almacenados

no se opone a la utilización de una capa de negocio.

Procedimientos almacenados en MySQL

Desde MySQL 5 los procedimientos almacenados empezaron a ser soportados, como suele

suceder en MySQL las sentencias se ejecutan luego de escribir el signo punto y coma (;),

por esta razón antes de escribir el procedimiento almacenado la función del punto y coma

se asigna a otros caracteres usando la sentencia DELIMITER seguida de un carácter tal

como |, de esta manera el procedimiento puede ser escrito usando los punto y comas sin

que se ejecute mientras se escribe; después de escrito el procedimiento, se escribe

nuevamente la sentencia DELIMITER ; para asignar al punto y coma su función habitual.

El siguiente es un ejemplo de procedimiento almacenado en MySQL:

DELIMITER |

CREATE PROCEDURE autos(IN velocidad int,IN marca varchar(50))

Page 25: DiazEnriquezAlanDeJesus Investigacion U3

25

BEGIN

IF velocidad < 120 then

INSERT INTO familiares VALUES(velocidad,marca);

ELSE

INSERT INTO deportivos VALUES(velocidad,marca);

END IF;

END;

|

3.2.- Programación del lado del cliente

En esta sección analizaremos algunos de los problemas que se presentan al trabajar con

SQL embebido. Este análisis no pretende ser detallado sino más bien una reseña básica

de los problemas y sus soluciones en el estandard.

Compilación

Al trabajar con SQL embebido en C escribimos un programa con instrucciones en dos

lenguajes distintos: C y SQL. Por lo tanto, será necesario compilar los programas de una

forma diferente cuando trabajamos con SQL embebido en C que cuando trabajamos solo

con C.

Todas las sentencias SQL deberán comenzar con las palabras EXEC SQL y en vez de

ejecutar el compilador de C, ejecutamos el precompilador de SQL embebido. En el RDBMS

PostgreSQL, el precompilador se llama ecpg .

La sintaxis del comando ecpg correspondiente al precompilador es la siguiente:

ecgp [opciones] archivos

Por detalle sobre las opciones consultar la documentacion del comando

Ejemplo compilacion.

Para compilar el archivo prog1.pgc creando un ejecutable con nombre prog1 escribimos la

siguiente secuencia de comandos:

ecpg prog1.pgc

cc -I/usr/local/pgsql/include -c prog1.c

cc -o prog1 prog1.o -L/usr/local/pgsql/lib -lecpg

Page 26: DiazEnriquezAlanDeJesus Investigacion U3

26

En el primer paso estamos precompilando el código que contiene las sentencias SQL

embebidas en C.

El paso siguiente crea el código objeto (para lo cual necesito los archivos de encabezado

de ECPG que se encuentran en usr/local/pgsql/include

El último paso genera el ejecutable, para lo cual precisa linkear con la biblioteca libecpg

ubicada en /usr/local/pgsql/lib

Ejemplo de código

A continuación presentamos un ejemplo del código C con SQL embebido que corresponde

al programa pepe.ec.

(1) #include <stdio.h>

(2) EXEC SQL include sqlca;

(3) main()

{

(4) EXEC SQL BEGIN DECLARE SECTION;

(5) int cant;

(6) EXEC SQL END DECLARE SECTION;

(7) EXEC SQL connect to 'dbventas';

(8) EXEC SQL

select count(*) into :cant

from cliente;

(9) printf(``La cantidad de tuplas de la tabla Cliente es %d \n'', cant);

}

Comunicación con el DBMS

Comencemos a observar más detenidamente el programa anterior. En particular las líneas

(4) a (6).

Estas instrucciones declaran una variable de comunicación entre el DBMS y el programa.

Siempre que se utilice esa variable en una instrucción SQL se debe escribir ``:'' delante del

nombre de la variable para que el precompilador interprete el símbolo como una variable

de programa. Si se utiliza en cualquier instrucción de C no se debe escribir más que el

nombre de la variable tal cual fue declarado.

Page 27: DiazEnriquezAlanDeJesus Investigacion U3

27

Podemos utilizar la declaración DECLARE SECTION, para declarar más de una variable.

EXEC SQL BEGIN DECLARE SECTION;

int hostint;

long hostlong;

double hostdbl;

char hostarr[80];

EXEC SQL END DECLARE SECTION;

Finalmente, hacemos notar que se pueden escribir tantas DECLARE SECTION como sean

convenientes.

Correspondencia entre tipos de C y tipos de SQL

Para utilizar correctamente las variables de comunicación, es necesario conocer las

correspondencias entre los tipos de C y los tipos de SQL. Dicha correspondencia es

presentada en tabla siguiente:

SQL Lenguaje C

CHAR(n) char[n + 1]

CHARACTER(n)

SMALLINT short int

INTEGER long int

INT

DECIMAL dec_t o struct decimal

DEC

NUMERIC

SMALLFLOAT float

Page 28: DiazEnriquezAlanDeJesus Investigacion U3

28

REAL

FLOAT double

DOUBLE PRECISION

MONEY dec_t o struct decimal

SERIAL long int

DATE long int

DATETIME dtime_t o struct dtime

INTERVAL intrvl_t o struct intrvl

La declaración de las variables en los programas tales como pepe.ec arriba, se realiza

según los tipos de C.

Los tipos dec_t, dtime_t e intrvl_t están definidos en diferentes .h que pueden ser incluídos

en nuestros programas mediante la directiva:

EXEC SQL include nomarch

También podemos definir estructuras y tipos del usuarios con typedef. Al utilizar variables

de dichos tipos, podemos hacer trabajar tanto con las componentes como con las

estructuras como un todo. En realidad, siempre que aparece una variable de tipo estructura,

el precompilador expande a la lista de campos correspondientes. Dada la siguiente

declaración:

EXEC SQL struct cliente_t {

int nro_cli;

char nombre[32];

char apellido[32];

} tupla_cli;

La instrucción:

EXEC SQL insert :tupla_cli into cliente;

es equivalente a:

EXEC SQL insert into cliente

values ( :tupla_cli.nro_cli, :tupla_cli.nombre, :tupla_cli.apellido);

Page 29: DiazEnriquezAlanDeJesus Investigacion U3

29

Por último, cabe notar que Informix las palabras claves ``EXEC SQL'' se pueden substituir

por ``$''.

Impedance Mistmatch

SQL es un lenguaje para manipulación de conjuntos de tuplas, donde cada tupla es similar

a un registro (record o struct) de un lenguaje tradicional.

En general, C maneja datos individuales y no conjuntos. Para manejar conjuntos en C

tenemos que realizar alguna forma de iteración que permita manejar datos individuales.

Debido a la diferencia de granularidad con que trabajan ambos lenguajes, es necesario que

el precompilador provea un mecanismo para resolver este problema. Para ello se introduce

la noción de cursor.

Un cursor es básicamente un puntero a un área de memoria donde está almacenado el

resultado de una consulta. Sin embargo, no es un puntero común del lenguaje de

programación (en nuestro caso de C). Debe manipularse con un conjunto de operaciones

especiales provistas. Algunas de estas operaciones son: Declare, Open, Fetch. A

continuación damos una breve explicación del significado de cada operación.

Declare. Declara un cursor para poder acceder al resultado de una instrucción SQL. Por

ejemplo,

EXEC SQL declare c_tabla cursor for

select *

from tabla;

Open. Ejecuta la consulta asociada al cursor y hace accesible el resultado por medio del

cursor. El cursor queda posicionado antes de la primera tupla del resultado.Por ejemplo,

EXEC SQL open c_tabla;

Fetch. Posiciona el cursor en la siguiente tupla. Luego de un open, es necesario ejecutar

esta operación para poder acceder a la primera tupla. Por ejemplo,

EXEC SQL fetch c_tabla into :struct_tupla_tabla;

while (sqlca.sqlcode == 0) {

print_struct(struct_tupla_tabla);

EXEC SQL fetch c_tabla into :struct_tupla_tabla;

}

La operación fetch permite posicionarse en cualquier tupla del resultado. Esto se logra

agregando alguna de las siguientes opciones antes del nombre del cursor:

Previous. Posiciona el cursor en la tupla anterior a la tupla que está en este momento.

First. Posiciona el cursor en al primer tupla del resultado.

Last. Posiciona el cursor en la última tupla accesible.

Relative n. Posiciona el cursor en la tupla n a partir de su posición actual. Si n es negativo,

entonces estamos especificando una posición anterior a la de la tupla actual.

Page 30: DiazEnriquezAlanDeJesus Investigacion U3

30

Absolute n. Posiciona el cursor en la tupla de ordinal n del resultado.

La Captura de Mensajes del DBMS

Después de la ejecución de una instrucción SQL, podemos informarnos del estado de la

ejecución o bien por un test explícito utilizando la estructura SQLCA (SQL Communication

Area) o bien por un test implicito utilizando la instrucción WHENEVER. Estas dos formas

de manejo de errores son descriptas brevemente a continuación.

La Estructura SQLCA

En el ejemplo de la operación fetch de la sección 2.4, se utiliza la siguiente instrucción:

while (sqlca.sqlcode == 0)

La variable de estructura llamada sqlca es el mecanismo que se utiliza para recibir

mensajes del DBMS. La estructura se encuentra declarada en el archivo sqlca.h y debe

ser incluída en todos los programas en los que queremos controlar el resultado de la

ejecución de operaciones por parte del DBMS. Un ejemplo de esta inclusión se encuentra

en la línea (2) del programapepe.ec de la sección 2.1.

Si la última operación que se envió ejecutar al DBMS se terminó sin ninguna característica

especial, entonces el valor de la variable sqlca.sqlcode es 0. En caso de que esa ejecución

genere un error, el valor de la variable sqlca.sqlcode será negativo y corresponde a un

código de error. El valor de la variable sqlca.sqlerrm, corresponde a un string que

representa el mensaje de error que emite el DBMS. Cuando el DBMS ejecuta una

instrucción select sobre una tabla que no tiene tuplas o una instrucción fetch que pretende

``pasarse'' de la última tupla, el valor de la variable sqlca.sqlcode es aquel de la

constante SQLNOTFOUND . SQLNOTFOUND es una constante definida en el

archivo sqlca.h que debe ser incluído en caso de utilizar dicha constante.

La variable de estructura sqlca tiene más campos que los presentados aquí. Esos campos

están destinados a recuperar datos tales como el último identificador de tupla generado o

determinar exactamente que ``warning'' fue el que se generó por parte del DBMS. Se

aconseja consultar el manual de SQL embebido provisto con el DBMS en caso de necesitar

estos campos.

La Instrucción WHENEVER

La instrucción whenever funciona como un manejador de excepciones primitivo. En

cualquier parte de nuestro programa podemos utilizar la instrucción whenever.

En lugar de sqlerror, otras declaraciones son posibles tales como not

found o sqlwarning. not found especifica que cuando se ejecuta un select sobre una tabla

sin tuplas o un fetch que pretende referirse a una tupla que está después de la última tupla

del resultado, se continuará la ejecución en la instrucción identificada por la etiqueta.

Con sqlwarning, se continuará la ejecución en la instrucción identificada por la etiqueta

cuando se genere un ``warning''.

Page 31: DiazEnriquezAlanDeJesus Investigacion U3

31

Una vez que se ejecuta el whenever-goto, éste queda activo hasta que se ejecute

otro whenever-goto con la misma condición o bien se ejecute una

instrucción whenever <condición > continue .

Este mecanismo de manejo de errores tiene sus problemas. Al trabajar con un lenguaje

estructurado, no se puede salir de una función usando un goto. Por ello, es aconsejable

elegir alguna de las siguientes guías:

1. Redefinir la etiqueta de un whenever en cada función que contenga instrucciones

SQL que puedan activarlo.

2. Definir un whenever con su etiqueta correspondiente en cada función que contenga

instrucciones SQL que pueda activar el whenever .

IMPORTANTE !. La primera instrucción en un trozo de instrucciones identificado por una

etiqueta, debe ser un whenever-continue con la misma condición que activó la etiqueta.

De lo contrario, si hay instrucciones SQL en el trozo de instrucciones identificado por la

etiqueta que son capaces de generar las misma condición que nos llevó hasta aquí, el

programa entrará en loop.

3.2.2 JDBC con Java

Java Database Connectivity, más conocida por sus siglas JDBC , es una API que permite

la ejecución de operaciones sobre bases de datos desde el lenguaje de programación Java,

independientemente del sistema operativo donde se ejecute o de la base de datos a la cual

se accede, utilizando el dialecto SQL del modelo de base de datos que se utilice.

El API JDBC se presenta como una colección de interfaces Java y métodos de gestión de

manejadores de conexión hacia cada modelo específico de base de datos. Un manejador

de conexiones hacia un modelo de base de datos en particular es un conjunto de clases

que implementan las interfaces Java y que utilizan los métodos de registro para declarar

los tipos de localizadores a base de datos (URL) que pueden manejar. Para utilizar una

base de datos particular, el usuario ejecuta su programa junto con la biblioteca de conexión

apropiada al modelo de su base de datos, y accede a ella estableciendo una conexión; para

ello provee el localizador a la base de datos y los parámetros de conexión específicos.

A partir de allí puede realizar cualquier tipo de tarea con la base de datos a la que tenga

permiso: consulta, actualización, creación, modificación y borrado de tablas, ejecución

de procedimientos almacenados en la base de datos, etc.

Conclusión

Page 32: DiazEnriquezAlanDeJesus Investigacion U3

32

Toda base de datos debe tener una serie de características tales como seguridad (sólo

personas autorizadas podrán acceder a la información), integridad (la información se

mantendrá sin pérdidas de datos), e independencia (esta característica es fundamental ya

que una buena base de datos debería ser independiente del sistema operativo o programas

que interactúen con ella). Hay más características que debe reunir una base de datos como

ser consistente (es decir, que la información se guarde sin duplicidades y de manera

correcta). Y finalmente, las bases de datos actuales permiten el manejo correcto de

transacciones. Esto significa que se ha de permitir efectuar varias operaciones sobre la

base de datos pero tratadas a modo de una sola. Es decir, si en el conjunto de las

operaciones de una transacción se produce un error, entonces se deshacen todas las

operaciones realizadas anteriormente y se cancela la transacción.

Fuentes

Page 33: DiazEnriquezAlanDeJesus Investigacion U3

33

Vistas Con Base De Datos

https://yoalo.wikispaces.com/2.1.4+Creacion+Vistas+Base+de+Datos+viewElProcesoUnifi

cadodeSoftware.RogerPressman.

Creación de funciones

https://msdn.microsoft.com/es-es/library/ms191320(v=sql.120).aspx

Procedimientos Almacenados

https://es.wikipedia.org/wiki/Procedimiento_almacenado

JDBC

http://cidecame.uaeh.edu.mx/lcc/mapa/PROYECTO/libro21/432_conectores_de_base_de

_datos_para_java_jdbc.html