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/OraHome1
Com Ora:

./configure --with-oracle=/oracle/OraHome1
mas tente compilar assim

./configure --with-oracle=/oracle/OraHome1
  --with-oci8=/oracle/OraHome1
Prová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_HOME
e digite também:

echo $ORACLE_SID
se aparecer nada em algum dos casos digite

export ORACLE_HOME=/diretorio/legal/onde/o/oracle/esta/instalado
ou....

export ORACLE_SID=nome_do_banco
e 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.


Nota: caso alguma função tenha passado com a tradução uma idéia diferente da qual ela realmente é usada comentem e corrijam o erro POR FAVOR! isso é muito importante.
A primeira pergunta devem ser (porque esse tonto não traduziu os Coming soon) o que isso ?? é que estas funções não foram documentadas.

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ípio

Ele 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