You are on page 1of 12

ORACLE CALL INTERFACE

El objetivo de este documento es guiar su aprendizaje en el uso de la ORACLE CALL INTERFACE (OCI ! Las OCIs son inter"aces de programas de aplicaci#n (A$Is % &ue permiten ejecutar instrucciones de '(L desde un programa escrito en un lenguaje de tercera generaci#n (C% CO)OL% FORTRAN% etc! ! *na OCI es un conjunto de A$Is &ue permiten manipular )+ ORACLE% 'on librer,as &ue no necesitan ser recompiladas para ser utilizadas! 'e compilan - se enlazan igual &ue las aplicaciones &ue no son para )+s! Las OCIs permiten ejecutar instrucciones del ++L - del +.L de ORACLE% e incluso permite llamar a procedimientos - "unciones almacenadas! Un programa con OCI tiene la siguiente estructura: /! +e"inici#n de Estructuras para el establecimiento de la cone0i#n! 1! Establecimiento de cone0i#n ("uncion orlon - apertura de cursores de trabajo ("unci#n oopen ! 2! $reparaci#n del comando '(L o $L3'(L a ser ejecutado! ("unci#n oparse ! 4! 'i el comando posee variables an"itrionas - Establecimiento de asociaciones entre variables an"itrionas - variables del programa! ("uncion obnddrv ! 5! Ejecuci#n del comando ("uncion oe0ec ! 6! 'i el comando es una consulta - +escripci#n de los campos a ser pro-ectados por el 'ELECT% en caso de deconocer su n7mero - tipo ("unci#n odescr ! - Establecimiento de asociaciones entre variables del programa - campos pro-ectados por el select ("uncion ode"in ! - $rocesamiento de los resultados retornados por la consulta ("uncion o"etc8 ! 9! Cierre de cursores ("uncion oclose ! :! +escone0ion ("uncion ologo" ! En este documento se presenta un ejemplo para realizar% con un programa escrito en lenguaje C% las siguientes operaciones; Creaci#n de una tabla! Inserci#n interactiva de un conjunto de valores! Consulta para mostrar el contenido de la tabla! Eliminaci#n de la tabla!

A continuaci#n se describe la estructura de dic8o programa!

PARTE 1. Definicin de estructuras.


'uponga &ue se tienen las siguientes de"iniciones;
#include <stdio.h> #include <string.h> #include <stdlib.h> /* Librerias de definiciones de estructuras y funciones provistas * por la OCI */ #include <ocidfn.h> #include <ocidem.h> /* efinicion de los diferentes comandos a e!ecutar en el e!emplo */

#define C"#$%# &C"#$%# %$'L# (artes)(artno *+,'#")-..& #define I*/#"% &I*/#"% I*%O (artes 0alues )12(artno.& #define /#L#C% &/#L#C% * 3"O, (artes& #define "O( & "O( %$'L# (artes& #define O4 5 #define #""O" 6O4

$ara conectarse a un )+ ORACLE v,a OCI% es necesario de"inir almacenar in"ormaci#n concerniente a;

estructuras para

- Area de datos para login (logon data area-lda ; Lda<+e"! - Area de datos para el 8ost ( host data area-hda ; arreglo de caracteres de tama=o >+A<'I?E! - Area de datos para los cursores (cursor data area-cda ; Cda<+e"! Es necesario declarar un par lda-hda por cada cone0i#n &ue se tenga abierta concurrentemente! Adem@s% se tiene &ue tener un cda por cada cursor activo concurrentemente! El lda - el cda tienen un campo para retornar errores ocurridos durante la operaci#n! Es posible obtener el mensaje de error asociado a un c#digo utilizando la "unci#n oerhms;
/* 3uncion1 error * escripcion1 Imprime en pantalla el mensa!e asociado al codigo de error retornado por alguna de las operaciones.

* (arametros1 7 ,ens1 ,ensa!e adicional a ser impreso. * 7 Log1 datos asociados a la cone2ion. * 7 Cur1 datos asociados al cursor donde se produ!o la * operacion 8ue reporto error. * "etorna1 *ada. */

void error)char *,ens9Lda: ef Log9Cda: ef Cur. ; char #rr,sg<-5=>?@ /* 'uffer para almacenar los mensa!es */ /* Cur.rc es el campo del cursor data area 8ue contiene el codigo del error en caso de haberse producido */ oerhms)ALog9Cur.rc9#rr,sg9)int. siBeof)#rr,sg..@ fprintf)stderr9&#""O"1 CsDnDtCs&9,ens9#rr,sg.@ e2it)E.@ F

La de"inici#n de las estructuras del programa se tienen en la "unci#n AmainB% tal - como se presenta a continuaci#n;
void main). ; /* efinicion de las estructuras necesarias para el establecimiento de * la cone2ion con el mane!ador y almacenamiento de los resultados */ Lda: ef lda@ /* Login ata $rea */ char hda<G $:/IH#?@ /* Gost ata $rea */ Cda: ef cda@ /* Cursor ata $rea */ if )Cone2ion)Acda9Alda9hda.. error)&#stableciendo cone2ion&9lda9cda.@ fprintf)stdout9&Dn *** CO*#IIO* #/%$'L#CI $ ***DnDn&.@ if )Crear(artes)Acda.. error)&Creando la tabla partes&9lda9cda.@ if)Insertar(artes)Acda.. error)& urante la insercion de (artes&9lda9cda.@ if)Consultar(artes)Acda.. error)&Consultando partes&9lda9cda.@ if)#liminar(artes)Acda.. error)&#liminado la tabla partes&9lda9cda.@ if) esconectar)Alda9Acda.. error)& urante la descone2ion&9lda9cda.@ F

La "unci#n AmainB devuelve un error si alguna de las operaciones a ejecutar "alla! $ara ello% utiliza la "unci#n AerrorB% presentada anteriormente!

PARTE 2. Establecimiento de la conexin.


Como se observ# en la "unci#n AmainB% lo primero &ue 8a- &ue 8acer para trabajar con la )+ es conectarse con ORACLE (orlon - abrir los cursores de trabajo (oopen ;
/* 3uncion1 Cone2ion * /emantica1 #stablece una sesion con O"$CL# e inicialiBa un cursor de * traba!o.

* (arametros1 7 Cur1 #structura del cursor a ser inicialiBado. * 7 Log1 #strucutra para el mantenimiento de la informacion * de cone2ion. * 7 Gost1 #structura 8ue almacenara el Gost ata $rea. * "etorna1 O4 #n caso de 8ue todas las operaciones sean e2itosas. * #""O" en caso contrario. */ int Cone2ion)Cda: ef *Cur9Lda: ef *Log9 char *Gost. ; char +ser<>5?@ char (ass<>5?@ fprintf)stdout9&+suario1&.@ scanf)&Cs&9+ser.@ fprintf)stdout9&Clave1&.@ scanf)&Cs&9(ass.@ /* #stablecimiento de la cone2ion con el mane!ador */ if )orlon)Log9 /* 0ariable 8ue contendra el Login ata $rea */ Gost9 /* 0ariable 8ue contendra el Gost ata $rea */ )te2t *.+ser9 /* +ser7name con el 8ue se desea establecer la cone2ion */ strlen)+ser.9 /* Longitud del user7name )no necesario si el string esta terminado con D59 se pasa 7E . */ )te2t *. (ass9 /* Clave de acceso asociado al login */ strlen)(ass.9 /* Longitud de la clave de acceso )no necesario si el string esta terminado con D59 se pasa 7E . */ 7E. /* (arametro de compatibilidad de versiones9 siempre debe ser 5 o 7E */ . return)#""O".@ /* $pertura del cursor de traba!o */

if )oopen)Cur9 /* Cursor data area a ser definido. */ Log9 /* /esion a la 8ue se asociara este cursor */ )te2t *. 59 /* Incluido por compatibilidad de versiones en nuestro caso siempre debe ser 5 */ 7E9 /* Incluido por compatibilidad de versiones en nuestro caso siempre debe ser 7E */ 7E9 /* (arametro no utiliBado por esta version */ )te2t *. 59 /* Cadena de caracteres 8ue representa el login y el passJord a ser utiliBados9 separados por /. */ 7E. /* Longitud de la cadena login/passJord */ . return)#""O".@ return)O4.@

*n programa OCI puede conectarse m7ltiples veces a una o m@s instancias de ORACLE! La comunicaci#n tiene lugar utilizando el lda - el hda de"inidos en el programa! La "unci#n orlon conecta el lda a ORACLE! Cada llamada a orlon tiene asociada un hda de un tama=o dado! Aun&ue el contenido del hda es privado de ORACLE% el espacio es solicitado por el programa OCI! *na vez establecida la cone0i#n% es necesario crear el cda asociado a Csta (al menos un cda% si no se tienen cursores concurrentes ! ORACLE utiliza este espacio para mantener in"ormaci#n de estado acerca del procesamiento de las sentencias de '(L! La creaci#n de un cda se 8ace utilizando la "unci#n oopen! +espuCs de establecer la cone0i#n - abrir el cursor de trabajo% es posible comenzar a ejecutar las operaciones sobre la )+ ORACLE!

PARTE 3. Creacin de una tabla


La primera tarea propuesta en este ejemplo es la creaci#n de una tabla% es decir% la ejecuci#n de la sentencia de '(L; DC"#$%# %$'L# (artes)(artno *+,'#")-..D% de"inida como la constante C"#$%# del programa! $ara ejecutar esta sentencia desde el programa OCI 8a- &ue veri"icar su correctitud% utilizando la "unci#n oparse - luego 8a&ue ejecutarla% utilizando la "unci#n oexec!
/* 3uncion1 Crear(artes * /emantica1 Crea una tabla para el almacenamiento de componentes. * (arametros1 7 Cur1 $rea de datos del cursor activo. * "etorna1 O4 #n caso de 8ue todas las operaciones sean e2itosas. * #""O" en caso contrario. */ int Crear(artes)Cda: ef *Cur. ; /* (reparacion de la instruccion para la e!ecucion1 * )%oda instruccion /KL debe pasar por LoparseL. */ if )oparse)Cur9 /* $rea de datos del cursor a utiliBar */ C"#$%#9 /* ,acro 8ue contiene la sentencia a e!ecutar */ 7E9 /* Longitud de la sentencia a ser e!ecutada )si el string 8ue representa el comando termina en LD5L este parametro puede ser omitido. */ 59 /* #33LM1 (ara instrucciones del L 5 indica 8ue la sentencia se e!ecutara automaticamente)no se re8uiere procesamiento posterior. N5 indica 8ue se e!ecutara con la invocacion de oe2ec9oe2n o oe2fet (ara instrucciones del ,L siempre se necesita procesamiento posterior. OJO: /e realiBaron pruebas y la combinacion 8ue funciono fue 5 O oe2ec */ -. /* 3orma de intepretar y mane!ar el comando1 51 0ersion P de O"$CL#. E1 0ersion P y Q dependiendo de la version con la 8ue se tenga la cone2ion. -1 0ersion Q*/ . return)#""O".@ /* #!ecucion de la instruccion */ if)oe2ec)Cur.. return)#""O".@ return)O4.@ F

La "unci#n oparse no s#lo veri"ica la correctitud de la sentencia '(L% sino &ue se encarga de almacenar la sentencia (una representaci#n de Csta para &ue pueda ser

ejecutada! Esta ejecuci#n se realiza utilizando el nombre del cda activo(vea la invocaci#n de la "unci#n oexec ! *n cursor abierto puede ser AreutilizadoB dentro de un programa% por subsecuentes llamadas a la "unci#n oparse!

PARTE 4. Insercin interacti a de un con!unto de alores


En este caso% se desea insertar un conjunto de c#digos en la tabla $artes! Los c#digos no aparecen e0pl,citamente en el c#digo del programa! 'e le pide al usuario% interactivamente% &ue suministre los c#digos a insertar en la tabla% uno a uno! $ara ello% se solicita el valor del c#digo - Cste se almacena en una variable del programa! La sentencia '(L 8ace re"erencia a esta variable como la "uente del valor a insertar; DI*/#"% I*%O (artes 0alues ):xPartno.D! $or lo tanto% para realizar la inserci#n no basta con preparar la sentencia (oparse - ejecutarla (oexec % sino &ue 8a- &ue indicar% de alguna manera% el lugar de la memoria de donde se deber@ tomar el valor del c#digo a insertar ( obndrv % es decir% 8a- &ue establecer el enlace entre las variables del programa ((artno - las variables an"itrionas de la sentencia '(L (2(artno !
/* 3uncion1 Insertar(artes * /emantica1 Inserta interactivamente codigos en la tabla (artes. * (arametros1 Cursor $ctivo * "etorna1 O4 #n caso de 8ue todas las operaciones sean e2itosas. * #""O" en caso contrario. */ int Insertar(artes)Cda: ef *Cur. ; int (artno@ /* 0ariable 8ue servira como asociacion para variables anfitrionas */ if )oparse)Cur9 I*/#"%9 7E9 59 -.. return)#""O".@ /* #stablecimiento de enlace entre variables de programa y variables * anfitrionas. */ if )obndrv)Cur9 &12(artno&9 /* *ombre de la variable anfitriona a ser enlaBada. (roviene del te2to 8ue define la instruccion1 I*/#"% */ 7E9 /* Longitud del nombre de la variable. )se puede ignorar si el string 8ue representa el nombre termina en /5. */ A(artno9 /* $puntador a la variable del programa a ser enlaBada con la variable anfitriona. */ siBeof)int.9 /* %amanio de la variable a ser utiliBada */ R9 /* %ipo de datos de la variable de programa para poder ser convertida a un tipo interno de O"$CL#. )0er %abla E. */ 7E9 /* (recision de los decimales empa8uetados9 no usado en C. */ )char *. 59 /* 0ariable indicadora9 un valor negativo implicara 8ue la variable anfitriona tome el valor *+LL */

)char *. 59 7E9 7E. . return)#""O".@

/* (arametro no utiliBado en C */ /* (armetro no utiliBado en C */ /* (arametro no utiliBado en C */

for)@@. ; fprintf)stdout9&IntroduBca el numero de la parte )7E terminar.1&.@ scanf)&Cd&9A(artno.@ if )(artno SS 7E. ; printf)&Dn*** 3I* # L$/ I*/#"CIO*#/ ***DnDn&.@ breaT@ F if)oe2ec)Cur.. return)#""O".@ F return)O4.@ F

A continuacin se presenta la tabla de equi alencias entre los tipos de datos de C ! los de ORACLE "Tabla #$:
Tipo de ORACLE 0$"CG$"*+,'#" >7bit signed I*%#M#" EP7bit signed I*%#M#" R-7bit signed I*%#M#" 3LO$% *ull7terminated /%"I*M 0$"*+, ($C4# #CI,$L LO*M 0$"CG$" "OWI $%# 0$""$W "$W LO*M "$W +*/IM*# I*% I/(L$X LO*M 0$"CG$" LO*M 0$""$W CG$" CG$"H ,L/L$'#L Cdigo E R R R = U P Q > V EE EEU -R -= P> VE V= VU VP VQ E5P Tipo de C char<n?E +nsigned char<-E? signed char signed short9 signed int signed int9 signed long float9double char<nOE? char<--? */$ char<n? char<nOslen?char<n? char<Q? +nsigned char<nOslen? +nsigned char<n? +nsigned char<n? +nsigned */$ char<nOilen?R +nsigned char<nOilen? char<n? char<nOE? char<n?

Tabla # % Equi alencia entre los Tipos de &atos de Lengua'e C ! los de ORACLE(

La longitud n es variable - depende de los re&uerimientos del programa slen representa el tama=o en b-tes de un s8ort int 2 ilen representa el tama=o en b-tes de un int
/ 1

Estas e&uivalencias son necesarias no s#lo para insertar elementos en una tabla% sino para realizar consultas% tal - como se muestra en el siguiente paso!

PARTE ". Consulta de una tabla


Cuando el comando a ejecutar es una consulta% tambiCn es necesario establecer los v,nculos% no s#lo con las variables del programa &ue puedan intervenir% sino con los elementos del la lista de atributos a seleccionar! Adem@s% es necesario 8acer fetch de los resultados obtenidos despuCs de la ejecuci#n de la consulta! En este caso se desea recuperar el contenido de toda la tabla $artes; D/#L#C% * 3"O, (artesD!
/* 3uncion1 Consultar(artes * /emantica1 ,uestra en la salida estandar el contenido de la tabla * (artes. * (arametros1 Cursor activo. * "etorna1 O4 #n caso de 8ue todas las operaciones sean e2itosas. * #""O" en caso contrario. */ int Consultar(artes)Cda: ef *Cur. ; int (artno@ printf)&Dn 0$LO"#/ CO*%#*I O/ #* L$ %$'L$ (artesDnDn&.@ printf)&($"%*ODnDn&.@ if )oparse)Cur9 /#L#C%9 7E9 59 -.. return)#""O".@ if)oe2ec)Cur.. return)#""O".@ /* #stablecimiento de las asociaciones entre las variables de salida )select * 7list. y las variables de programa )se hace un odefin por cada una de los * items en el select7list.. */ if)odefin)Cur9 E9 /* (osicion del resultado a ser enlaBado en relacion a los campos proyectados por el /#L#C% */ A(artno9 /* ireccion de la variable de programa 8ue recibira los diferentes valores para esta columna proyectada */ siBeof)int.9 /* %amanio de la variable a ser utiliBada */ R9 /* %ipo de datos de la variable de programa para poder ser convertida a un tipo interno de O"$CL#. )0er %abla E. */ 7E9 /* #scala de los decimales empa8uetados. *o +tiliBado en C */ )int *. 59 /* ireccion de la variable de programa 8ue servira de indicadora de valores nulos */ 59 /* *o utiliBado en C */ 7E9 /* *o utiliBado en C */

7E9 59

5.

/* *o utiliBado en C */ /* #n caso de recuperacion de datos de longitud variable este campo almacena el tamanio del dato recuperado despues de ser e!ecutada la operacion de fetch */ /* Codigo de error de la columa )0alor %runcado90alor nulo9 entre otros.. #ste valor es actualiBado despues de e!ecutada la operacion de fetch */

. return)#""O".@ /* "ecuperacion de resultados */ for)@@. ; if)ofetch)Cur.. ; /* 0erificacion de 8ue el error en la operacion de * fetch fue por no e2istir mas datos 8ue ser recuperados */ if )Cur7>rc S *O: $%$:3O+* . breaT@ return)#""O".@ F fprintf)stdout9&CdDn&9(artno.@ F return)O4.@ F

Como se observa% la secuencia de operaciones &ue 8a- &ue realizar para ejecutar una consulta es la siguiente; - $reparaci#n de la sentencia (oparse ! - Ejecuci#n de la sentencia (oexec ! - Establecimiento de la relaci#n entre las columnas devueltas por la consulta - las variables del programa (odefin ! 'e realiza un odefin por cada una de las columnas del selectFlist! - Recuperaci#n de las "ilas devueltas por la consulta (ofetch !

/G

PARTE #. Eliminacin de tablas


La 7ltima tarea propuesta en este ejemplo% es la eliminaci#n de la tabla $artes;
/* 3uncion1 #liminar(artes * /emantica1 #liminacion de la tabla de partes. * (arametros1 7 Cur1 $rea de atos del cursor a ser asociado a la * operacion. * "etorna1 O4 #n caso de 8ue todas las operaciones sean e2itosas. * #""O" en caso contrario. */ int #liminar(artes)Cda: ef *Cur. ; if )oparse)Cur9 "O(9 7E9 59 -.. return)#""O".@ if)oe2ec)Cur.. return)#""O".@ return)O4.@ F

PARTE $. Desconexin
*na vez realizadas todas las tareas propuestas en el ejemplo% es necesario desconectarse del manejador ORACLE - liberar todos los recursos solicitados para la cone0i#n!
/* 3uncion1 esconectar * /emantica1 Libera los recursos asociados a el area de datos del * Cursor y cierra la cone2ion con el mane!ador. * (arametros1 7 Cur1 $rea de datos del cursor a ser liberado. * 7 Log1 $rea de datos de login de la cone2ion a ser * cerrada. * "etorna1 O4 #n caso de 8ue todas las operaciones sean e2itosas. * #""O" en caso contrario. */ int esconectar)Lda: ef *Log9 Cda: ef *Cur. ; if )oclose)Cur.. return)#""O".@ if )ologof)Log.. return)#""O".@ return)O4.@ F

//

%eneracin de un e!ecutable
$ara poder crear el ejecutable de su aplicacion &ue contiene llamadas a las librer,as provistas por ORACLE% una vez &ue terminada la implementaci#n (arc8ivo(s !c - !8 de su aplicaci#n% es necesario modi"icar el makefile b@sico provisto por ORACLE (oracle!mH % el cual se encuentra en el directorio 3opt3oracle3rdbms3lib% agregando una l,nea de la siguiente "orma;
<nombre de la aplicaciYn> 1 <nombre del archivo con la implementaciYn de la aplicaciYn>.o Z),$4# #,O.

Esta l,nea puede agregarse despuCs de los comandos de compilacion de los demos provistos por ORACLE! I.$ORTANTE Este maHe"ile tiene como compilador de C a cc! $ara cambiar el compilador basta con cambiar la variable CC de"inida dentro del makefile por el compilador &ue se desee utilizar!

/1

You might also like