PEAR::MDB2, Prepared Statements e Blobs

por Walter Cruz on 15/01/2007
in PHP, PostgreSQL

Recentemente, migramos um projeto nosso do PEAR::DB para o PEAR::MDB2.

Além do PEAR:DB não estar mais sendo desenvolvido (apenas mantido, por questões de compatibilidade), o MDB2 tem alguns poderes adicionais. Descobri um desses ao usar prepared statements.

Prepared Statements são uma funcionalidade que a maioria dos bancos de dados relacionais atuais implementa, que consiste em escrever uma consulta, e executá-la variás vezes seguidas, modificando apenas os parâmetros.

Um exemplo, retirado do site do PostgreSQL:


PREPARE fooplan (int, text, bool, numeric) AS INSERT INTO foo VALUES($1, $2, $3, $4);
EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
 

Os bancos de dados otimizam o prepared statement de forma especial. Segundo a documentação do PostgreSQL: " Quando o comando PREPARE é executado, o comando especificado é analisado, reescrito e planejado. Após isso, quando forem emitidos comandos EXECUTE o comando preparado precisa apenas ser executado. Assim os estágios de análise, reescrita e planejamento são realizados apenas uma vez, e não todas as vezes que o comando é executado.". Prepared Statements são otimizados também no MySQL, por exemplo.

Agora, um exemplo usando o antigo PEAR::DB


$sth = $db->prepare('INSERT INTO numbers (number) VALUES (?)');
if (PEAR::isError($sth)) {
    die($sth->getMessage());
}

$res =& $db->execute($sth, 1);
if (PEAR::isError($res)) {
    die($res->getMessage());
}
 

Observe que o statement não é um objeto. Para ser executado, você chama o objeto DB, passando o statement como parâmetro.

No PEAR::MDB2, o statement já é de fato um objeto.

O mesmo exemplo acima, dessa vez usando o MDB2:


$sth = $mdb2->prepare('INSERT INTO numbers (number) VALUES (?)', array('integer'), MDB2_PREPARE_MANIP);
$sth->execute(1);
$sth->execute(8);
 

O MDB2_PREPARE_MANIP é para indicar que essa consulta modifica dados. Como vocês também viram o MDB2 aceita um segundo parâmetro, um array informando os tipos dos objetos. Outro exemplo:


$types = array('integer', 'text', 'text');
$sth = $mdb2->prepare('INSERT INTO numbers VALUES (?, ?, ?)', $types, MDB2_PREPARE_MANIP);

$data = array(1, 'one', 'en');
$affectedRows = $sth->execute($data);
 

E sobre blobs? Para inserir um arquivo numa coluna blob no PostgreSQL (na verdade, BYTEA), ele deve ser preparado através da função pg_escape. Porém, usando prepared statements com o PEAR MDB2, isso não é necessário. Aliás, não é nem necessário ler o arquivo - basta passar como parâmetro do statement o descritor de arquivo! O próprio MDB2 se encarrega de lê-lo.

Veja o exemplo:


$types = array('text','blob');

$statement = $this->db->prepare("insert into tabeladeblob(
    nome_arquivo,
    dados_arquivo,
    ) values (
    ?,
    ?,
    )"
,$types);

$fp = fopen($arquivoNome,'r');
$data = array($arquivoNome,$fp);
$resultado = $statement->execute($data);
unlink($arquivoNome);
$statement->free();
 

Muito prático!

Endereço de trackback para este post

Trackback URL (clique direito e copie atalho/localização do link)

Sem feedback para esse post ainda

    Share Your Thoughts


    Seu endereço de e-mail não será revelado nesse site.

    Sua URL será exibida.
    PobreExcelente
    (Quebras de linha se tornam <br />)
    (Nome, e-mail & website)
    (Permitir que usuários o contatem através de um formulário eletrônico (seu e-mail não será exibido.))
    Subscribe to comments by email

    You can just use your OpenID to provide your name, e-mail and url.