0

Criando Cláusulas SQL Dinamicamente

criado por Alfred R. Baudisch em 24/08/2005 12:02am
Para todos nós, programadores PHP usando Banco de Dados, temos a tarefa de digitar várias cláusulas SQL.

Em um dos meus projetos, onde o número de cláusulas INSERT e UPDATES foi grande, eu estava perdendo muito tempo em sempre ter que digitar:
INSERT INTO tabela VALUES... Bom, você deve saber do que estou falando.

Então, para resolver o problema, criei uma classe que gera cláusulas INSERT e UPDATE, onde precisamos fornecer apenas os nomes dos campos e os valores dos campos.

Abaixo o código da classe. Na próxima página exlicarei o funcionamento e uso da classe.

<?php
class clausulas_sql
{
    /**
    * @param string $clausula_sql;
    * @access public
    */
    var $clausula_sql;

    /**
    * Cria cláusulas SQL INSERT
    *
    * @param string $tabela
    * @param array $campos
    * @param array $valores
    * @access public
    */
    function gera_insert($tabela, $campos, $valores)
    {
        $this->clausula_sql = "INSERT INTO " . $tabela . " (";
        
        $quantidade_campos = count($campos);        
        for ($i = 0; $i < $quantidade_campos; ++$i) {
            $this->clausula_sql .= $campos[$i];

            if ($i < ($quantidade_campos-1)) {
                $this->clausula_sql .= ", ";
            }
        }

        $this->clausula_sql .= ") VALUES (";

        for ($i = 0; $i < $quantidade_campos; ++$i) {
            $this->clausula_sql .= clausulas_sql::escreve_valor($valores[$i], $i, $quantidade_campos);
        }

        $this->clausula_sql .= ");";

        return $this->clausula_sql;
    }

    /**
    * Cria cláusulas SQL UPDATE
    *
    * @param string $tabela
    * @param array $campos
    * @param array $valores
    * @param string $sentenca
    * @access public
    */
    function gera_update($tabela, $campos, $valores, $sentenca)
    {
        $this->clausula_sql = "UPDATE " . $tabela . " SET ";

        $quantidade_campos = count($campos);

        for ($i = 0; $i < $quantidade_campos; ++$i) {
            $this->clausula_sql .= $campos[$i] . " = ";
            $this->clausula_sql .= clausulas_sql::escreve_valor($valores[$i], $i, $quantidade_campos);
        }
        
        $this->clausula_sql .= " " . $sentenca . ";";

        return $this->clausula_sql;
    }

    /**
    * Retorna um valor formatado para se inserir na query SQL
    *
    * @param mix $valor
    * @param int $atual
    * @param int $total
    * @access private
    */
    function escreve_valor($valor, $atual, $total)
    {
        if (is_string($valor)) {
            $retorno = "'" . $valor . "'";
        } elseif (empty($valor)) {
            $retorno = "NULL";
        } else {
            $retorno = $valor;
        }

        if ($atual < ($total-1)) {
            $retorno .= ", ";
        }

        return $retorno;
    }
}
?>

Comentários:

Mostrando 1 - 10 de 14 comentários
Josue Samuel disse:

...é isso aí, meu caro!!!

gostei da idéia. Eu ainda não havia me despertado para isso.

realmente não sei se vou usar devido a outra opções interessantes relatadas nos comentários.

... mas espere um pouco, não ache isso ruim e nem que estou menospresando seu trabalho. Através dele eu aprendi algo contigo e, através dos comentários, aprendi mais outras coisas.

por fim, não sei como vc lidou com essas críticas da galera toda, porém é sempre bom ter em mente que essas 'rejeições' foram para o trabalho e não para vc. ENCARE isso como um processo de engrandecimento: a gente se expõe mostrando o que sabemos e a comunidade colabora.

viva longa à comunidade com seus eternos colaboradores!!!
06/01/2006 5:19am (~18 anos atrás)

Facilita o trabalho de qualquer programador. É a prova concreta de que Programar Orientado a objetos é essencial nos dias atuais.
22/09/2005 12:30am (~18 anos atrás)

bem bacana o artigo
14/09/2005 2:29pm (~18 anos atrás)

Diego Hellas disse:
Olha, acho que so esta ficando mais facil de haver bugs nesse script, por que caso vc tenha que modificar alguma coisa vai ter que passar revisando o seu código, e acho que está mais vulnerável a bugs.
05/09/2005 3:38pm (~18 anos atrás)

Rui disse:
Procure utilizar AR active record.
02/09/2005 10:36am (~18 anos atrás)

Rui disse:
Em tempo: use SQL normal mesmo separado em uma segunda classe. DAO. Só tome cuidado com o anemic domaim (ambos patterns Martin Fowler).
02/09/2005 8:12am (~18 anos atrás)

Rui disse:
Não vejo como isso pode ser mais prático.
Você está apenas "quebrando" o SQL e com isso inserindo possíveis bugs.

Muito mais prático seria, se todos programassem OO, criar um framework para persistência de objetos.

Utilize reflexão para obter os atributos do objeto e na sequência crie comandos sql *realmente* dinâmicos. Algo que o ezpdo faz de forma bem porquinha (performance baixa).

Desculpa se fui rude. Criei um user, verifiquei o meu e-mail, escrevi... enfim, *tentei* colaborar. Só falei isso com o intuito de mudar um pouco a visão de que *tudo* escrito com php tem "bad smell".

Nota: 10 pela dediação, 0 para o código/idéia.
02/09/2005 8:09am (~18 anos atrás)

GILSON SOARES disse:
estou ainda só começando mas estou gostando da franquesa dessa comunidade....valeu mesmo
01/09/2005 5:44pm (~18 anos atrás)

mto bom seu artigo.. ajuda mto.. queria apenas coloca um comentario, é q ta faltando um ; depois de

mysql_query($query);
31/08/2005 10:08pm (~18 anos atrás)

Adler Medrado disse:
Eu achei interessante seu artigo.
Outra maneira de fazer isso, que é a maneira que eu uso, é que para cada tabela do banco eu tenho uma classe que a representa. esta classe é filha de uma classe que implementa os metodos montarInclusao() e montarAlteracao().
Estes métodos montam o comando SQL de acordo com os atributos que tiveram algum valor atribuido pelos métodos set referentes a cada um deles. Por exemplo, na classe eu tenho um atributo nome, entao eu tenho um método setNome() e getNome().
o Set eu seto o valor e o get eu obtenho o valor de determinado atributo. Com isso eu verifico quais atributos tem valor e monto o comando.

É isso.
um abraço a todos.
31/08/2005 3:50pm (~18 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)