Oracle Call Interface (OCI) NGUYEN TIEN Dung Univerzita Karlova Matematicko-fyzikální fakulta Last modified : 06.12.2007
Co je OCI? low-level aplikační rozhraní (API) umožňující aplikacím psaným v hostitelském jazyce (např. v C) komunikovat s jedním či více Oracle servery umožňuje aplikaci manipulovat s objekty databáze jednotlivé funkce jsou přímo konstrukcí programovacího jazyka, nejedná se o preprocesor jako u Embeded SQL konzistentní rozhraní pro dynamické relace a správu transakcí ve dvouvrstvém klient-server a vícevrstvém prostředí N-vrstvová autentizace NGUYEN TIEN Dung - MFF UK 2
Výhody snadný přístup k metadatům Oracle serveru ladění, ladí se aplikace pouze v cílovém jazyce, žádný preprocesor dostupnost dynamického SQL asynchronní zpracování příkazů NGUYEN TIEN Dung - MFF UK 3
Části OCI OCI lze rozdělit na 5 hlavních množin funkčností: API pro vytváření vícevláknových aplikací funkce pro zpracování SQL příkazů a manipulaci se získanými objekty mapování datových typů a funkcí pro manipulaci s atributy Oracle datových typů funkce pro zpřístupnění dat z databáze bez použití SQL funkce externích procedur, které zapisují Céčkovská zpětná volání (callbacky) z PL/SQL NGUYEN TIEN Dung - MFF UK 4
Překlad OCI aplikace NGUYEN TIEN Dung - MFF UK 5
Struktura programu používající OCI inicializace programového prostředí a procesů OCI alokace potřebných handlů, navázání spojení se serverem a zahájení uživatelské relace (session). posílání SQL příkazů serveru a případné zpracování dat uvolnění handlů, které již nebudou použity, příprava nových příkazů ukončení uživatelské relace a uzavření spojení se serverem NGUYEN TIEN Dung - MFF UK 6
Struktura programu používající OCI 2 NGUYEN TIEN Dung - MFF UK 7
Inicializace prostředí volání OCI funkcí se provádí v kontextu prostředí kontext prostředí se vytváří zavoláním OCIEnvCreate() funkci je potřeba zavolat před voláním jiných funkcí OCI NGUYEN TIEN Dung - MFF UK 8
Inicializace prostředí sword OCIEnvCreate ( OCIEnv **envhpp, ub4 mode, CONST dvoid *ctxp, CONST dvoid *(*malocfp) (dvoid *ctxp, size_t size), CONST dvoid *(*ralocfp) (dvoid *ctxp, dvoid *memptr, size_t newsize), CONST void (*mfreefp) (dvoid *ctxp, dvoid *memptr)) size_t xtramemsz, dvoid **usrmempp ); NGUYEN TIEN Dung - MFF UK 9
Inicializace prostředí 2 význam jednotlivých parametrů: envhpp (out) - ukazatel na handle prostředí, který funkce inicializuje mode - specifikuje způsob, jakým bude aplikace volat funkce z OCI, běžně stačí OCI_DEFAULT, prostředí s vlákny (OCI_THREADED), použití objektů (OCI_OBJECT), použití sdílených datových struktur (OCI_SHARED) (kombinace jednotlivých parametrů pomocí binárního OR) ctxp - uživatelsky definovaný kontext pro funkce alokující/dealokující paměť malocfp, ralocfp, mfreefp - ukazatele na funkce alokující, realokující a uvolňující paměť xtramemsz, usrmempp (out) - vrátí extra paměť zadané velikosti pro uživatelské informace NGUYEN TIEN Dung - MFF UK 10
Inicializace prostředí 3 Příklad použití: OCIEnvCreate ( &myenvhp, OCI_THREADED OCI_OBJECT, (dvoid *)0, mymalloc, myrealloc, myfree, 0, (dvoid **)0 ) NGUYEN TIEN Dung - MFF UK 11
Alokace handles funkce OCI používají jako své parametry handle, ukazatele na vnitřní struktury, v které jsou uložené atributy před předáváním handlů funkcím OCI, je třeba je inicializovat k tomu slouží OCIHandleAlloc() OCIAttrGet() získání parametru struktury, OCIAttrSet() změna parametru struktury NGUYEN TIEN Dung - MFF UK 12
Alokace handles 2 OCIHandleAlloc ( CONST dvoid*parenth, Dvoid **hndlpp, ub4 type, size_t xtramem_sz, dvoid **usrmempp ); NGUYEN TIEN Dung - MFF UK 13
Alokace handles 3 význam jednotlivých parametrů: parenth - (inicializovaný) environment handle hndlpp (out) - vrátí alokovaný handle type - typ handle, který alokujeme, každému typu handlu OCIněco odpovídá konstanta OCI_HTYPE_něco NGUYEN TIEN Dung - MFF UK 14
Alokace handles 4 Příklad použití: OCIHandleAlloc ( (dvoid *)myenvhp, (dvoid **)&mysrvhp, OCI_HTYPE_ERROR, 0, (dvoid **) 0 ) NGUYEN TIEN Dung - MFF UK 15
Důležité handles Environment Handle definice kontextu pro volání OCI funkce (C typ OCIEnv) Error Handle ošetření chyb (C typ OCIError). Service Context Handle identifikace zdroje dat, uživatelských práv a dalších informací, v jejichž kontextu se provádí příkazy na serveru (C typ OCISvcCtx). Statement Handle slouží při posílání SQL a PL/SQL příkazů serveru (C typ OCIStmt). NGUYEN TIEN Dung - MFF UK 16
Navázání spojení a zahájení relace liší se podle toho, zda chceme jednoho uživatele a jedno spojení nebo více spojení a více relací. typicky jeden uživatel, jedno spojení Spojení se naváže zavoláním funkce OCILogon(). NGUYEN TIEN Dung - MFF UK 17
Navázání spojení a zahájení relace 2 Příklad použití: OCILogon( envhp, errhp, &svchp, "dbadmin", strlen("dbadmin"), semora7dbi", strlen( semora7dbi"), "DB7SEMORA", strlen("db7semora") ); NGUYEN TIEN Dung - MFF UK 18
Navázání spojení a zahájení relace 3 pro více relací nebo spojení se zavolá nejprve OCIServerAttach(), která vytvoří přístupovou cestu na server pro OCI operace a potom OCISessionBegin(), která vytvoří relaci NGUYEN TIEN Dung - MFF UK 19
Ukončení aplikace Aplikace by před svým ukončením měla provést následující kroky: Pokud se aplikace připojila k databázi pomocí OCILogon() potom by měla zavolat OCILogoff() ukončení relace, odpojení serveru, uvolní service context a asociované handly voláním OCIHandleFree() uvolnit všechny handly které sama alokovala NGUYEN TIEN Dung - MFF UK 20
Ukončení aplikace 2 OCILogoff ( OCISvcCtx *svchp, OCIError *errhp ); OCIHandleFree ( dvoid *hndlp, ub4 type ); NGUYEN TIEN Dung - MFF UK 21
Příklad programu #include <stdio.h> #include <stdlib.h> #include <string.h> #include <oci.h> static OCIEnv *p_env; static OCIError *p_err; static OCISvcCtx *p_svc; static OCIStmt *p_sql; static OCIDefine *p_dfn = (OCIDefine *) 0; static OCIBind *p_bnd = (OCIBind *) 0; NGUYEN TIEN Dung - MFF UK 22
Příklad programu /* Initialize OCI */ rc = OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *)) 0 ); /* Initialize evironment */ rc = OCIEnvInit( (OCIEnv **) &p_env, OCI_DEFAULT, (size_t) 0, (dvoid **) 0 ); NGUYEN TIEN Dung - MFF UK 23
Příklad programu /* Initialize handles */ rc = OCIHandleAlloc( (dvoid *) p_env, (dvoid **) &p_err, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0); rc = OCIHandleAlloc( (dvoid *) p_env, (dvoid **) &p_svc, OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0); NGUYEN TIEN Dung - MFF UK 24
Příklad programu /* Connect to database server */ rc = OCILogon(p_env, p_err, &p_svc, "scott", 5, "tiger", 5, "d458_nat", 8); if (rc!= 0) { OCIErrorGet((dvoid *)p_err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); printf("error - %.*s\n", 512, errbuf); exit(8); } NGUYEN TIEN Dung - MFF UK 25
Příklad programu /* Allocate & prepare SQL statement */ rc = OCIHandleAlloc( (dvoid *) p_env, (dvoid **) &p_sql, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0); rc = OCIStmtPrepare(p_sql, p_err, "select ename from emp where deptno=:x", (ub4) 37, (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT); NGUYEN TIEN Dung - MFF UK 26
Příklad programu /* Bind the values for the bind variables */ p_bvi = 10; /* Use DEPTNO=10 */ rc = OCIBindByName(p_sql, &p_bnd, p_err, (text *) ":x", -1, (dvoid *) &p_bvi, sizeof(int), SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT); /* Define the select list items */ rc = OCIDefineByPos(p_sql, &p_dfn, p_err, 1, (dvoid *) &p_sli, (sword) 20, SQLT_STR, (dvoid *) 0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT); NGUYEN TIEN Dung - MFF UK 27
Příklad programu /* Execute the SQL statement */ rc = OCIStmtExecute(p_svc, p_sql, p_err, (ub4) 1, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT); while (rc!= OCI_NO_DATA) { /* Fetch the remaining data */ printf("%s\n",p_sli); rc = OCIStmtFetch(p_sql, p_err, 1, 0, 0); } NGUYEN TIEN Dung - MFF UK 28
Příklad programu /* Disconnect */ rc = OCILogoff(p_svc, p_err); rc = OCIHandleFree((dvoid *) p_sql, OCI_HTYPE_STMT); /* Free handles */ rc = OCIHandleFree((dvoid *) p_svc, OCI_HTYPE_SVCCTX); rc = OCIHandleFree((dvoid *) p_err, OCI_HTYPE_ERROR); NGUYEN TIEN Dung - MFF UK 29
Make příkaz na Matesu make -f /opt/oracle/ora920/rdbms/demo/demo _rdbms.mk EXE=main OBJS= example.o" build NGUYEN TIEN Dung - MFF UK 30
Zdroje Oracle Call Interface Programmer's Guide http://download.oracle.com/docs/cd/b14117_01/a ppdev.101/b10779/toc.htm Oracle Call Interface FAQ http://www.orafaq.com/faqoci.htm OCI Examples http://docs.huihoo.com/oracle/docs/b19306_01/se rver.102/b14257/ap_oci.htm NGUYEN TIEN Dung - MFF UK 31