Consultas SQL pelo Terminal no Postgres, Mysql, SQL Server, etc

Que tal ter a possibilidade de realizar, rapidamente, uma consulta no seu banco de dados sem precisar abrir um software cliente? E que tal fazer isso via terminal? Nesse artigo veremos como construir uma solução simples para isso, com o uso do PHP.

[ Hits: 25.164 ]

Por: Raimundo Alves Portela em 12/07/2012 | Blog: http://portelanet.com


Mão na massa ( O script PHP )



Arquivo de conexão

Para realizar a conexão com o SGBD fiz a classe DataBase ler um arquivo ".ini", onde o mesmo é nomeado com o nome do SGBD seguido pelo nome da base de dados, e dentro dele seguem os dados do servidor (host), usuário, senha e opcionalmente a porta.

Exemplo de arquivo de configuração para conexão:

host    = 192.168.0.100
user    = postgres
pass     = gnuxx22l1n1

Classe de conexão

Seque o código da classe de conexão com os SGBD:

<?php
/*
* classe DataBase
* Gerencia conexoes com bancos de dados através de arquivos de configuracao.
* Baseada em TConnection.class.php do livro: PHP Programando com Orientação a Objetos (Pablo Dall''Oglio)
*/

class DataBase
{
    public static $conn;

    private function __construct() {}
    
    /*
     * metodo open()
     * recebe o nome do banco de dados e instancia o objeto PDO correspondente
     * o arquivo segue o padrao: tipobanco_nomebase
     */
    private function open( $arquivo )
    {
        // verifica se existe o arquivo
        if ( file_exists( "{$arquivo}.ini") )
        {
            // le o INI e retorna um array
            $nome = explode('_', $arquivo );
            $tipoBanco = $nome[0];
            $nomeBase = $nome[1];
            $db = parse_ini_file("{$arquivo}.ini");
        }
        else
        {
            // se nao existir, lanca um erro
            throw new Exception("Arquivo '$arquivo' nao encontrado");
        }
        
        // le as informacoes contidas no arquivo
        $usuario = isset($db['user']) ? $db['user'] : NULL;
        $senha = isset($db['pass']) ? $db['pass'] : NULL;
        $host = isset($db['host']) ? $db['host'] : NULL;
        $porta = isset($db['port']) ? $db['port'] : NULL;
        
        // descobre qual o tipo (driver) de banco de dados a ser utilizado
        switch ( $tipoBanco )
        {
            case 'pgsql':
                $porta = $porta ? $porta : '5432';
                $conn = new PDO("pgsql:dbname={$nomeBase}; user={$usuario}; password={$senha};
                        host=$host;port={$porta}");
                break;
            case 'mysql':
                $porta = $porta ? $porta : '3306';
                $conn = new PDO("mysql:host={$host};port={$porta};dbname={$nomeBase}", $usuario, $senha);
                break;
            case 'mssql':
               $conn = new PDO("dblib:host={$host};dbname={$nomeBase};charset=UTF-8", $usuario, $senha);
                break;
        }
        // define para que o PDO lance excecoes na ocorrencia de erros
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        // retorna o objeto instanciado.
        return $conn;
    }
    
    /*
     * Metodo que implementa o padrao Singleton
     * O mesmo retorna a instancia de conexao de um banco caso ja exista
     * Evitando a criacao de uma nova a cada solicitacao
     */
    

    public static function getConn( $nomeArquivo ) {
       if ( ! isset( self::$conn[$nomeArquivo] ) ) {
          self::$conn[$nomeArquivo] = DataBase::open( $nomeArquivo );
       }
       return self::$conn[$nomeArquivo];
    }
}
?>

Script de consulta (shellquery)

Agora o código do script PHP que realiza de fato a consulta no banco de dados, mediante parâmetros fornecidos via terminal.

#!/usr/bin/php
<?php
# uso: shellquery tipoBanco_nomeBase "comandoSQL"
include_once "DataBase.class.php";
#----------------------------------------------
$mostraNomeCampos = TRUE;
$banco = isset( $argv[1] ) ? $argv[1] : NULL;
$sql = isset( $argv[2] ) ? $argv[2] : NULL;
# se for passado um terceiro argumento, não exibe o nome dos campos
if ( isset( $argv[3] ) ) $mostraNomeCampos = FALSE;

if ( $banco == NULL || $sql == NULL ) {
   echo "Sintaxe {$argv[0]} nomeArquivoConfiguracao comandoSQL\n";
   exit;
}

try {
   $conn = DataBase::getConn( "$banco" );
   $rs = $conn->query( $sql )->fetchAll();
} catch ( Exception $e ){
   echo "Erro: {$e->getMessage()} :\nLinha: {$e->getLine()}\n";
   exit;
}
  
foreach ( $rs as $dados ) {
   $ultimaCol = ( count( $dados ) / 2 ) - 1;
  
   if ( $mostraNomeCampos == TRUE ) {
      # obtem os nomes dos campos
      $key = ( array_keys( $dados ) );
      $x=0;
      for ( $i=0; $i < count( $key ); $i++ ) {
         if ( is_int( $key[$i] ) ) continue;
         $campo[$x] = $key[$i];
         $x++;
      }  

      # exibe os nomes dos campos
      for ( $i=0; $i < $ultimaCol; $i++ ) {
         echo "{$campo[$i]}|";
      }
      echo "{$campo[$ultimaCol]}\n";
   }
   $mostraNomeCampos = FALSE;
  
   # exibe os dados
   for ( $i=0; $i < $ultimaCol; $i++ ) {
      echo "{$dados[$i]}|";
   }
   echo "{$dados[$ultimaCol]}\n";
}
?>

Salve em um arquivo, como shellquery, dê permissão de execução:

chmod +x shellquery

E use à vontade.

Exemplo de uso

./shellquery pgsql_casa "SELECT * FROM disciplinas"

Resultado:
no_disciplina|id_disciplina
PORTUGUES|1
MATEMATICA|2
GEOGRAFIA|3
HISTORIA|4

Bom, a saída deixei bem simples, exibindo os registros um por linha, separados por "|", assim poderá ser usado a seu gosto, para:

- Quantos registros foram retornados?:

./shellquery pgsql_casa "SELECT * FROM disciplinas" QUALQUERCOISA | wc -l

Resultado:
4

- Criar um arquivo CSV com separdor ";" no lugar de "|":

./shellquery pgsql_casa "SELECT * FROM disciplinas" | tr '|' ';' > resultado.csv

Arquivo resultado.csv aberto no libreoffice:
Linux: Consultar SQL pelo terminal

Enfim, podem ser feitas as infinidades de modificações que o GNU/Linux permite via shell.

Espero que ajude e facilite a vida de vocês, pra mim é uma mão na roda, uso todos os dias!
Página anterior    

Páginas do artigo
   1. Introdução
   2. Mão na massa ( O script PHP )
Outros artigos deste autor

Aplicativos para gerenciar a Área de Transferência (Clipboard)

Explorando a entrada de dados com READ em Bash Shell

Yad 0.16 - Eu quero sempre mais de ti

Enviar e-mail pelo terminal com mutt

Otimizando o uso do seu disco rígido usando a mesma /home para várias distribuições

Leitura recomendada

Relato de experiência: contribuição para tradução de um artigo da Wikipédia

Banco de dados e Cloud Computing, melhor opção?

Banco de dados orientados a documentos

Uma vulnerabilidade chamada de SQL Injection

Internet: Amiga ou inimiga?

  
Comentários
[1] Comentário enviado por rony_souza em 12/07/2012 - 17:51h

Dica muito boa mesmo :D

[2] Comentário enviado por rai3mb em 12/07/2012 - 21:49h

Obrigado, engraçado que já faz quase um ano que uso isso no meu dia a dia e só agora sentei pra escrever esse "rápido" artigo.

[3] Comentário enviado por removido em 13/07/2012 - 08:25h

pode-se usar o shell direto para fazer a consulta.


$> echo " select * from users;" | mysql -u fulano -psicrano -h naquelelugar

O resultado é o mesmo, mais rápido direto e sem perda de tempo.




[4] Comentário enviado por rai3mb em 13/07/2012 - 10:58h

@mufui, sei disso, mas pra isso ai vc vai precisar de um cliente pra cada SGBD instalado, consome mais recursos e de forma desnecessária se o objetivo for só consultas.
Sabe fazer com SQL Server por exemplo?

[5] Comentário enviado por cesar em 13/07/2012 - 12:02h

Muito bom Raimundo, nunca fiz consultas desta forma.

[]'s

[6] Comentário enviado por rai3mb em 13/07/2012 - 12:09h

Obrigado @cesar, como falei tem como usar os respectivos cliente do mysql ou postgres, mas ai vc precisar ter eles instalados na sua máquina, e vai um comando pra cada banco de dados, sem contar com os bancos de dados que ainda não tem cliente para GNU/Linux.

Então com esse método, pasta ter a extensão de conexão com o SGBD para o PHP.
Abraços

[7] Comentário enviado por danniel-lara em 14/07/2012 - 11:21h

muito bom Rai3mb
eu estou sando direto shell script
para brincar com banco de dados
muito legal mesmo

[8] Comentário enviado por foguinho.peruca em 18/07/2012 - 21:55h

Olá!

Gostei da dica. Realmente se encaixa na minha necessidade. A maioria das vezes eu preciso virtualizar um Windows somente para acessar uma base MS SQL Server. Vou usar bastante esse script..

;)

Jeff

[9] Comentário enviado por rai3mb em 18/07/2012 - 22:51h

Obrigado, também tenho que usar muito o SQL SERVER devido vários sistemas legados usarem ele onde trabalho, e também acesso muito o postgres, dai esse script se encaixa perfeitamente, pois fica fácil fazer as consultas pelo terminal e exportar o resultado conforme a necessidade.


Contribuir com comentário