Artigos
Aqui falarei um pouco sobre o SGBD mais famoso do mundo, sendo usado com PHP, limitações, dúvidas, problemas e cabelos brancos na hora de usar as duas ferramentas juntas. Se você é novato como eu na duplinha PHP/Oracle, mas por curiosidade ou necessidade tem que desenvolver aplicações usando-os, já percebeu que os seus próximos finais de semana não serão de descanso não é ?
PHP e Oracle - O mundo dos grandes!!
Por Marcelo Pereira Fonseca da Silva
Por isso resolvi escrever este artigo, por estar pesquisando atualmente coisas sobre isso.. e espero dar continuidade neste artigo, trocando experiências e facilitando a vida dos membros da comunidade.
Primeiro, Oracle pra linux não é fácil de instalar (principalmente em distribuições não homologadas (aprovada)) nem por isso você vai deixar de tentar e conseguir instalar num Slackware como foi o meu caso.
Existem ótimos tutoriais e artigos por ai ensinando a instalar o Oracle no linux (outros nem tão bons, bastante superficiais e sem os possíveis erros que ocorrem na instalação e os "porques" de estarem ocorrendo).
Começando:
As bibliotecas disponíveis:
Ora x OCI
Breve explicação sobre as duas:
OCI - A grande (traduzida da página oficial do PHP)
Essa extensão permite você acessar Oracle8 e Oracle7 Database. Usa o Oracle8 "Call-Interface" (pode ser usada para versões acima da 8 do Oracle também).
Essa extensão é mais flexível do que a extensão padrão Oracle (Ora).
Ela suporta "alocar" as variáveis globais e locais do PHP para o Oracle.
LOB, FILE e ROWID permitem à você usar variáveis definidas pelo usuário.
Saindo da teoria, o que é necessário pra ter esse bixo ai?
No Windows, é necessário habilitar no php.ini a dll: php_oci8.dll
No Linux, necessário compilar com --with-oci8=[ DIR] onde DIR é o diretório do Oracle, aqui em casa eu coloquei ele em /oracle/OraHome1 dai assim, quando vocês forem compilar saibam que pode ser compilada OCI e Ora juntos, e então para futuros e eventuais testes com as duas bibliotecas já compilem as duas juntas e não sejam mané como eu que só descobri isso esses dias :)
legal agora eu já sei o que fazer, como compilar o PHP com isso ai.. a grande pergunta agora é: "porque eu vou querer usar o Ora ???"
Resposta: Tem louco pra tudo hoje em dia né :) brincadeira.. bom, a experiência que eu tive em projetos foi a seguinte.. divisão da equipe para desenvolver um arquivo com as funções necessárias para migrar nosso sistema de SQL Server pra Oracle.
Se você pensou "putz, que abacaxi.." pois é, pensei o mesmo hehe :) mas todos viveram felizes para sempre, a proposta era a seguinte:
Cada um tentaria fazer o tal do arquivo, um com OCI e o outro(eu) com Ora.. nem preciso falar que tomei um chocolate né :// vivendo e aprendendo.. realmente eu comprovei a .. ahnn digamos.. "sugestão" que está na PHP.net. (choose your destiny e a risadinha ha-ha-ha) :)
Na próxima página o descritivo da outra extensão
Ora - A "outra" (tradução do site PHP.net)
Essa extensão adiciona suporte ao Oracle Database Server. Para usá-la você deve compilar o PHP com --with-oracle[=DIR] onde dir é o diretório padrão onde está instalado o oracle.
Legal, tá ai a explicação das duas, agora .. porque diabos eu ainda não falei nas tão famosas variáveis do Oracle ?
Exemplos do ./configure pro linux que costuma ser chatinho.. ahh que modéstia.. É MUITO CHATO ISSO SIM!!!
Com OCI8:
./configure --with-oci8=/oracle/OraHome1Com Ora:
./configure --with-oracle=/oracle/OraHome1mas tente compilar assim
./configure --with-oracle=/oracle/OraHome1 --with-oci8=/oracle/OraHome1Prováveis erros na hora de compilar isso e der erro é que assim.. sem oracle na máquina filhote..desiste, pega o controle remoto e vai assistir tv, porque provavelmente não vai funcionar (se algum jyraia conseguiu instalar sem oracle na máquina que se apresente e conte-nos sua historinha).
Se você tem Oracle e tá pensando assim: "esse tutorial idiota não ensina droga nenhuma" calma.. muito provavelmente você não tem a ORACLE_HOME e ORACLE_SID (moreira) (desculpa não aguentei) setadas.. na prática como fazer para setar e o que são elas ??
ORACLE_HOME, variável no lnx que é usada para o PHP "entender" onde o Oracle está.. pense nela como o endereço do Oracle, a rua que ele mora no seu computador :)
Oracle_SID, é a variavel de ambiente lnx que fala pra todo mundo qual o nome do database que você criou.. no caso coloquei o meu nome "marcelo" ficando assim:
ORACLE_HOME = /oracle/OraHome1
ORACLE_SID = marcelo
para verificar se elas estão setadas digite em um terminal:
echo $ORACLE_HOMEe digite também:
echo $ORACLE_SIDse aparecer nada em algum dos casos digite
export ORACLE_HOME=/diretorio/legal/onde/o/oracle/esta/instaladoou....
export ORACLE_SID=nome_do_bancoe tente compilar.. se mesmo assim não compilar provavelmente você está indicando um lugar diferente do qual você instalou o Oracle.
Se compilou normal agora passarei à descrição das funções e exemplos das funções.
Iniciarei pela OCI8 que tem mais funções e que é mais interessante para trabalhar.
- OCIBindByName -- Passa variáveis do PHP para o Oracle
- OCICancel -- Cancela a Leitura de um cursor
- ocicollappend -- Coming soon
- ocicollassign -- Coming soon
- OCICollAssignElem -- Coming soon
- ocicollgetelem -- Coming soon
- ocicollmax -- Coming soon
- ocicollsize -- Coming soon
- ocicolltrim -- Coming soon
- ocicolumnisnull -- Testa se um resultado da coluna é NULO
- ocicolumnname -- Retorna o número de colunas.
- ocicolumnprecision -- Coming soon
- ocicolumnscale -- Coming soon
- ocicolumnsize -- Retorna o resultado do tamanho de uma coluna
- ocicolumntype -- Retorna o tipo de dados de uma coluna
- ocicolumntyperaw -- Coming soon
- OCICommit -- Dá o famoso Commit após um bloco SQL
- OCIDefineByName -- Usa as variaeis do PHP definidas durante um SELECT
- OCIError -- Retorna o último erro stmt|conn|global
- ociexecute -- Executa um "bloco de comando"
- ocifetch -- Coloca os dados dentro de um "result-buffer"
- ocifetchinto -- Coloca os dados dentro de um "result-array"
- ocifetchstatement -- Joga dentro de um array os resultados
- ocifreecollection -- Coming soon
- ocifreecursor -- Libera todos os recursos associados à um cursor
- ocifreedesc -- Deleta um descritor de objeto muito grande
- ocifreestatement -- Libera todos os recursos associonados à um bloco de comando
- ociinternaldebug -- Habilita ou desabilita a saída interna de "debug"
- ociloadlob -- Coming soon
- ocilogoff -- Disconecta do Oracle
- ocilogon -- Conecta com o Oracle
- ocinewcollection -- Coming soon
- ocinewcursor -- Retorna um novo cursor (Statement-Handle)
- ocinewdescriptor -- Inicializa um novo e vzio LOB ou FILE
- ocinlogon -- Abre um conexão com o Oracle
- ocinumcols -- Retorna o número de colunas de um comando SQL
- ociparse -- Verifica a integridade de um bloco de comando (de uma query)
- ociplogon -- Abre uma conexão persistente com o Oracle
- ociresult -- Retorna os valores das linhas "requisitadas"
- ocirollback -- Executa o Rollback (desfaz tudo que foi feito por um comando SQL, após o último commit)ocirowcount -- Pega o número de colunas afetadas
- ocisavelob -- Coming soon
- ocisavelobfile -- Coming soon
- ociserverversion -- Retorna uma string com info da versão
- ocisetprefetch -- Seta o número de linhas que serão afetadas
- ocistatementtype -- Retorna um tipo de bloco de comando...
- ociwritelobtofile -- Coming soon
Aqui tentarei passar alguns pontos relevantes na hora de trabalhar efetivamente com os dois, espero receber comentários sobre os exemplos e sugestões (sinta-se livre também para dar continuidade à este documento)
Para conectar será necessário o uso de um login/senha válido usando a função OCILogon(); O Oracle vem com alguns usuários padrão, um deles é o login "scott" e a senha "tiger"
exemplo:
<?php
// passa a variável do ORACLE_HOME
putenv("ORACLE_HOME=/path/pro/diretorio/do/oracle");
// passa a variável do Oracle_SID
putenv("ORACLE_SID=nome_do_database");
$user="scott"; // seta o usuario
$senha="tiger"; // seta a senha
$banco="(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)
(HOST=127.0.0.1)(PORT=1521)
)
)
(CONNECT_DATA=(SERVICE_NAME=melancia_legal))
)"; // configuracoes do banco (isso muda um pouco no oracle)
// neste caso usei o HOST como local "127.0.0.1"
// e o nome do banco em SERVICE_NAME como sendo melancia_legal
// somente para ficar mais fácil de enxergar o que deve ser alterado.
if ($conexao = OCILogon($user,$senha,$banco) )
echo "Conexão bem sucedida.";
else
echo "Erro na conexão com o Oracle.";
?>
Este foi um exemplo de como fazer uma conexão, agora explicarei o que é cada linha e porque daria um eventual erro.- as linhas que setam as variáveis de ambiente ORACLE_HOME e ORACLE_SID são para evitar surpresas, sem elas provavelmente vá apontar um erro de conexão (não sei precisar qual o numero do erro)
- o $banco pode ser deixado em branco caso esteja acessando de uma máquina local $banco=""; fiz este teste e ele aceitou normalmente em um WINDOWS 2000, Slackware9 com Oracle 9 e Red Hat Linux 9 e Oracle 9 também funcionam normal
- a linha da variável $conexao inclui um if para validar ou nao a expressao da função OCILogon que tenta conectar com o Oracle, retornando sucesso ou erro.
Exemplo de uma função em Oracle para passar comandos SQL
<?php
function sql_legal($comando)
{
// pega os 6 primeiros caracteres da string,
// ou o verbo do comando SQL
$vl_command = substr($comando,0,6);
// comando switch do PHP com o verbo em minúscula
switch(strtolower($vl_command)):
case "select": $sql = OCIExecute(OCIParse($comando));
break;
// caso seja select executa...
// caso nao seja select ele executa o bloco com uma
// constante da função OCIExecute.. e dá Commit.
default: $sql = OCIExecute(OCIParse($comando,
OCI_COMMIT_ON_SUCCESS)); OCICommit($conexao);
endswitch; // fim do switch
return $sql; // retorna a variavel $sql
}
?>
Se você achou essa função estranha e/ou não funcionar favor reportar o erro e avisar-nos.. Apesar de estar levemente comentada a função segue o seguinte princípioEle recebe um bloco de comando SQL, verifica o verbo, e caso seja um select ela usa das funções OCIParse() e OCIExecute() (este segundo com a constante padrão OCI_DEFAULT) e executa o bloco. Caso contrário, por padrão ele entraria em qualquer outro comando <> de select se é que vocês me entendem :) Não sendo um select ele terá que validar isto, usando o famoso Commit do Oracle [pausa] Pra quem começar a trabalhar com Oracle é assim, ele tem uma regrinha que nua e crua é a seguinte: Não quero saber quem você é, se é importante ou não, tudo que você fizer dentro da tua seção filho, querendo ou não querendo você vai ter que validar. como ? dando o comando "commit" no SQLPlus por exemplo, no caso do PHP isto é feito com a função OCICommit()
Tá, não entendi nada do que você falou
vamos lá..
<?php
// bloco SQL
$sql_melancia = OCIParse("UPDATE frutas SET melancia='3'");
OCIExecute($sql_melancia); // executa o bloco SQL acima.
?>
Este exemplo não funciona, porque ? Bom, primeiramente porque não tem o OCICommit() pra validar a expressão, "segundamente" hehehe mesmo tendo o OCICommit() não iria funcionar porque não tem a constante O certo seria:
<?php
// bloco SQL
$sql_melancia = OCIParse("UPDATE frutas SET melancia='3'");
// executa o bloco SQL acima.
OCIExecute($sql_melancia, OCI_COMMIT_ON_SUCCESS);
OCICommit($conectar); // valida a expressao
?>
O que acontece efetivamente ai em cima ? O cara passa o comando de update na tabela de frutas, setando a quantidade no caso de melancias como 3, o segundo comando executa o bloco de SQL com a constante e em um terceiro momento ele valida a expressão, sem isso o Oracle finge que nem te viu :)Alguns pontos relevantes pra quem está saindo de um MySQL da vida e fuçando num Oracle.
- É interessante o uso da função OCIParse(); para verificar integridade de comandos SQL.
- O OCIExecute() executa "efetivamente" um "bloco de comando", ou uma instrução SQL.
- Para validar ou desfazer as possíveis caquinhas usamos OCIRollback e OCICommit (valida tudo) ou seja, se está usando o commit valida todos os comandos SQL passados após o último que foi dado.
Importante: se você tem uma ordem de comandos assim:
UPDATE, DELETE, SELECT.. e sem commit e depois você dá um CREATE TABLE, é feito um Commit que valida o UPDATE e o DELETE anteriores.. então, um OCIRollBack conhecido como anti-caquinha neste caso não vai funcionar porque você deu um CREATE TABLE que tem "embutido" um Commit.
- O OCI não tem função que retorna a quantidade de colunas de um select (isso é mal)
- Há diferenças de uso na função OCIExecute para UPDATE, SELECT, INSERT e DELETE.
- Há duas constantes importantes no OCIExecute são elas: OCI_COMMIT_ON_SUCCESS e OCI_DEFAULT a última é usado por padrão como o nome sugere, e se não especificar um OCI_COMMIT_ON_SUCCESS não poderá ser usado um OCICommit.
- O caractere de concatenação no Oracle é o ||
Bom, este é um primeiro documento no qual gostaria e espero ter tirado o medo de quem tem o Oracle instalado em qualquer plataforma e não sabe nem onde nem como procurar informação, a PHP.net novamente é ponto de referência, e pelo que consegui captar, os comentários abaixo dos descritivos das funções no site da PHP são relevantes e importantíssimos, dicas em N plataformas de como trabalhar me foram úteis na hora de começar a trabalhar com estas duas ferramentas.
Para não prolongar este artigo irei encerrar este como o primeiro de uma série de outros artigos sobre PHP / Oracle se a comunidade gostar deste aqui, aprofundar um pouco e até mesmo contruirmos alguns exemplos de sisteminhas em Oracle que já são vistos hoje em MySQL.
Marcelo Pereira











