Base de Datos Oracle: desarrollo de aplicaciones Oracle Pro-C/C++ Contenidos Introducción Compilación Código incrustado Comunicación de variables Conexión Transacciones Control de errores Llamadas a procedimientos almacenados Más sobre el pre-compilador jul-04 Alberto M.F.A. alb@lsi.uniovi.es 2
Características Se escribe todo en C/C++ Precompila SQL, valida sintaxis antes de ejecutar Se puede emplear cualquier sentencia SQL y PL/SQL Permite Threading Conversión de tipos C a Oracle jul-04 Alberto M.F.A. alb@lsi.uniovi.es 3 Características Permite conexión simultanea a varios servidores Control cómodo de errores Soporta tipos objeto, LOBS, CLOBS Puede interactuar con OCI jul-04 Alberto M.F.A. alb@lsi.uniovi.es 4
Contenidos Introducción Compilación Código incrustado Comunicación de variables Conexión Transacciones Control de errores Llamadas a procedimientos almacenados Más sobre el pre-compilador jul-04 Alberto M.F.A. alb@lsi.uniovi.es 5 Compilación Exec jul-04 Alberto M.F.A. alb@lsi.uniovi.es 6
Compilación detallada.h.h <<includes>>.pc PROC.c VC++.exe 01010 10101 11001 Preproceso Compilación 01010 10101 11001 Linkage.tmp.obj 01010 10101 11001.lib jul-04 Alberto M.F.A. alb@lsi.uniovi.es 7 Compilación MVC++ 6.0 Librerías solo para MSVC++ 6.0 El preprocesador proc.exe en %ORA_HOME%\bin Linkar con orasql8.lib y orasqx8.lib en %ORA_HOME%\precomp\lib\msvc jul-04 Alberto M.F.A. alb@lsi.uniovi.es 8
Ficheros de inclusión Es necesario incluir en nuestro código: #include <oci.h> #include <sqlca.h> /*SQL Communications Area*/ <oci.h> está en %ORA_HOME%\oci\include <sqlca.h> está en %ORA_HOME%\precomp\public jul-04 Alberto M.F.A. alb@lsi.uniovi.es 9 Invocación de proc.exe proc parse=full varios modos iname=$(inputname).pc oname=$(inputname).c include= %ORA_HOME%\oci\include" include= %ORA_HOME%\precomp\public" include="$(msdevdir)\..\..\vc98\include Tiene más opciones ver: $>proc -h jul-04 Alberto M.F.A. alb@lsi.uniovi.es 10
Integración con VC++ Sobre <fichero>.pc Botón derecho ratón Settings... Seleccionar Custom build Cuadro Commands... %ORA_HOME%\bin\proc.exe parse=full... Cuadro Outputs... $(InputName).c Así para cada fichero.pc Incluir en el proyecto los generados.c jul-04 Alberto M.F.A. alb@lsi.uniovi.es 11 Project Settings en VC++ jul-04 Alberto M.F.A. alb@lsi.uniovi.es 12
Línea de comando para precompilación sencila %ORA_HOME%\bin\proc.exe parse=full iname=$(inputname).pc oname=$(inputname).c include="%ora_home%\oci\include include="%ora_home%\precomp\public include="$(msdevdir)\..\..\vc98\inc lude include="." jul-04 Alberto M.F.A. alb@lsi.uniovi.es 13 Estructura de ejecución Código.PC Código Pro-C/C++ SQLLIB OCI Net8 Interfaz propietario, no documentado jul-04 Alberto M.F.A. alb@lsi.uniovi.es 14
Contenidos Introducción Compilación Código incrustado Comunicación de variables Conexión Transacciones Control de errores Llamadas a procedimientos almacenados Más sobre el pre-compilador jul-04 Alberto M.F.A. alb@lsi.uniovi.es 15 Código SQL incrustado Estructura: EXEC SQL <sentencia SQL> ; Se puede insertar en cualquier parte Se pueden referenciar variables del programa host jul-04 Alberto M.F.A. alb@lsi.uniovi.es 16
Código PL/SQL incrustado EXEC SQL EXECUTE DECLARE... BEGIN... END; END-EXEC; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 17 Reglas para código incrustado Admite comentarios C y SQL Strings en SQL con y NO Código C (prototipos de función): MODE=CPP C++ MODE=KR_C Kernighan y Ritchie MODE=ANSI_C Continuación strings EXEC SQL... \ jul-04 Alberto M.F.A. alb@lsi.uniovi.es 18
Contenidos Introducción Compilación Código incrustado Comunicación de variables Conexión Transacciones Control de errores Llamadas a procedimientos almacenados Más sobre el pre-compilador jul-04 Alberto M.F.A. alb@lsi.uniovi.es 19 Variables host Cualquier escalar o array Son de lectura/escritura para SQL y el programa host Esta asociación se denomina binding En C se referencian por el <nombre> En SQL por :<nombre> El nombre debe ser idéntico jul-04 Alberto M.F.A. alb@lsi.uniovi.es 20
Ejemplo variables host int nempleado; //Esto es C... EXEC SQL SELECT //Esto es PRO-C NVL(MAX(empno), 0) INTO :nempleado FROM emp;... if (nempleado <> 0) // Esto es C {... jul-04 Alberto M.F.A. alb@lsi.uniovi.es 21 Declare Section Declare Section: EXEC SQL BEGIN DECLARE SECTION; char *uid = "scott/tiger";... EXEC SQL END DECLARE SECTION; Necesaria si CODE=CPP o MODE=ANSI o PARSE=NONE o PARSE=PARTIAL jul-04 Alberto M.F.A. alb@lsi.uniovi.es 22
Indicadores Avisan de NULL y truncamientos char emplname[14]; char empljob[10]; short indjob; // Indicador EXEC SQL FETCH c INTO :emplname, :empljob:indjob; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 23 Indicadores Son de entrada/salida Pueden usarse arrays como variables Si se necesitan indicadores, otro array de la misma dimensión con solo indicadores int vector[5]; //Valores int ind[5]; //Indicadores EXEC SQL INSERT INTO tbl (val) VALUES :vector:ind; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 24
Indicadores, valores 0 Todo correcto -1 Valor leído/escrito es NULL -2 Truncamiento no determinable >0 Truncamiento, la longitud inicial es el valor jul-04 Alberto M.F.A. alb@lsi.uniovi.es 25 Cursores Para las SELECT que devuelvan una sola fila no hace falta declararlos Para las SELECT múltiples si jul-04 Alberto M.F.A. alb@lsi.uniovi.es 26
Ejemplo Cursores EXEC SQL DECLARE <nombre> CURSOR FOR <sql>;... EXEC SQL OPEN c; EXEC SQL WHENEVER NOT FOUND DO break; while(more_rows) { EXEC SQL FETCH c INTO <binded vars>... Proceso... } EXEC SQL CLOSE c; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 27 Contenidos Introducción Compilación Código incrustado Comunicación de variables Conexión Transacciones Control de errores Llamadas a procedimientos almacenados Más sobre el pre-compilador jul-04 Alberto M.F.A. alb@lsi.uniovi.es 28
Abrir la conexión EXEC SQL CONNECT :user_pass; EXEC SQL CONNECT :user IDENTIFIED BY :password; EXEC SQL CONNECT :user IDENTIFIED BY :password ALTER AUTHORIZATION :newpass; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 29 Conexión automática OP$<username> <username> en el S.O. Trata de conectar automáticamente si: Si opción de proc.exe AUTO_CONNECT=YES O en código char *oraid = / ; Solo 1 char EXEC SQL CONNECT :oraid; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 30
Cerrar la conexión EXEC SQL COMMIT RELEASE; Si el programa acaba sin COMMIT todo el trabajo perdido EXEC SQL ROLLBACK RELEASE; Si se detecta error grave jul-04 Alberto M.F.A. alb@lsi.uniovi.es 31 Contenidos Introducción Compilación Código incrustado Comunicación de variables Conexión Transacciones Control de errores Llamadas a procedimientos almacenados Más sobre el pre-compilador jul-04 Alberto M.F.A. alb@lsi.uniovi.es 32
Transacciones Cada sentencia inicia una implícitamente Las sentencias DDL inician y terminan implícitamente Las sentencias DML hacen COMMIT o ROLLBACK cuando: EXEC SQL COMMIT/ROLLBACK [WORK]; Se inicia detrás una sentencia DDL jul-04 Alberto M.F.A. alb@lsi.uniovi.es 33 Transacciones Cuando el programa para por fallo software o hardware... Se produce un ROLLBACK automático Todo las escrituras que haga el programa están dentro de una ÚNICA transacción hasta que se hace COMMIT o ROLLBACK Hacerlo con frecuencia Excepción: Si por el medio se mete DDL jul-04 Alberto M.F.A. alb@lsi.uniovi.es 34
SavePoints Dentro de una transacción compleja: EXEC SQL SAVEPOINT start_delete; EXEC SQL DELETE FROM...; EXEC SQL ROLLBACK TO SAVEPOINT start_delete; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 35 Contenidos Introducción Compilación Código incrustado Comunicación de variables Conexión Transacciones Control de errores Llamadas a procedimientos almacenados Más sobre el pre-compilador jul-04 Alberto M.F.A. alb@lsi.uniovi.es 36
Control de errores Dos mecanismos: Uso de la SQLCA Si es necesaria más información también se usa ORACA Uso de la sentencia WHENEVER jul-04 Alberto M.F.A. alb@lsi.uniovi.es 37 SQLCA Es una struct C que almacena status de operaciones Inclusión, dos alternativas: EXEC SQL INCLUDE SQLCA; #include <sqlca.h> jul-04 Alberto M.F.A. alb@lsi.uniovi.es 38
Contenido de SQLCA Entre otras cosas... sqlca.sqlcode 0 si OK, >0 NO_DATA, <0 Error grave sqlca.sqlerrm.sqlerrmc mensaje de error sqlca.sqlerrm.sqlerrml longitud err. mens sqlca.sqlerrd[2] nº de filas procesadas sqlca.sqlerrd[4] nº de columna error parse sqlca.sqlwarm[0..7] varios warms jul-04 Alberto M.F.A. alb@lsi.uniovi.es 39 WHENEVER EXEC SQL WHENEVER <condition> <action>; Condiciones: SQLWARNING consultar SQLCA SQLERROR NOT FOUND última fila, no hay filas jul-04 Alberto M.F.A. alb@lsi.uniovi.es 40
Acciones WHENEVER CONTINUE DO <expresion_lenguaje> DO BREAK DO CONTINUE GOTO <label> STOP jul-04 Alberto M.F.A. alb@lsi.uniovi.es 41 Ejemplos WHENEVER EXEC SQL WHENEVER NOT FOUND DO handle_error(); EXEC SQL WHENEVER SQLWARNING CONTINUE; EXEC SQL WHENEVER SQLERROR GOTO finaliza; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 42
Ejemplos WHENEVER EXEC SQL WHENEVER NOT FOUND DO break; while(more_rows) { EXEC SQL FETCH c INTO :emplname, :empljob:indjob;... Proceso... } jul-04 Alberto M.F.A. alb@lsi.uniovi.es 43 Ámbito WHENEVER Su ámbito es posicional, no lógico Vigila todas las sentencias que físicamente siguen en el código No vigila el flujo del programa! Una WHENEVER está activa hasta que otra la revoca Buena práctica: Una antes de cada SQL a vigilar jul-04 Alberto M.F.A. alb@lsi.uniovi.es 44
Contenidos Introducción Compilación Código incrustado Comunicación de variables Conexión Transacciones Control de errores Llamadas a procedimientos almacenados Más sobre el pre-compilador jul-04 Alberto M.F.A. alb@lsi.uniovi.es 45 Llamada a P/F almacenados Dos métodos CALL BEGIN... END CALL cómodo para llamar a procedimientos y funciones BEGIN... END única forma si el procedimiento devuelve un cursor jul-04 Alberto M.F.A. alb@lsi.uniovi.es 46
CALL EXEC SQL CALL [schema.] [package.]stored_proc[@db_link]( arg1,...) [INTO :ret_var [[INDICATOR]:ret_ind]] ; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 47 Ejemplo call... int num, fact;... EXEC SQL CALL mathpkge.fact(:num) INTO :fact ;... jul-04 Alberto M.F.A. alb@lsi.uniovi.es 48
BEGIN... END EXEC SQL EXECUTE BEGIN raise_salary(:emp, :increase); END; END-EXEC; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 49 Procedimientos y cursores Variable de tipo SQL_CURSOR Se inicializa (allocate) Se le pasa el proc almacenado Se recorren todas las filas Se cierra Se libera jul-04 Alberto M.F.A. alb@lsi.uniovi.es 50
Ejemplo Procs y cursores (1) SQL_CURSOR crsr; EXEC SQL ALLOCATE :crsr; EXEC SQL EXECUTE BEGIN proc(:id, :crsr); END; END-EXEC; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 51 Ejemplo Procs y cursores (y 2) EXEC SQL WHENEVER NOT FOUND... while(more_rows) { EXEC SQL FETCH :crsr INTO... } EXEC SQL CLOSE :crsr; EXEC SQL FREE :crsr; jul-04 Alberto M.F.A. alb@lsi.uniovi.es 52
Contenidos Introducción Compilación Código incrustado Comunicación de variables Conexión Transacciones Control de errores Llamadas a procedimientos almacenados Más sobre el pre-compilador jul-04 Alberto M.F.A. alb@lsi.uniovi.es 53 Compilación detallada #INCLUDE.h.h PROC.pc.c VC++.exe 01010 10101 11001 Preproceso.tmp Compilación 01010 10101 11001.obj Linkage 01010 10101 11001.lib jul-04 Alberto M.F.A. alb@lsi.uniovi.es 54
Precompilación condicional Como la precompilación normal del compilador pero para Pro-C jul-04 Alberto M.F.A. alb@lsi.uniovi.es 55 Ficheros de inclusión C Pro-C interpreta la mayoría de las directivas del preprocesador C del compilador. #define, #ifdef,... NO interpreta: #pragma, #error, #line, #, ## jul-04 Alberto M.F.A. alb@lsi.uniovi.es 56
Opciones del precompilador Muchas opciones se pueden dar desde la línea de comandos de proc.exe También se pueden ajustar en código EXEC ORACLE OPTION(<opc>=<val>); Está en efecto hasta que aparece otra OPTION en el mismo fichero. No pasan de un fichero a otro. jul-04 Alberto M.F.A. alb@lsi.uniovi.es 57 Opciones si se usa PL/SQL...... o se desea chequeo estricto Más opciones en la línea de comandos: %ORA_HOME%\proc.exe... SQLCHECK=SEMANTICS USERID=user/pass@instance Para solo algunas partes de código: EXEC ORACLE OPTION(SQLCHECK=SEMANTICS) PROC chequea contra el diccionario de datos Se conecta con el servidor para precompilar El servidor debe estar on-line! jul-04 Alberto M.F.A. alb@lsi.uniovi.es 58
Algunas opciones jul-04 Alberto M.F.A. alb@lsi.uniovi.es 59