Consultas SQL pelo Terminal no Postgres, Mysql, SQL Server

Introdução

No meu dia a dia, e de muitos que possam está lendo este artigo, tenho que fazer diversas consultar em tabelas, às vezes dispostas em Sistemas Gerenciadores de Banco de Dados (SGBD) diferentes. Para este tipo de situação, o Eclipse SQL Explorer funciona muito bem, mas muitas vezes, são consultas simples e abrir este software ou qualquer outro para fazer a consulta pode ser desnecessário…

Então pensei em fazer algo simples, porém útil, um script em PHP que faça a consulta e apresente na saída padrão ( no terminal ).

Poderia ter sido usado qualquer outra linguagem de programação, usei o PHP por sua conexão com diferentes SGBD ser bem fácil e no momento estou mais familiarizado com sua sintaxe.

Preparando o Ambiente

Caso não tenha o PHP instalado ainda:

$ sudo apt-get install php5

Para este artigo, preparei o ambiente para realizar consultar no Postgres, MySQL e MS SQL Server.

Instale os módulos necessários para o PHP realizar a conexão:

$ sudo apt-get install php5-pgsql php5-mysql php5-sybase

Obs.: O php5-sybase é um módulo usado tanto para o Sybase como para o MS SQL Server.

Com a ajuda de um terminal embutido, como Guake, você nem vai precisar ir até um terminal usando o menu, basta usar o atalho configurado.

Ao final desse artigo teremos a possibilidade de fazer algo como:

Linux: Consultar SQL pelo terminal
Linux: Consultar SQL pelo terminal

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!

Rolar para cima