Monografias.com > Computación > Programación
Descargar Imprimir Comentar Ver trabajos relacionados

SQL en entorno de programación




Enviado por Pablo Turmero



    Monografias.com

    1
    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.

    Monografias.com

    2
    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()…

    Monografias.com

    3
    Posibles formas de Conexión con la base de datos
    Embedded SQL
    Library (database API): ODBC (database independent, complex), JDBC (slow),

    Monografias.com

    4
    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

    Monografias.com

    5
    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

    Monografias.com

    6
    Un ejemplo rollback and commit
    Preprocesador para C y SQL embebido (ECPG)?

    #include
    /* 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=%dn",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*/

    Monografias.com

    7
    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

    Monografias.com

    8
    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 Course AS C
    WHERE C.CrsCode = :crs_code;
    Variables
    compartidas

    “:” se usa para las variables en SQL

    Monografias.com

    9
    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

    Monografias.com

    10
    Variables Indicadoras: Ejemplo
    EXEC SQL BEGIN DECLARE SECTION;
    char address[51];
    short addressInd;
    EXEC SQL END DECLARE SECTION;
    addressInd = -1;
    EXEC SQL UPDATE PrivateOwner
    SET address = :address:addressInd
    WHERE ownerNo = ‘CO21';
    2 byte int
    Se sitúan inmediatamente después de la variable que “matizan”. address=NULL!!!

    Monografias.com

    11
    Ejemplo!!!saltarse clave primaria
    #include
    //create table pepinillo(id int,color text);
    //psql peliculas
    int main()?
    {
    EXEC SQL BEGIN DECLARE SECTION;
    char resultado[11];
    int resultadoInd;
    EXEC SQL END DECLARE SECTION;
    //las variables indicadoras funcionan en las dos direcciones
    EXEC SQL CONNECT TO peliculas;
    resultadoInd = -1;
    strcpy(resultado,"rojo");

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

    return 0;
    }//297b.pgc

    Monografias.com

    12
    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

    Monografias.com

    13
    Ejemplo
    #include
    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("%sn", sqlca.sqlerrm.sqlerrmc);
    exit(1);
    }
    EXEC SQL SELECT (1+1) INTO :resultado;

    printf("1+1=%dn",resultado);
    return 0;
    }

    Monografias.com

    14
    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

    Monografias.com

    15
    Errores
    #include
    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=%dn",resultado);
    return 0;
    }
    /*300*/

    Monografias.com

    16
    Códigos de Error
    http://www.postgresql.org/docs/7.4/static/ecpg-errors.html
    struct
    {
    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í

    Monografias.com

    17
    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

    Monografias.com

    18
    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

    Monografias.com

    19
    WHENEVER (CONT)?
    La acción puede ser:

    CONTINUE – ignora el error y continua la ejecución
    función – transfiere el error a la funcion que se encarga de procesar los error.
    DO BREAK – salte del bucle
    DO 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

    Monografias.com

    20
    WHENEVER: Ejemplo!!!
    #include

    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

    Monografias.com

    21
    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?

    Monografias.com

    22
    SELECT – Devuelve una sola tupla
    EXEC SQL SELECT fName, lName, address
    INTO :firstName, :lastName, :address:addressInd,
    FROM PrivateOwner
    WHERE 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?

    Monografias.com

    23
    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

    Monografias.com

    24
    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, votos
    FROM pelicula
    WHERE puntuacion > 9.4;

    Monografias.com

    25
    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 miprimercursor
    INTO :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.

    Monografias.com

    26
    CURSOR – CLOSE
    La orden CLOSE “cierra” el cursor activo.
    EXEC SQL CLOSE miprimercursor;

    Monografias.com

    27
    Un ejemplo de todo junto
    #include

    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()?
    {
    // conectarse
    EXEC SQL CONNECT TO peliculas;
    if (sqlca.sqlcode)?
    {printf("Error: No puedo conectar a la base (%d)n",
    sqlca.sqlcode);
    exit(1);
    }

    Monografias.com

    28
    // declara cursor
    EXEC 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 %dn",titulo, fPuntuacion, votos);
    }

    EXEC SQL DISCONNECT;
    return 0;
    }

    //312.pgc

    Monografias.com

    29
    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, votos
    FROM peliculas
    WHERE puntuacion < 5
    FOR UPDATE OF titulo,puntuacion,votos;

    Monografias.com

    30
    Ejemplo: modificar relaciones usando cursores
    #include
    #include
    #include

    EXEC SQL INCLUDE sqlca;

    #define CHECKERR(CE_STR) if (sqlca.sqlcode != 0) {printf("%s failed. Reason %ldn", 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");

    Monografias.com

    31
    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 %dn",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 */

    Monografias.com

    32
    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)?

    Monografias.com

    33
    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)?

    Monografias.com

    34
    Ejemplo
    #include

    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

    Monografias.com

    35
    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

    Monografias.com

    36
    Immediate vs Prepare/Execute

    Monografias.com

    37
    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

    Monografias.com

    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);

    Monografias.com

    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);

    Monografias.com

    ESTA PRESENTACIÓN CONTIENE MAS DIAPOSITIVAS DISPONIBLES EN LA VERSIÓN DE DESCARGA

    Nota al lector: es posible que esta página no contenga todos los componentes del trabajo original (pies de página, avanzadas formulas matemáticas, esquemas o tablas complejas, etc.). Recuerde que para ver el trabajo en su versión original completa, puede descargarlo desde el menú superior.

    Todos los documentos disponibles en este sitio expresan los puntos de vista de sus respectivos autores y no de Monografias.com. El objetivo de Monografias.com es poner el conocimiento a disposición de toda su comunidad. Queda bajo la responsabilidad de cada lector el eventual uso que se le de a esta información. Asimismo, es obligatoria la cita del autor del contenido y de Monografias.com como fuentes de información.

    Categorias
    Newsletter