Base de Datos Oracle:
desarrollo de aplicaciones
Interfaz OCI
Contenidos
Tecnologías nativas ORACLE
Plataforma Windows
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 3
Tecnologías ORACLE
OCI Oracle Call Interfaz
3GL C/C++, COBOL, FORTRAN Precompiladores Pro C/C++ Pro COBOL Pro FORTRAN SQLJ para java
OCI
Interfaz de más bajo nivel disponible en
el cliente
Encima de Net8
OCI es un API procedural para
lenguajes de 3ª generación
C / C++ Cobol Fortran
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 5
OCI y Net8
Características del API
Permite obtener mucho rendimiento
Pro-C, ODBC, OleDB, ADO, JDBC sobre OCI Incluye funciones para:
Control de sesiones Transacciones
SQL dinámico
Acceso a Objetos Oracle Arrays en sentencias SQL
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 7
Características avanzadas
Interfaces para estructuras internas
Gestión de varias sesiones concurrentes
Client-side Object cache
Maneja objetos con SQL o punteros C
Conversión entre tipos C y Oracle
OTT
Oracle Advanced Queing (OA)
Inconvenientes
Muchas funciones en el API
Con muchos parámetros
Excesivo uso de void*
Para portabilidad tipos de datos C
Oracle (cast)
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 9
Compilación
Compilación
Ficheros de cabecera #include <oci.h> $ORA_HOME/oci/includeLibrerías compiladas para ANSI C:
Borland C++ 5.0 $ORA_HOME/oci/lib/bc MVC++ 6.0 $ORA_HOME/oci/lib/msvc
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 11
Programación: pasos básicos
Crear variable de entorno
Crear handlers y estructuras
Conectar al servidor e iniciar
sesión
Ejecutar transacciones SQL y
procesar
Cerrar sesión y desconectar
Liberar handlers y estructuras
Proceso y entorno
Todas las transacciones se ejecutan en
un entorno (OCIEnv)
Un Proceso OCI soporta múltiples
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 13
Proceso y entorno
Estructuras de datos OCI
Son áreas de datos opacas, ocultas al
programa, dentro de la librería.
Se referencian a través de *handlers.
Se crean con llamadas al API
Dos tipos:
Handlers Descriptores
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 15
Handlers
Punteros a estructuras ocultas
Guardan información sobre:
Contexto y conexión Errores y funciones OCI
Solo Algunos...
Handlers
Se pasan en todas las llamadas
La mayoría dependen del Handle de
entorno
Hay relación jerárquica entre ellos
Creación de OCIEnv
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 17
Jerarquía de Handlers
Casi todos dependen de OCIEnv
Creación de Handlers
De entorno OCIEnv:
OCIEnvCreate(&Env,OCI_DEFAULT,...
Resto de Handlers:
OCIHandleAlloc(Env, &Error, OCI_HTYPE_ERROR, 0, NULL);
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 19
Destrucción de handlers
Para todos
OCIHandleFree(...)
Si se elimina el de entorno, todos liberados
(jerarquía)
OCIHandleFree(Env, OCI_HTYPE_ENV)
Handlers principales
Environment OCIEnv
Error OCIError
Service Context OCISvcCtx
Server OCIServer
UserSesion OCISesion
Statement OCIStmt
Bind OCIBind
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 21
Atributos de handlers
Cada atributo representa información
guardada en el handle
Cada handler tiene atrib. Especificos
Hay que Asociar explicitamente los
atributos al handler
OCIAttrSet(...) OCIAttrGet(...)
Uso de memoria OCI
OCICreateEnv, OCIHandleAlloc y
OCIDescriptorAlloc() permiten reservar
memoria de la librería
Útil para datos de cliente con mismo
ciclo de vida que el handle
Parámetro xtramem_sz
La librería la libera al eliminar el handle
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 23
Descriptores
Mantienen información sobre conceptos
“dentro” de la BD (¿metainformación?) Funciones: OCIDescriptorAlloc(...) OCIDescriptorFree(...)
Tipos de descriptores
OCISnapshot InstántaneaOCILOBLocator CLOB, BLOB
OCIParam describe calls
OCIRowid bind-define rowids
OCINotify publish-suscribe
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 25
Inicialización de la aplicación
Varios modos
Shared Mode, cuando:
Varias instancias de la misma aplicación en la misma
máquina para distintos clientes
Se ejecuta la misma sentencia en la misma o distintas
conexiones
Es un driver SQL u otro middleware
Threaded Events Default
Inicialización
Los modos anteriores pueden
combinarse con el operador |:
mode = (OCI_THREADED | OCI_OBJECT)
Con las funciones:
OCIEnvCreate(...)
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 27
Conexión y sesión
Dos modos:
Aplicaciones para único usuario y conexión
por BD
OCILogon(...)
Múltiples sesiones o conexiones
OCIServerAttach(...) OCISessionBegin(...)
Conexión sencilla
OCIEnvCreate(&Env, ...)
OCIHandleAlloc(Env, &Error, ...)
OCILogon(Env, Error
, &Servicio
, “user” , “pass”
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 29
Conexión compleja
Crear entorno Crear conexión Crear sesión
Poner sesión en contexto de servicio
Muchas posibilidades:
Conexión a varias máquinas Varias sesiones por máquina
Migración de sesiones entre conexiones
Entorno y conexión
OCIEnvCreate(&Env, ...)OCIHandleAlloc(Env, &Error, ...)
OCIHandleAlloc(Env, &Server, ...)
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 31
Sesión y servicio
OCIHandleAlloc(Env, &Sesion, ...) OCIAttrSet(Sesion, “user”, ...) OCIAttrSet(Sesion, “pass”, ...)
OCIHandleAlloc(Env, &Servicio, ...)
OCISessionBegin(Servicio, Sesion, ...) OCIAttrSet(Servicio, Server, ...)
OCIAttrSet(Servicio, Sesion, ...)
Ejecución de sentencias
Ubicar Handlers Preparación Bind de variables Define de variables EjecutarFetch para recuperar datos (SELECT )
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 33
Ejecución de sentencias
Caso complejo con SQL dinámicoCreación de handler
OCIHandleAlloc(Env , &hStmt , OCI_HTYPE_STMT , ...);jul-04 Alberto M.F.A. alb@lsi.uniovi.es 35
Preparación
Se precompila
Validación sintáctica y semántica
Preparación de estructuras en memoria
Se cachea la precompilación importante si
muchas ejecuciones repetidas
OCIStmtPrepare(hStmt, Error
, “Sentencia SQL”
, OCI_NTV_SYNTAX Sintaxis
, ...);
Bind y Define
Bind: asociar variables de entrada a la
sentencia con variables del programa
Define: asociar variables de salida de la
sentencia a las del programa
SELECT ename, sal, comm INTO
:emp_name, :salary, :commission
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 37
Placeholders
Marcadores dentro de la sentencia
Sintaxis :<nombre>
Solo validos para datos, no para
estructura
INSERT INTO :emp Inválido
VALUES (12345, ’OERTEL’ ,’WRITER’, 50000, 30)
Placeholders
También en PL/SQL char plsql_statement[] = "BEGIN \ RAISE_SALARY(:emp_number,:new_sal); \ END;";jul-04 Alberto M.F.A. alb@lsi.uniovi.es 39
Formas de Bind y Define
ByName OCIBindByName(...) OCIDefineByName(...) ByPos OCIBindByPos(...) OCIDefineByPos(...)
OCI<Bind/Define>ByName()
status = OCIBindByName(hStmt , &bnd1 Handler , hError, (text *)":ENAME” Placeholder
, strlen(":ENAME”) sizeof(“:ename”)
, emplName Puntero a var
, EMPL_NAME_LENGTH + 1 sizeof(variable)
, SQLT_STR Tipo dato
, NULL, NULL, NULL, 0, NULL , OCI_DEFAULT );
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 41
OCI<Bind/Define>ByPos()
status = OCIDefineByPos(hStmt , &dfn1 Handler , Error , 1 Posición, deptName Puntero a Var.
, sizeof(deptName)+1 Tamaño
, SQLT_STR Tipo dato
, NULL, NULL, NULL , OCI_DEFAULT);
sizeof(<B/D variable>)
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 43
Indicación de situaciones
especiales
En BIND o DEFINE:
Truncamientos por longitud NULL’s
En OCI<B/D>By<Name/Pos>() se
puede dar un puntero a sb2
Tipo definido en algún .h de OCI
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 45
Indicadores en Define
Ejemplo indicadores
OCIBindByName(hStmt , bnd2 , Error , (text *)":JOB" , -1 , ud->emplJob , EMPL_JOB_LENGTH + 1 , SQLT_STR , &indB2 Puntero a sb2jul-04 Alberto M.F.A. alb@lsi.uniovi.es 47
Empleo de indicadores
Al dar un dato a sentencia:
Si NULL ind = -1;
Resto de casos dato=3; ind=0;
Al leer un resultado a sentencia:
Si NULL ind == -1;
Resto de casos
if (ind >= 0) expr = dato * ...;
Ejecución de sentencias
status = OCIStmtExecute(SvcCtx handler servicio
, hStmt handler sentencia
, Error handler de error
, 1 nº de iteraciones
, 0 index en array si iter
, NULL snap-in
, NULL snap-out
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 49
Lectura de resultados
Si la sentencia retorna un conjunto de
datos (cursor)
Hay que iterar por el resultado
Si la sentencia devuelve una sola fila
OCIStatementExecute() ya deja los
resultados en las variables asociadas con
OCIDefineBy<name/pos>() y actualiza
los indicadores.
Iteración por el resultado
OCIStatementExecute(...)while (hay datos) {
proceso de datos ... OCIStmtFetch(...)
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 51
Iteración por el resultado
status = OCIStmtFetch(hStmt , Error
, 1 Nº filas a recuperar
, OCI_FETCH_NEXT Movimiento de cursor , OCI_DEFAULT
);
Ajustes de iteraciones
Para minimizar RoundTrips al servidor
se pueden ajustar cosas como:
Prefetch, cantidad de filas traídas en cada
lectura
Cantidad de memoria para prefetch
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 53
Transacciones
OCI soporta varios niveles de
transacción: Simple local
Serializable o Read-only Global
Transacciones simples
Cada sentencia inicia una Trx
A OCIStatementExecute() se le
puede indicar que trabaje en modo
OCI_COMMIT_ON_SUCCESS
Si no (OCI_DEFAULT) hay que cerrar
las transacciones explícitamente Si éxito COMMIT
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 55
Trx Serializables o Read-only
Se inician explicitamente con
OCITransStart(...)
Se debe parar el modo:
OCI_TRANS_SERIALIZABLE OCI_TRANS_READONLY
Trx globales
Son transacciones sofisticadas
Intervienen varios agentes
Pueden ser ramificadas
Commit en una o dos fases
One-Phase commit Two-Phase commit
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 57
Commit y RollBack
OCITransCommit(...) status = OCITransCommit( SvcCtx, Error, OCI_DEFAULT); OCITransRollBack(...) status = OCITransCommit( SvcCtx, Error, OCI_DEFAULT);Terminación de la aplicación
OCISessionEnd(...) OCIServerDetach(...)Para cada handle
OCIHandleFree(...)
Alternativa:
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 59
Manejo de errores
Cada llamada al API devuelve un status
status = OCI<funcion>(...
Se debería verificar el status después
de cada llamada
Puede dejar el código muy farragoso
Al menos chequear después de cada paso
importante
Acumular varios resultados (|| o |=)
Si status != OCI_SUCCESS
Se puede llamar a OCIGetError() para
recuperar información adicional.
Se puede llamar repetidamente a
OCIGetError() para recuperar todos los mensajes.
Cuando no hay más:
jul-04 Alberto M.F.A. alb@lsi.uniovi.es 61