1 sql en entorno de programación. 2 motivación: sql interactivo vs. no interactivo hasta la fecha...

57
1 SQL en Entorno de Programación

Upload: prudencio-banos

Post on 28-Jan-2016

224 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

1

SQL en Entorno de Programación

Page 2: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

2

Motivación: SQL Interactivo vs. No Interactivo

• Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos en “psql” o “pgaccess” las ordenes que deseamos ejecutar. Esto se conoce como SQL Interactivo.

• SQL interactivo es ideal para:– Definir la estructura de la base de datos– Probar consultas– realizar prototipos

• El SQL interactivo no es una buena solución para la mayoría de las aplicaciones “reales” que requieren un interfaz con un usuario sin conocimientos de SQL. Para las cuales se necesita, además de SQL, un lenguaje de programación de alto nivel.

Page 3: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

3

Más motivación

• (2,5 puntos) Diseñar razonadamente una base de datos (diagrama entidad...no redundante…

• (2,5 puntos) Dar razonadamente consultas en el álgebra relacional y en SQL que permitan obtener…

• (2,5 puntos) Dar razonadamente una función en C void f()…

Page 4: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

4

Posibles formas de Conexión con la base de datos

• Embedded SQL• Library (database API): ODBC (database

independent, complex), JDBC (slow),• ...

Page 5: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

5

SQL embebido

• Los comandos SQL deben seguir una sintaxis especial que los "aísla" del resto de las ordenes del programa– EXEC SQL SQL_statement

• Un precompilador se encargará de procesar estas ordenes y trasladarlas a llamadas a una librería (que se encarga de las comunicaciones). ecpg

• Finalmente el compilador nativo compila el programa. gcc

Page 6: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

6

Precompilador SQL

Editor

Precompilador

Compilador

Lincador

Programa “nativo” + SQL embebido

Programa “nativo” + SQL traducido (ecpg)

Código objeto

Librerías nativas

Librerías DDBB

Ejecutable

Page 7: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

7

Un ejemplo rollback and commit

• Preprocesador para C y SQL embebido (ECPG)

#include <stdio.h>/* Esta zona se descibirá más adelante */EXEC SQL BEGIN DECLARE SECTION; int resultado; EXEC SQL END DECLARE SECTION; int main() { EXEC SQL CONNECT TO peliculas; EXEC SQL SELECT (1+1) INTO :resultado;

printf("1+1=%d\n",resultado);return 0;} /* /home/roberto/Docencia/DDBB/SQL-Prog/Prog_2 /*//*ecpg 297.pgc -o 297.c; vi 297.c *//*make -f 297.mak -n*/

Page 8: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

8

Compartir Variables• Es posible compartir variables entre el código SQL y el

nativo. • La definición se realiza usando la sintaxis:

EXEC SQL begin declare section;varchar userid[ 10], password[ 10],

cname[ 15];int cno;EXEC SQL end declare section;

• Declaration section-> variables compartidas por SQL y lenguaje nativo

• ":" se antepone a las variables cuando se usan en SQL

Page 9: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

9

Compartir variables: un ejemplo

• Declaration section-> variables compartidas por SQL y lenguaje nativo

• ":" se antepone a las variables cuando se usan en SQL

EXEC SQL BEGIN DECLARE SECTION; unsigned long num_enrolled; char crs_code; char SQLSTATE [6];EXEC SQL END DECLARE SECTION; ……….EXEC SQL SELECT C.NumEnrolled INTO :num_enrolled FROM CourseCourse AS C WHERE C.CrsCode = :crs_code;

Variablescompartidas

“:” se usa para las variables en SQL

Page 10: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

10

NULL• SQL trata el “valor” NULL de forma muy

especial que no es directamente exportable a otros lenguajes de programación.

• Hay unas variables llamadas “variables indicadoras” que contienen un código que “matiza” los valores devueltos por la base de datos:– 0 el valor de la variable “nativa” es correcto.– -1 el valor de la variable “nativa” debe tratarse como si

fuera NULL. Su valor es irrelevante.– >0 el valor de la variable “nativa” ha sido procesado

(probablemente un casting que ha producido una truncación o redondeo)

null jdbc> wasNull

Page 11: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

12

Ejemplo!!!saltarse clave primaria

#include <stdio.h>//create table pepinillo(id int,color text);//psql peliculasint main(){EXEC SQL BEGIN DECLARE SECTION; char resultado[11]; int resultadoInd;EXEC SQL END DECLARE SECTION;//las variables indicadoras funcionan en las dos direccionesEXEC SQL CONNECT TO peliculas; resultadoInd = -1; strcpy(resultado,"rojo");

EXEC SQL INSERT INTO pepinillo (id,color) VALUES (1,:resultado:resultadoInd);

return 0;}//297b.pgc

Page 12: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

13

Conexión

• Hasta la fecha hemos usado:EXEC SQL CONNECT TO peliculas;

para conectarnos • Obviamente faltan campos para:

– usuario– password– servidor (dirección IP)– puerto…En JDBC hay que especificar siempre la direccion

Page 13: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

14

Ejemplo#include <stdio.h>EXEC SQL INCLUDE sqlca;

EXEC SQL BEGIN DECLARE SECTION; int resultado;EXEC SQL END DECLARE SECTION;int main(){EXEC SQL CONNECT TO peliculas@localhost:5432

USER roberto/pepino;if (sqlca.sqlcode) {printf("%s\n", sqlca.sqlerrm.sqlerrmc); exit(1); }

EXEC SQL SELECT (1+1) INTO :resultado;

printf("1+1=%d\n",resultado);return 0;}

Page 14: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

15

Errores

• Se puede acceder a la base de datos para conocer su estado (¿Ha habido algún error durante la ejecución?EXEC SQL include sqlca;

• El elemento más interesante de la estructura sqlca es sqlcode. El– 0 consulta correcta.– >0 la consulta se ha realizado satisfactoriamente

pero ha ocurrido una excepción (por ejemplo no hay más tuplas disponibles)

– < 0 ha ocurrido un error

Page 15: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

16

Errores #include <stdio.h>EXEC SQL INCLUDE sqlca;EXEC SQL BEGIN DECLARE SECTION; int resultado; EXEC SQL END DECLARE SECTION; int main() { EXEC SQL CONNECT TO basequenoexiste;if (sqlca.sqlcode) {printf("Error: No puedo conectar a la base (%d)\n", sqlca.sqlcode); exit(1); } EXEC SQL SELECT (1+1) INTO :resultado;

printf("1+1=%d\n",resultado);return 0;} /*300*/

Page 16: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

17

Códigos de Error http://www.postgresql.org/docs/7.4/static/ecpg-errors.htmlstruct{ char sqlcaid[8]; long sqlabc; long sqlcode; struct {int sqlerrml; char sqlerrmc[70];} sqlerrm; char sqlerrp[8]; long sqlerrd[6]; char sqlwarn[8]; char sqlstate[5];} sqlca;______________________________________________ver 300.c; sqlca esta comentado ahí

Page 17: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

18

WHENEVER

• Cada comando de SQL embebido puede (potencialmente) generar un error.

• Para aliviar el trabajo del programador existe la directiva WHENEVER que instruye al precompilador para que genere el código que procesará los errores

• La sintaxis de la directiva WHENEVER es:

EXEC SQL WHENEVER <condición> <acción>

Page 18: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

19

WHENEVER (cont)

• La condición puede ser:

– SQLERROR - genera código que se encargue de los errores (SQLCODE < 0).

– SQLWARNING – genera codigo que se encarge de las advertencias (warnings) (SQLCODE > 0)

– NOT FOUND - genera código que se encargue del caso especial en que todas las tuplas obtenidas como resultado de la consulta ya se han transferido.

– sqlprint – imprime mensaje de error

Page 19: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

20

WHENEVER (CONT)

• La acción puede ser:

CONTINUE – ignora el error y continua la ejecuciónfunción – transfiere el error a la funcion que se

encarga de procesar los error. DO BREAK – salte del bucleDO CONTINUE – continua con la interación

siguiente (se supone dentro de un bucle) GOTO label - transfiere el control a otra parte del

programa. STOP – Aborta transacción.SQLPRINT – imprime codigo error

Page 20: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

21

WHENEVER: Ejemplo!!!

#include <stdio.h>

int main(){EXEC SQL BEGIN DECLARE SECTION;int resultadoInd;EXEC SQL END DECLARE SECTION;

EXEC SQL CONNECT TO peliculas;

EXEC SQL WHENEVER sqlerror sqlprint; // DO BREAK //STOP

EXEC SQL INSERT INTO tablaquenoexiste (id,color) VALUES (1,2);

printf(“El programa no ha abortado tras hacer sqlprint”);return 0;}//297c.pgc

Page 21: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

22

SELECT• SELECT es un comando de SQL

potencialmente complicado de usar.• Problema: los lenguajes de programación

tradicionales están concebidos para procesar variables aisladas y no grandes tablas de dimensión virtualmente infinita

• SQL, por el contrario, puede procesar una gran cantidad de filas con un solo comando

• Aquellos SELECTs que devuelvan 0 o una tupla son fácilmente procesables pero... ¿qué hacer cuando ‘n’ tuplas son devueltas?

Page 22: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

23

SELECT – Devuelve una sola tupla

EXEC SQL SELECT fName, lName, address

INTO :firstName, :lastName, :address:addressInd,

FROM PrivateOwnerWHERE ownerNo = ‘CO21';

• Si se devuelve más de una tupla solo la primera de ellas es retenida

¿Sabrías escribir el código necesario para poder compilar el programa?

Page 23: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

24

Cursores• Si una consulta puede devolver un número

arbitrario de tuplas, es necesario usar cursores. • Los cursores permiten al lenguaje “nativo”

acceder a una relación tupla a tupla. • Los cursores se comportan como punteros a

una tupla del resultado y pueden ser movidos de una tupla a la siguiente (se puede saltar hacia atrás y delante).

• Los cursores se deben declarar y “abrir” antes de que puedan ser usados.

• Una vez abiertos el comando fetch permite avanzar hasta la siguiente tupla

Page 24: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

25

CURSOR - Ejemplo

2559.8Flåklypa Grand Prix

2569.5High and the Mighty, The

votospuntuaciontítulo

Consideremos la consulta:SELECT titulo, puntuacion ,votosFROM peliculaWHERE puntuacion > 9.4;

Page 25: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

26

Cursor: Declaraciónhacer paso a paso

• Los cursores se declara usando las palabras reservadas:– DECLARE CURSOR...CURSOR FOR– el nombre del cursor – y la consulta a realizar

EXEC SQL DECLARE miprimercursor CURSOR FOR

SELECT titulo, puntuación, votosFROM peliculaWHERE puntuacion > 9.4;

Page 26: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

27

Cursors - OPEN

• La orden OPEN ejecuta la consulta y coloca un puntero apuntando hacia la primera tupla de la relación resultante

EXEC SQL OPEN miprimercursor;

Pointer

2559.8Flåklypa Grand Prix

2569.5High and the Mighty, The

Page 27: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

28

Cursores - FETCH• FETCH devuelve la siguiente tupla en la relación

resultante de nuestra consulta y la coloca en una variable accesible por el lenguaje nativo

EXEC SQL FETCH miprimercursorINTO :titulo, :puntuación, :votos

• FETCH se coloca normalmente dentro de un bucle que itera hasta que no se devuelven más filas. Esto es, SQLCODE es NOT FOUND.

Page 28: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

29

Cursores: FETCH

EXEC SQL WHENEVER NOT FOUND DO BREAK;while(1) {

EXEC SQL FETCH miprimercursorINTO :titulo, :puntuación, :votos;

//MAS CODIGO AQUI}

Fetch 1

Fetch 2

2559.8Flåklypa Grand Prix

2569.5High and the Mighty, The

Page 29: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

30

CURSOR - CLOSE

• La orden CLOSE “cierra” el cursor activo.

EXEC SQL CLOSE miprimercursor;

Page 30: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

31

Un ejemplo de todo junto#include <stdio.h>

EXEC SQL INCLUDE sqlca;EXEC SQL BEGIN DECLARE SECTION;char titulo[256]; float fPuntuacion; int votos;char miquery[256];EXEC SQL END DECLARE SECTION;

EXEC SQL WHENEVER SQLERROR sqlprint;

int main(){

// conectarseEXEC SQL CONNECT TO peliculas; if (sqlca.sqlcode) {printf("Error: No puedo conectar a la base (%d)\n",

sqlca.sqlcode); exit(1); }

Page 31: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

32

// declara cursorEXEC SQL DECLARE micursor CURSOR FOR

SELECT titulo, puntuacion, votos FROM pelicula WHERE puntuacion > 9.4;

EXEC SQL OPEN micursor;

EXEC SQL WHENEVER NOT FOUND DO BREAK;while (1){EXEC SQL FETCH IN micursor INTO :titulo, :fPuntuacion, :votos;printf("%s %f %d\n",titulo, fPuntuacion, votos);}

EXEC SQL DISCONNECT;return 0;

}

//312.pgc

Page 32: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

33

Modificar datos usando cursores

• Los cursores pueden ser declarados como “READ ONLY” o “UPDATE”

• Aquellos declarados como “UPDATE” pueden ser usados para modificar o borrar tuplas

• “READ ONLY” es la opción por defecto, para declarar un cursor que será usado para modificar la relación usese la sintaxis:EXEC SQL DECLARE

misegundocursor CURSOR FOR SELECT titulo, puntuacion, votosFROM peliculasWHERE puntuacion < 5FOR UPDATE OF titulo,puntuacion,votos;

Page 33: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

34

Ejemplo: modificar relaciones usando cursores

#include <stdio.h>#include <stdlib.h>#include <string.h> EXEC SQL INCLUDE sqlca;

#define CHECKERR(CE_STR) if (sqlca.sqlcode != 0) {printf("%s failed. Reason %ld\n", CE_STR, sqlca.sqlcode); exit(1); }

EXEC SQL WHENEVER SQLERROR sqlprint;

int main() {

EXEC SQL BEGIN DECLARE SECTION;char titulo[256]; float fPuntuacion; int votos;char miquery[256];EXEC SQL END DECLARE SECTION;

EXEC SQL CONNECT TO peliculas; CHECKERR ("CONNECT TO peliculas");

Page 34: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

35

Ejemplo: modificar relaciones usando cursores-II

/* Maniaco de Star Trek *///LOCK table IN exclusive mode;EXEC SQL DECLARE micursor CURSOR FOR SELECT puntuacion, votos FROM pelicula WHERE titulo LIKE 'Star Trek%'

FOR UPDATE OF puntuacion,votos;EXEC SQL OPEN micursor;CHECKERR ("OPEN CURSOR");do { EXEC SQL FETCH micursor INTO :fPuntuacion, :votos; printf("%f %d\n",fPuntuacion,votos); if (SQLCODE != 0) break; if(fPuntuacion < 99999){ EXEC SQL UPDATE pelicula SET puntuacion = 999999, votos = 99999 ; CHECKERR ("UPDATE pelicula"); }} while ( 1 );EXEC SQL CLOSE micursor; EXEC SQL commit;}/* end of program 326 */

Page 35: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

36

SQL Dinámico vs Estático• Hasta el momento hemos visto SQL (embebido) estático• SQL estático es, posiblemente, la formula más popular de

programar con SQL pero sólo en usable si se conoce las consultas que una aplicación va a hacer durante la fase de diseño de la aplicación.

• Su principal limitación es que no permite decidir en tiempo real a que tablas o atributos (u otros objetos) nos queremos referir.

• Esto es: con SQL estático puedes decidir que valor va a tener un atributo en tiempo real pero no que atributo vas a cambiar (o a que base de datos vas a acceder)

Page 36: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

37

EXECUTE IMMEDATELY• La forma más sencilla de ejecutar una sentencia arbitraria en SQL

consiste en usar la orden EXECUTE IMMEDIATE :EXEC SQL EXECUTE IMMEDIATE

[cadena_con_la_consulta]

• Por ejemplo:EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "CREATE TABLE test1(...);"; EXEC SQL END DECLARE SECTION;

EXEC SQL EXECUTE IMMEDIATE :stmt;

• No se pueden ejecutar sentencias que devuelvan datos de esta manera. (SELECT no esta permitido pero INSERT o UPDATE son posibles)

Page 37: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

38

Ejemplo#include <stdio.h>

int main(){EXEC SQL BEGIN DECLARE SECTION; char resultado[11]; int resultadoInd;EXEC SQL END DECLARE SECTION;

EXEC SQL CONNECT TO peliculas;//Dos Declare secction estilo c++

EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "CREATE TABLE test1 (i int, f float);";EXEC SQL END DECLARE SECTION;

EXEC SQL EXECUTE IMMEDIATE :stmt;EXEC SQL COMMIT;return 0;}//immediate

Page 38: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

39

PREPARE y EXECUTE• La base de datos tiene que analizar, validar y

optimizar cada sentencia SQL de tipo “EXECUTE IMMEDIATE”.

• Si se planea utilizar repetidamente la misma sentencia (o variantes parametrizadas de la misma) entonces combiene “preparar” las consultas previamente de forma que la validación, optimización y analisis se realice una única vez por “familia” de consultas.

• SQL dinámico cuenta con las intrucciones: PREPARE y EXECUTE para realizar esta tarea

Page 39: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

40

Immediate vs Prepare/Execute

Page 40: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

41

int main() {/*No se comprueban errores para ahorrar espacio*/EXEC SQL BEGIN DECLARE SECTION; char dbname[64] = “peliculas”; char sql_string[1000]; int i; float f;

EXEC SQL END DECLARE SECTION;

/* Conectarse a la base de datos*/ EXEC SQL CONNECT TO :dbname; /*EXEC SQL SET AUTOCOMMIT TO ON; */

/* Preparara la orden INSERT */ strcpy(sql_string, "INSERT INTO test1 VALUES(?, ?)"); EXEC SQL PREPARE prep_ins FROM :sql_string;

/* Insertar varias tuplas (en una sola transaccion*/

EXEC SQL BEGIN;

for(i = 0; i < 3; i++) {

switch(i) {

case 0: f=0.; break;

case 1: f=1.; break;

case 2: f=2.; break;

}

EXEC SQL EXECUTE prep_ins USING :i, :f;

}

EXEC SQL COMMIT;

}//400.pgc

Page 41: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

42

falta ejemplo prepare execute con cursores

Page 42: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

Use declare and prepare

• // first declare some variables• EXEC SQL BEGIN DECLARE SECTION;• char *stmt;const • char *input;• int num;• EXEC SQL END DECLARE SECTION;• // now construct your search query. This has to be stored in a

non const char*. In this example I don't show any fancy construction code.

• stmt=strdup("select nr from table where name=?");• // prepare the cursor• EXEC SQL PREPARE search FROM :stmt;• EXEC SQL DECLARE curs • SCROLL CURSOR FOR search;EXEC SQL OPEN curs USING

:input;// now loop over our resultsEXEC SQL WHENEVER NOT FOUND DO break;while(true){ EXEC SQL FETCH NEXT FROM curs INTO :num; // do whatever need to be done with "num"}EXEC SQL CLOSE curs;EXEC SQL DEALLOCATE PREPARE search;free(stmt);

Page 43: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

• CREATE RULE update_grupo_46 AS ON UPDATE TO introducir_notas_teoria_grupo_46 DO INSTEAD UPDATE notas_teoria_46 SET parcial = new.parcial, febrero = new.febrero, septiembre = new.septiembre, nota_teoria = new.nota_teoria, nota_acta = new.nota_acta, aux1 = new.aux1, aux2 = new.aux2 WHERE (notas_teoria_46.dni = old.dni);

Page 44: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

45

APIs para las bases de datos• Hasta ahora hemos mencionado distintos

métodos para “embeber” SQL en lenguajes de programación de alto nivel. (Con la excepción de JDBC)

• Normalmente todos las empresas que mantienen sistemas de bases de datos ofrecen APIs.

• De esta forma en lugar de “embeber” SQL los programadores tienen acceso a un conjunto de librerías que les permiten comunicarse con la base de datos.

Page 45: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

46

Open Database Connectivity (ODBC)

• Las distintas APIs desarrolladas por los diferentes vendedores representan un problema para los desarrolladores de aplicaciones ya que les fuerzan a rescribir el código para cada base de datos

• Entre las muchas estandarizaciones propuestas ODBC (originalmente propuesta por Microsoft) es uno de los estándares de facto. Probablemente el estándar que “es soportado” por más lenguajes y aplicaciones

• ODBC asume que las bases están basadas en SQL estandard.

Page 46: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

47

Open Database Connectivity (ODBC)• ODBC (escrito en ‘C’) permite conectarse a las

diversas bases de datos usando el mismo código y sin necesidad de recompilar.

• java -Djdbc.drivers=org.mysql.Driver myaplicacion

• Por lo tanto permite al desarrollador crear programas que no estén orientados hacia una base de datos en concreto.

• Se precisa de un driver (suministrado por la empresa que desarrolla el sistema de bases de datos) que hace de enlace entre el driver manager y la base de datos.

Page 47: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

48

Ventajas de usar ODBC

• La aplicacion no depende de un API nativo (de una base de datos en particular).

• La aplicación puede ignorar las comunicaciones cliente servidor.

• Hay drivers que siguen el estandar ODBC para virtualmente cualquier lenguaje y cualquier sistema de bases de datos. Así pues una aplicación escrita con ODBC puede conectarse a virtualmente cualquier base de datos

Page 48: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

49

ODBC: Arquitectura

• ODBC tiene cuatro componentes principales:

– Aplicación

– Driver Manager (parte del sistema operativo en windows)

– Driver

– Base de Datos.

Page 49: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

50

ODBC Architecture

ApplicacionApplicacion – procesa los – procesa los datos y realiza llamadas a datos y realiza llamadas a funciones ODBC para emviar funciones ODBC para emviar sentencias SQL o recibir datos sentencias SQL o recibir datos de la BBDDde la BBDD

Driver ManagerDriver Manager – maneja los – maneja los drivers “en representación” de drivers “en representación” de la aplicación.la aplicación.

DatosDatos- -

Driver – procesan las llamadas a funciones ODBC, embian el as consultas SQL y recogen los resultados

• Los drivers pueden modificar las consultas para que se adecuen a la sintaxis que espera la base de datos. •

Page 50: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

51

ODBC: Limitaciones

• Las principales son:– Más lento que las alternativas usando

drivers ‘nativos’ o SQL embebido– ODBC no puede explotar todas las

funciones disponibles en la base de datos.

Page 51: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

53

Conexión desde Oofficeun interludio

• unixODBC-2.2.8-5• cat /etc/odbcpsql.ini• cat $HOME/.odbc.ini • isql testodbc2 roberto pepino • Tools -> Data Sources• Data -> DataPilot -> Start

– View -> DataSource -> Tables– Left click

• application->ODBC-Manager->odbc.ini->odbcinst.ini->driver->database

Page 52: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

54

ODBC: Fuentes de sabiduría

http://www.unixodbc.org/

http://msdn.microsoft.com/

Page 53: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

55

Ejemplo initializate.h

#include <stdio.h>#include <stdlib.h>#include <sql.h>#include <sqlext.h> #include <sqltypes.h> SQLCHAR DSN[10] = "testodbc2"; // The following should be changed to your userid and password// and the length of the variable should be the actual length + 1SQLCHAR DSN_userid[9] = "roberto";SQLCHAR DSN_password[9] = "pepino"; int Initialize(HENV * phenv, HDBC * phdbc, HSTMT * phstmt);void cleanup(HENV henv, HDBC hdbc, HSTMT hstmt); // Allocate the environment, connection, statement handlesint Initialize(SQLHANDLE * phenv, SQLHANDLE * phdbc, SQLHANDLE * phstmt){ SQLINTEGER res; // Allocate an environment handle // 1. allocate Environment handle and register version res=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,phenv); // res = SQLAllocEnv(phenv); OLD odbc style if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { fprintf(stderr, "Unable to allocate environment handle (ret=%d)\n", res); exit(1); } // Requiere ODBC 3 res=SQLSetEnvAttr(*phenv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);

if (res != SQL_SUCCESS){

printf("Error SetEnv\n");SQLFreeHandle(SQL_HANDLE_ENV, phenv);exit(0);

}

Page 54: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

56

Ejemplo (cont) // Allocate a connection handle res = SQLAllocHandle(SQL_HANDLE_DBC, *phenv, phdbc); //res = SQLAllocConnect(*phenv, phdbc); OLD

STYLE if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { fprintf(stderr, "Unable to allocate connection handle (ret=%d)\n", res); cleanup(*phenv, *phdbc, *phstmt); exit(1); } // The connection parameters printf("Connection Parameters: DSN='%s', UID='%s', PWD='%s'\n", DSN, DSN_userid, DSN_password); // Connect to the database res = SQLConnect(*phdbc, DSN, SQL_NTS, DSN_userid, SQL_NTS, DSN_password, SQL_NTS); //SQL_NTS -> Null Terminated String if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { fprintf(stderr, "Unable to connect to datasource (ret=%d)\n", res); cleanup(*phenv, *phdbc, *phstmt); exit(1); } // Allocate a statement handle res = SQLAllocHandle(SQL_HANDLE_STMT, *phdbc, phstmt); //res = SQLAllocStmt(*phdbc, phstmt); if (res != SQL_SUCCESS) { fprintf(stderr, "Unable to allocate statement handle (ret=%d)\n", res); cleanup(*phenv, *phdbc, *phstmt); exit(1); } printf("Handles initialized.\n"); return 0;}

Page 55: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

57

Ejemplo (cont)

// Cleanup before exit

void cleanup(HENV henv, HDBC hdbc, HSTMT hstmt)

{

// Disconnect from the database and free all handles

SQLFreeHandle(SQL_HANDLE_STMT, hstmt);//SQLFreeStmt(hstmt, SQL_CLOSE);

SQLDisconnect(hdbc);

SQLFreeHandle(SQL_HANDLE_DBC, hdbc);//SQLFreeConnect(hdbc);;

SQLFreeHandle(SQL_HANDLE_ENV, henv);//SQLFreeEnv(henv);

return;

}

Page 56: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

58

Ejemplo (Cont)main file: ExecDiretc.c

#include <stdio.h>#include <stdlib.h>#include "Initialize.h"// gcc -lodbc -I/home/roberto/tmp/unixODBC-2.2.10/include ExecDirect.c -o

ExecDirect int main(int argc, char *argv[]){ HENV henv; HDBC hdbc; HSTMT hstmt; SQLCHAR SelectStmt[255]; int res; if (argc != 2) { fprintf(stderr, "Usage: ExecDirect <SQL Statement>\n"); exit(1); } else { if (strlen (argv[1]) > 254) { fprintf(stderr, "SQL statement is longer than 254 characters\n"); exit(1); } strncpy((char *) SelectStmt, argv[1], 255); } // Allocate all handles res = Initialize(&henv, &hdbc, &hstmt); if (res != 0) { fprintf("Unable to initialize (ret=%d)\n", res); exit(1); }

Page 57: 1 SQL en Entorno de Programación. 2 Motivación: SQL Interactivo vs. No Interactivo Hasta la fecha hemos considerado sólo consultas SQL en las que tecleamos

59

Ejemplo Cont

// Prepare and execute the user provided SQL statement res = SQLExecDirect(hstmt, SelectStmt, SQL_NTS); if (res != SQL_SUCCESS) { fprintf("Unable to execute statement directly (ret=

%d)\n", res); // Disconnect from the database and free all

handles cleanup(henv, hdbc, hstmt); exit(1); } printf("'%s' directly executed.\n", SelectStmt); cleanup(henv, hdbc, hstmt); return 0;}