extension=php_mysql.dll ;extension=php_oci8.dll ; Use with Oracle 10g, 11g, 12c Instant Client ;extension=php_oci8_11g.dll ; Use with Oracle 11g, 12c Instant Client extension=php_oci8_12c.dll ; Use with Oracle 12c Instant ClientPentru gestiunea bazelor de date Oracle versiunile 10g, 11g şi 12c se poate folosi extensia precizată de linia: "extension=php_oci8.dll".
resource oci_connect(string $username, string $password [, string $connection_string [, string $character_set [, int $session_mode ]]])
Funcţia oci_new_connect are aceiaşi parametri ca oci_connect.
Conecţiunile deschise cu oci_connect şi oci_new_connect sunt automat închise la sfârşitul scriptului. Cu funcţia oci_pconnect se poate crea o conecţiune care nu se închide la sfârşitul scriptului, deci se poate reutiliza în alte scripturi.
Funcţia furnizează o eroare sau un identificator de conectare (util la execuţia altor funcţii).
ORCL12 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 172.30.33.0)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = orcl12) ) ) ORCL10 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 172.30.33.1)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = orcl10) ) ) ORCL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = orcl) ) )
$idc = oci_connect('system', 'oracle', 'orcl'); $idc = oci_connect('system', 'oracle', '//127.0.0.1:1521/orcl'); $idc = oci_connect('system', 'oracle', '//localhost:1521/orcl'); $idc = oci_connect('system', 'oracle', '//localhost:1521/orcl:DEDICATED/orcl'); $idc = oci_connect('system', 'oracle', '172.30.33.1:1521/orcl10');
bool oci_close(resource $id_conectare)
resource oci_parse(resource $id_conectare, string $text_sql)
pregăteşte o instrucţiune SQL sau un bloc PL/SQL pentru execuţie.
Această funcţie furnizează un identificator de instrucţiune (ce va fi utilizat de alte funcţii care folosesc textul analizat).
Resursa identificată de acest identificator de instrucţiune se poate elibera prin:
oci_free_statement(resource $id_instructiune)
bool oci_execute(resource $id_instructiune [, int $mode = OCI_COMMIT_ON_SUCCESS])
execută un text sql pregătit de oci_parse
(o instrucţiune SQL sau un bloc PL/SQL, care se identifică cu primul parametru).
Al doilea parametru precizează modul în care sunt tratate
modificările în baza de date (dacă se execută astfel de instrucţiuni), implicit se face un COMMIT dacă nu au apărut erori.
Valoarea funcţiei este TRUE (textul s-a executat) sau FALSE (la execuţie au apărut erori).
bool oci_fetch(resource $id_instructiune)
furnizează următoarea înregistrare din rezultatul identificat de primul argument. Coloanele din rezultat se pot folosi prin intermediul unor variabile precizate de funcţia oci_define_by_name.
bool oci_define_by_name(resource $id_instructiune, string $nume_coloana, $variabila)
asociază
o denumire de variabilă (se va folosi în PHP) la o coloană (precizată în instrucţiunea SQL). O astfel de asociere este necesară dacă instrucţiunea identificată
de primul parametru furnizează un rezultat (de exemplu avem o instrucţiune SELECT) şi rezultatul se consultă cu oci_fetch.
O astfel de asociere se face înainte de execuţia instrucţiunii (cu oci_execute).
<?php $con = oci_connect("master", "master", "orcl10"); // conectiune if (!$con) { $er = oci_error(); echo $er['code'].'-'.$er['message']; die(); } $s = 'select cod,denumire from judete order by cod'; $idi = oci_parse($con, $s); //asociaza denumiri de variabile (php) la nume de coloane (sql) //denumirile de coloane se precizeaza cu litere mari (asa sunt memorate in dictionar) oci_define_by_name($idi, 'COD', $cod); oci_define_by_name($idi, 'DENUMIRE', $den); oci_execute($idi); $n=0; while (oci_fetch($idi)) { $n++; echo $n.'. '.$cod.' - '.$den.'<br>'; } oci_free_statement($idi); oci_close($con); ?>
array oci_fetch_row(resource $id_instructiune)
furnizează într-un vector cu indici (precizaţi prin numere, prima coloană are indicele 0) următoarea
înregistrare din rezultatul identificat de argument.
Valoarea funcţiei este false dacă nu există o următoare înregistrare.
$s = 'select cod,denumire from judete order by cod'; $idi = oci_parse($con, $s); oci_execute($idi); $n=0; while ($r = oci_fetch_row($idi)) { $n++; echo $n.'. '.$r[0].' - '.$r[1].'<br>'; }
array oci_fetch_assoc(resource $id_instructiune)
furnizează într-un vector associativ (indicii pentru vector sunt denumirile coloanelor,
precizate cu litere mari) următoarea înregistrare din rezultatul identificat de argument.
Valoarea funcţiei este false dacă nu există o următoare înregistrare.
$s = 'select cod,denumire from judete order by cod'; $idi = oci_parse($con, $s); oci_execute($idi); $n=0; while ($r = oci_fetch_assoc($idi)) { $n++; echo $n.'. '.$r['COD'].' - '.$r['DENUMIRE'].'<br>'; }
object oci_fetch_object(resource $id_instructiune)
furnizează într-un obiect următoarea
înregistrare din rezultatul identificat de argument. Coloanele din rezultat sunt proprietăţi ale acestui obiect (precizate cu litere mari).
Valoarea funcţiei este false dacă nu există o următoare înregistrare.
$s = 'select cod,denumire from judete order by cod'; $idi = oci_parse($con, $s); oci_execute($idi); $n=0; while ($r = oci_fetch_object($idi)) { $n++; echo $n.'. '.$r->COD.' - '.$r->DENUMIRE.'<br>'; }
array oci_fetch_array(resource $id_instructiune [, int $mod_utilizare])
se furnizează într-un vector (associativ sau cu indici numere) următoarea înregistrare din rezultatul identificat de primul argument. Modul în care se pot folosi poziţiile din vector este precizat de al doilea parametru:
int oci_fetch_all(resource $id_instructiune, array $variabila)
furnizează într-un array bidimensional (matrice)
toate înregistrările din rezultatul identificat de primul argument.
Cu această variantă se obţin toate înregistrările, deci funcţia se poate apela o singură dată după oci_execute.
In funcţie se pot include şi alţi parametrii pentru identificarea înregistrărilor care se copiază în matrice.
Valoarea funcţiei poate fi false (dacă apare o eroare), sau numărul de înregistrări din rezultat (0, 1, ...).
int oci_num_fields(resource $id_instructiune)
furnizează numărul de coloane din rezultat
int oci_num_rows (resource $id_instructiune)
care furnizează numărul de linii (înregistrări) afectate de ultima instrucţiune.
$s = 'create table temp1 (x varchar2(20))'; $idi = oci_parse($con, $s); $id=oci_execute($idi); if ($id){ echo 'Tabelul temp1 s-a creat<br>'; }else{ die('Eroare la crearea tabelului'); } $s = 'insert into temp1 select denumire from judete'; $idi = oci_parse($con, $s); oci_execute($idi); echo 'S-au adaugat '.oci_num_rows($idi).' inregistrari<br>'; $s = 'drop table temp1'; $idi = oci_parse($con, $s); $id=oci_execute($idi); if ($id){ echo 'Tabelul temp1 s-a sters<br>'; }else{ die('Eroare la stergerea tabelului'); }
$s = "declare ". " cursor stud(s char) is". " select distinct st.*". " from studenti st ". " where sectia=s order by nume,prenume;". " x stud%rowtype;". "begin". " dbms_output.enable;". " for x in stud('43') loop". " insert into temp1(x) values(trim(x.nume) || ' ' || trim(x.prenume));". " end loop;". "end;"; $idi = oci_parse($con, $s); $id=oci_execute($idi);
Observaţie. Dacă se foloseşte Windows şi atribuirea se face astfel (textul apare pe mai multe linii):
$s = "declare cursor stud(s char) is select distinct st.* . . . end;";
atunci va apare o eroare la compilare, deoarece la finalul fiecărei linii apar caracterele "carriage-return" şi "linefeed".
select * from studenti where grupa=:g; select * from studenti where REGEXP_LIKE(nume, :s); insert into studenti(nume,prenume) values(:n, :p); update studenti set nume=:n where nrmatricol=:nm; begin :v:=to_char(eval(:expresie)); end; begin pstudenti.NrStud(2,:s); end;
Pentru a stabili o legătură între o "variabilă legată" (din textul sql analizat de funcţia oci_parse, indiferent
dacă este parametru de intrare sau parametru de ieşire) şi o variabilă PHP se poate folosi funcţia:
bool oci_bind_by_name (resource $id_instructiune , string $variabila_legata , mixed $variabila_php [, int $maxlength = -1 [, int $type = SQLT_CHR]] )
unde: id_instructiune este furnizat de oci_parse, al doilea argument are ca valoare o denumire de variabilă legată (precedată de ":" în textul sql şi în această funcţie), iar al treilea argument este o variabilă php. Lungimea valorilor pentru variabila php este dată de valoarea curentă a acestei variabile, sau de al patrulea argument. Tipul valorilor este precizat de argumentul "type" (implicit este un şir de caractere, alte valori se pot vedea în documentaţia PHP pentru această funcţie). Această asociere se face înainte de execuţia instrucţiunii.
Tot înainte de execuţia unor astfel de instrucţiuni este necesară atribuirea unei valori pentru "variabilele legate" care sunt parametri de intrare, iar
după execuţie (proceduri, funcţii, bloc) se poate folosi valoarea unora dintre aceste variabile (care sunt parametri de ieşire).
$s="begin :v:=to_char(eval(:expresie)); end;"; //eval este o functie definita de utilizator (vezi curs/fisiere/plsql07.htm) $idi = oci_parse($con, $s); $e="sysdate+2000"; oci_bind_by_name($idi, ":expresie", $e); oci_bind_by_name($idi, ":v", $v, 30); $id=oci_execute($idi); echo "Evaluarea pentru: '".$e."' este: ".$v."<br>"; $s="begin pstudenti.NrStud(:s,:v); end;"; //NrStud este o procedura din pachetul pstudenti $idi = oci_parse($con, $s); $sectia=2; oci_bind_by_name($idi, ":s", $sectia); oci_bind_by_name($idi, ":v", $v, 100, SQLT_CHR); $id=oci_execute($idi); echo "Repartizarea studentilor de la sectia: '".$sectia."' pe intervale de medie este: ".$v."<br>"; $s="begin :nr:=pstudenti.NrStudMedia(:s, :m1, :m2); end;"; //NrStudMedia este o functie din pachetul pstudenti $idi = oci_parse($con, $s); $sectia=2; $m1=7.33; $m2=9.66; $nr=1000; oci_bind_by_name($idi, ":s", $sectia); oci_bind_by_name($idi, ":m1", $m1); oci_bind_by_name($idi, ":m2", $m2); oci_bind_by_name($idi, ":nr", $nr); $id=oci_execute($idi); echo "Numarul studentilor de la sectia: '".$sectia."' cu media intre: ".$m1." si ".$m2." este: ".$nr."<br>";
oci_bind_array_by_name(resource $id_instructiune , string $variabila_legata , mixed $variabila_array_php , int $max_length_array = -1 [, int $maxlength = -1 [, int $type = SQLT_AFC ]] )
unde a apărut în plus faţă de oci_bind_by_name parametrul $max_length_array care precizează
lungimea maximă (ca număr
de componente) din array (variabila din PHP).
Tipul variabilei poate fi: SQLT_AFC (array de CHAR), SQLT_CHR (array de VARCHAR2), etc.
Considerăm sursa de date:
şi pachetul definit astfel:
create or replace package p2 as TYPE listas is table of varchar2(70) index by binary_integer; procedure stud(lista out listas, m1 in number, m2 in number); end; create or replace package body p2 as procedure stud(lista out listas, m1 in number, m2 in number) as CURSOR c(m1 in number, m2 in number) IS SELECT nume,prenume from infstud where media between m1 and m2; s listas; st c%rowtype; i integer:=0; begin for st in c(m1,m2) loop i:=i+1; s(i):=trim(st.nume) || ' ' || trim(st.prenume); end loop; lista:=s; end; end;
Folosirea procedurii p2.stud în PHP se poate face astfel:
$a=array(); //procedure stud(lista out listas, m1 in number, m2 in number); $s="begin p2.stud(:lista, :m1, :m2); end;"; $idi = oci_parse($con, $s); $m1=8.33; $m2=9.66; oci_bind_array_by_name($idi, ":lista", $a, 300, 70, SQLT_CHR); oci_bind_by_name($idi, ":m1", $m1); oci_bind_by_name($idi, ":m2", $m2); $id=oci_execute($idi); echo "Lista studentilor cu media intre: ".$m1." si ".$m2." este: <br>"; for ($i=0; $i<count($a); $i++){ echo $a[$i]."<br>"; }
TYPE tip_colectie IS {VARRAY | VARYING ARRAY} (dimensiune) OF tip_element [NOT NULL] TYPE tip_colectie IS TABLE OF tip_element
se poate folosi o resursă care se crează cu funcţia:
OCI-Collection oci_new_collection(resource $id_conectiune, string $tip_colectie [, string $schema = NULL ])
Al treilea parametru din functie este numele schemei unde este definit "tip_colectie" (prin lipsă se ia schema utilizatorului curent).
Pentru ca să se poată folosi din exteriorul unei proceduri, tipul de colecţie trebuie memorat, deci trebuie creat prin:
create or replace type tip_colectie ...
La asocierea dintre resursa astfel creată şi parametrul din subprogramul Oracle (prin oci_bind_by_name) se foloseşte valoarea OCI_B_NTY pentru tipul de valoare.
Pentru gestiunea unei resurse (colecţii, obiect) astfel creată în PHP există mai multe metode, dintre care amintim:
Exemplu de utilizare.
Fie următorul script pentru Oracle:
create or replace type tpersoana is table of varchar2(70); create or replace procedure listap(cod in number, lista out tpersoana) as p infstud%rowtype; i number :=0; begin lista := tpersoana(); for p in (select * from infstud a where a.sectia=cod) loop lista.extend; i:=i+1; lista(i):=trim(p.nume) || ' ' || trim(p.prenume); end loop; end;
Un exemplu de utilizare a procedurii astfel definită:
$s="begin listap(:sectia, :lista); end;"; $idi = oci_parse($con, $s); $sectia=2; $lista=oci_new_collection($con,'TPERSOANA'); oci_bind_by_name($idi, ":sectia", $sectia); oci_bind_by_name($idi, ':lista', $lista, -1, OCI_B_NTY); $id=oci_execute($idi); echo "Lista studentilor de la sectia: ".$sectia." este: <br>"; for ($i=0; $i<$lista->size(); $i++){ echo $lista->getElem($i)."<br>"; } $lista->free();
TYPE nume IS REF CURSOR [RETURN tipvaloare]
Se observă ca tipul poate fi restrictiv (la un tip de valoare) sau nerestrictiv.
OPEN variabila_cursor FOR instr_select
O variabilă cursor se poate deschide de mai multe ori (o astfel de operaţie generează eroare la un cursor static),
o nouă deschidere va distruge precedenta deschidere. O variabilă cursor se poate deschide
şi prin trecere la o procedură memorată ce declară o variabilă cursor ca un parametru formal.
Pentru a putea folosi în PHP valorile furnizate de parametrii de tip cursor de subprogramele PL/SQL, se defineşte o resursă
cu funcţia:
resource oci_new_cursor (resource $id_conectiune)
Pentru asocierea resursei astfel definite la un parametru de tip ref cursor (prin funcţia oci_bind_array_by_name) se foloseşte
tipul "OCI_B_CURSOR" (ultimul argument din funcţie).
Pentru această resursă trebuie folosită funcţia oci_execute ca să se genereze datele, după care ea se gestionează ca rezultatul
execuţiei unei instrucţiuni select.
Considerăm pachetul p1 definit în curs\exemple\RefCursor\DefPachet.txt.
Folosirea procedurii se face astfel:
//p1.listastud(an in number, s in number, stud in out cstudenti) $s="begin p1.listastud(:an, :sectia, :stud); end;"; $idi = oci_parse($con, $s); $an='2015'; $sectia=2; $stud=oci_new_cursor($con); oci_bind_by_name($idi, ':stud', $stud, -1, OCI_B_CURSOR); oci_bind_by_name($idi, ":an", $an); oci_bind_by_name($idi, ":sectia", $sectia); $id=oci_execute($idi); oci_execute($stud); echo "Lista studentilor de la sectia: ".$sectia." din anul univ. ".$an." este: <br>"; while ($r = oci_fetch_row($stud)) { echo trim($r[0]).' '.trim($r[1])."<br>"; }
{INSERT | UPDATE | DELETE} ... RETURNING {expresie [, expresie]... INTO {variabila | :variabila_legata} ...
Acest format se utilizează dacă se foloseşte o singură linie din sursa de date.
Valoarea unei expresii din această singură linie se poate atribui unei variabile sau unei variabile legate (utilizată cu OCI în PHP).
Pentru o coloană LOB (BLOB sau CLOB) din baza de date se poate folosi o variabilă legată. Pentru o astfel de variabilă legată se
poate crea o resursă în PHP cu funcţia:
OCI-Lob oci_new_descriptor(resource $id_conectiune [, int $type = OCI_DTYPE_LOB])
Această resursă poate fi considerată ca un pointer (referinţă, locator) spre zona de memorie rezervată pentru coloana LOB. Relativ la o resursă creată în acest mod, care este o instaţă a clasei OCI-Lob, există mai multe metode, dintre care amintim:
Toate metodele clasei OCI-Lob (analog şi pentru alte clase) se pot afla prin execuţia scriptului:
foreach (get_class_methods('OCI-Lob') as $m ) { print "$m()<br>\n"; }
Informaţii suplimentare se pot afla în articolul
Working with LOBs in Oracle and PHP
Cu o astfel de metodă se poate modifica valoarea (din memorie) a unei coloane BLOB.
Cu funcţia oci_commit se poate salva în baza de date această modificare.
Exemplu. Presupunem că în tabelul
JUDETE[COD CHAR(2 BYTE), IMAGINE BLOB, ....]
function imagine($con, $cod, $fisier){ $s="update judete set imagine=EMPTY_BLOB() where cod='".$cod."' returning imagine into :imagine"; $imagine = oci_new_descriptor($con, OCI_DTYPE_LOB); $idi = oci_parse($con, $s); oci_bind_by_name($idi, ":imagine", $imagine, -1, OCI_B_BLOB); oci_execute($idi, OCI_DEFAULT); if ($imagine->savefile($fisier)) { oci_commit($con); echo "BLOB actualizat la codul ".$cod."<br>"; } else { echo "Eroare la actualizare BLOB pentru codul ".$cod."<br>"; } $imagine->free(); oci_free_statement($idi); }