make all

cd /usr/src/universe && make all

Personalizando o psql

Escrito por Guedes em Maio 25, 2008

Personalizando o psqlUma das ferramentas mais utilizadas na administração do PostgreSQL é o nosso bom e velho psql. Sua interface em modo texto permite a sua utilização local ou remota de maneira rápida e eficiente  nos presenteando com alguns recursos interessantes como por exemplo a complementação de código baseada em contexto (proporcionado pelo readline).

Outro recurso que utilizo é a personalização do prompt, e este é muito útil para quem está acostumado a conectar em vários servidores distintos, administrando várias bases de dados em cada um deles, pois ele pode lhe fornecer dados interessantes de uma forma simples e prática. Vou tentar exemplificar:

Imagine um cenário onde você administre 3 (três) servidores diferentes, cada um deles contendo algumas bases de dados, conforme a figura abaixo:

Personalizando o psql

Você pode utilizar o script a seguir para definir o um prompt personalizado para cada servidor.

#!/bin/sh
########################################################
#
# Script inicializacao de parametros do psql
#
#
# 2007-2008 (c) Dickson Guedes <guediz at gmail dot com>
########################################################
ARG1=$1

PSQL_RC="$HOME/.psqlrc"

PROMPT_SRV01='%[%033[44;37;1m%](%`date +%H:%M:%S`) %n@%M:%>/%/ %[%033[0m%]\\n%x%# '
PROMPT_SRV02='%[%033[43;37;1m%](%`date +%H:%M:%S`) %n@%M:%>/%/ %[%033[0m%]\\n%x%# '
PROMPT_SRV03='%[%033[41;37;1m%](%`date +%H:%M:%S`) %n@%M:%>/%/ %[%033[0m%]\\n%x%# '
PROMPT_DEFAULT='%[%033[40;37;1m%](%`date +%H:%M:%S`) %n@%M:%>/%/ %[%033[0m%]\\n%x%# '

SERVIDOR=${ARG1:=srv01}

define_psqlrc() {
        echo "\set QUIET 1" > $PSQL_RC
        echo "\pset null '(null)'" >> $PSQL_RC
        echo "\set PROMPT1 '$1'" >> $PSQL_RC
        echo "\set PROMPT2 '| '" >> $PSQL_RC
        echo "\set HISTSIZE 5000" >> $PSQL_RC
        echo "\set HISTFILE ~/.psql_history- :DBNAME" >> $PSQL_RC
        echo '\\timing' >> $PSQL_RC
        echo "\set QUIET 0" >> $PSQL_RC
}

case $1 in
        srv01) define_psqlrc "$PROMPT_SRV01" ;;
        srv02) define_psqlrc "$PROMPT_SRV02" ;;
        srv03) define_psqlrc "$PROMPT_SRV03" ;;
            *) define_psqlrc "$PROMPT_DEFAULT" ;;
esac

psql -h $SERVIDOR
## FIM DO SCRIPT

Com esse script eu posso executá-lo e obter prompts diferenciados para cada servidor:

Personalizando o psql

Personalizando o psql

Personalizando o psql

A data é apresentada através do uso da sequência de escape %`command`. Já as cores são mostradas através do uso da sequência de escape %[ ... %].

Outras sequências de escape e personalizações podem ser encontradas no manual do psql.

Bom, é isso!

Enviado em postgresql | Tagged: , , | 1 Comentário »

Exemplo de um script SQL interativo no PostgreSQL

Escrito por Guedes em Abril 7, 2008

Exemplo de um script SQL interativo no PostgreSQLA semana foi corrida, e o final de semana foi totalmente utilizado para descanso e lazer. Mas a vontade de escrever é maior, e cá estou novamente pronto para mais um post. A idéia hoje era falar sobre scripts SQL, então imaginei algo diferente, e pensei em mostrar como fazer um script interativo no PostgreSQL 8.3, associando o seu uso a um cenário hipotético. Vejamos…

Em um universo ideal, é muito comum existir um banco de dados de desenvolvimento, um de testes, um de homologação e um de produção. Neste cenário, imagine que seu Analista de Testes precise testar uma nova funcionalidade do sistema relacionada ao módulo de compras, e que para isso constantemente você tenha que aplicar a carga de testes desse módulo no banco de dados de teste, não é de se estranhar que você possua uma carga pronta (é o mínimo que você deveria ter).

Veja a seguir o script simplificado que representa esse cenário:

CREATE TABLE tb_cliente (
     nr_documento numeric(14,0) NOT NULL,
     nm_cliente character varying(60)
);
ALTER TABLE blog.tb_cliente OWNER TO postgres;

CREATE TABLE tb_compra (
     nr_nota_fiscal numeric(15,0) NOT NULL,
     dt_compra date,
     nr_documento_cliente numeric(14,0)
);
ALTER TABLE blog.tb_compra OWNER TO postgres;

CREATE TABLE tb_item_compra (
     nr_nota_fiscal numeric(15,0) NOT NULL,
     nr_referencia integer NOT NULL,
     qt_item smallint DEFAULT 1
);
ALTER TABLE blog.tb_item_compra OWNER TO postgres;

CREATE TABLE tb_produto (
     nr_referencia integer NOT NULL,
     ds_produto character varying(60) NOT NULL,
     vl_venda numeric(15,2)
);
ALTER TABLE blog.tb_produto OWNER TO postgres;

CREATE SEQUENCE tb_produto_nr_referencia_seq
     INCREMENT BY 1
     NO MAXVALUE
     NO MINVALUE
     CACHE 1;
ALTER TABLE blog.tb_produto_nr_referencia_seq OWNER TO postgres;

ALTER SEQUENCE tb_produto_nr_referencia_seq OWNED BY tb_produto.nr_referencia
ALTER TABLE tb_produto ALTER COLUMN nr_referencia SET DEFAULT nextval('tb_produto_nr_referencia_seq'::regclass);

ALTER TABLE ONLY tb_compra
     ADD CONSTRAINT pk_compra PRIMARY KEY (nr_nota_fiscal);
ALTER TABLE ONLY tb_item_compra
     ADD CONSTRAINT pk_item_compra PRIMARY KEY (nr_nota_fiscal, nr_referencia);
ALTER TABLE ONLY tb_cliente
     ADD CONSTRAINT pk_pessoa PRIMARY KEY (nr_documento);
ALTER TABLE ONLY tb_produt
     ADD CONSTRAINT pk_produto PRIMARY KEY (nr_referencia);

ALTER TABLE ONLY tb_compra
     ADD CONSTRAINT fk_cliente_compra_01 FOREIGN KEY (nr_documento_cliente) REFERENCES tb_cliente(nr_documento);
ALTER TABLE ONLY tb_item_compra
     ADD CONSTRAINT fk_compra_item_compra_01 FOREIGN KEY (nr_nota_fiscal) REFERENCES tb_compra(nr_nota_fiscal);
ALTER TABLE ONLY tb_item_compr
     ADD CONSTRAINT fk_produto_item_compra_01 FOREIGN KEY (nr_referencia) REFERENCES tb_produto(nr_referencia);

Esse é o conteúdo simplificado da entidade cliente no banco de dados de teste:

 nr_documento |        nm_cliente
--------------+---------------------------
74727756632 | Marta Antonia
56548986527 | Antonia Josefina
47040567970 | Adamantina Pereira
24348435149 | Carlos Augusto
80987468692 | José Silveira
56096344407 | Maria Eleontina de Castro
79056669606 | José da Silva Sauro
31887461081 | Ribamar de Castr
45792555043 | Manoel Bandeira

Esse é o conteudo simplificado da entidade produto no banco de dados de teste:

 nr_referencia |    ds_produto     | vl_venda
---------------+-------------------+----------
1 | Sapato Velho      |    15.00
2 | Sapato Novo       |    25.00
3 | Blusa Velha       |    35.00
4 | Blusa Nova        |    45.00
5 | Calça Jeans Velha |    29.50
6 | Calça Jeans Nova  |    49.50
7 | Peruca Masculina  |   439.9
8 | Camisola          |    19.50

E este é o Script de Carga de Teste para as entidades tb_compra e tb_item_compra:

postgres@banco $ cat ~/scripts/carga_compra_teste.sql
/***************************************************
*
* Script de geração de carga
* Modulo de Compras - Banco de dados de Teste
*
* (c) 2007 Dickson Guedes <guediz at gmail dot com>
*
****************************************************/

INSERT INTO tb_compra (nr_nota_fiscal, dt_compra, nr_documento_cliente
     VALUES (1234567890, now(), 56473847366);

INSERT INTO tb_item_compra (nr_nota_fiscal, nr_referencia, qt_item)
     VALUES (1234567890, 6,  2);
INSERT INTO tb_item_compra (nr_nota_fiscal, nr_referencia, qt_item)
     VALUES (1234567890, 4,  1);
INSERT INTO tb_item_compra (nr_nota_fiscal, nr_referencia, qt_item)
     VALUES (1234567890, 3, 15);
INSERT INTO tb_item_compra (nr_nota_fiscal, nr_referencia, qt_item
     VALUES (1234567890, 2,  2);

INSERT INTO tb_compra (nr_nota_fiscal, dt_compra, nr_documento_cliente
     VALUES (1122334455, now(), 56096344407);

INSERT INTO tb_item_compra (nr_nota_fiscal, nr_referencia, qt_item)
     VALUES (1122334455, 6,  2);
INSERT INTO tb_item_compra (nr_nota_fiscal, nr_referencia, qt_item)
     VALUES (1122334455, 4,  1);
INSERT INTO tb_item_compra (nr_nota_fiscal, nr_referencia, qt_item)
     VALUES (1122334455, 3, 15);
INSERT INTO tb_item_compra (nr_nota_fiscal, nr_referencia, qt_item
     VALUES (1122334455, 2,  2);

E para executá-lo e utilizo o utilitário psql:

postgresql@banco $ psql bdtesteWelcome to psql 8.4devel, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
     \h for help with SQL commands
     \? for help with psql commands
     \g or terminate with semicolon to execute quer
     \q to quit

postgres=# \i ~/scripts/carga_compra_teste.sql

E se eu quisesse tornar esse script interativo?

O utilitário psql além de aceitar instruções SQL, possui um conjunto de instrucoes proprias que nos permitem extenter suas funcionalidades. Utilizaremos duas delas: \echo, que permite enviar um texto para a console do psql e \prompt (a partir da versão 8.3 do PostgreSQL) que permite receber um dado da entrada e salvar um uma variável.

Nosso script acima poderia ficar assim:

/***************************************************
*
* Script de geração de carga
* Modulo de Compras - Banco de dados de Teste
*
* (c) 2007 Dickson Guedes <guediz at gmail dot com>
*
****************************************************/

\echo """"""""""""""""""""""""""""""""""""""""""
\echo " Gerando carga para o ambiente: TESTE   "
\echo "                                        "
\echo " Cenário: Prestacoes de compra a prazo  "
\echo "                                        "
\echo """"""""""""""""""""""""""""""""""""""""""
\echo
\echo Continuar..: Enter
\echo Cancelar...: Ctrl+C

\prompt continua
\unset continuar

\echo
SELECT nr_documento || ' -> ' || nm_cliente AS "Lista de Clientes" FROM tb_cliente;
\echo
\prompt 'Informe um dos números de CPFs acima.: ' v_nr_document
\prompt 'Informe o número da nota fiscal......: ' v_nr_nota_fiscal

\echo '* Inserindo compra para o cliente:' :v_nr_documento 'com número de nota fiscal:' :v_nr_nota_fiscal

INSERT INTO tb_compra (nr_nota_fiscal, dt_compra, nr_documento_cliente) VALUE
     (:v_nr_nota_fiscal, now(), :v_nr_documento);

INSERT INTO tb_item_compra (nr_nota_fiscal, nr_referencia, qt_item) VALUES
     (:v_nr_nota_fiscal, 2, ((RANDOM()*5)+1)::int2),
     (:v_nr_nota_fiscal, 4, ((RANDOM()*5)+1)::int2),
     (:v_nr_nota_fiscal, 7, ((RANDOM()*5)+1)::int2),
     (:v_nr_nota_fiscal, 5, ((RANDOM()*5)+1)::int2);

\echo "* Script finalizado!"

E para executá-lo e utilizo também o utilitário psql:

postgresql@banco $ psql bdtesteWelcome to psql 8.4devel, the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute quer
\q to quit

postgres=# \i ~/scripts/carga_compra_teste.sql

DICA 1: quando usar o \prompt você pode usar 2 (dois) argumentos: um texto explicativo seguido do nome da variável que você deseja armazenar o valor recebido.
DICA 2: os valores das variáveis são recuperados utilizando-se o dois pontos (”:”) precedendo o nome da variável que se deseja ler o valor, como por exemplo \echo ‘Valor da variavel é’ :variavel_qualquer.

DESAFIO 1: Tente alterar o script acima para que os produtos também sejam aleatórios, ou seja, cada vez que o script for executado ele gere uma carga diferente.

DESAFIO 2: Como você trataria o problema de um erro de digitação ou problema de violação de chaves? Você poderia utilizar transações?

Enviado em postgresql | Tagged: , , | 1 Comentário »

ALTER TABLE em massa no PostgreSQL…

Escrito por Guedes em Março 27, 2008

ALTER TABLE em massa no PostgreSQL...Você já se deparou com a necessidade de fazer uma alteração que afeta vários campos de várias tabelas? Imagine a seguinte situação: você possui vários campos em diversas tabelas que representam valores monetários de 10 casas inteiras e 2 decimais, ou seja, tipo numeric(12,2), e por necessidade do cliente o analista informou que isso precisa ser alterado para 15 casas inteiras e 2 decimais, ou seja, tipo numeric(17,2). E agora?

Bem, nosso amigo elefante que nunca esquece, guarda esses dados com bastante carinho e permite que nós, meros mortais, possamos visualizá-los e tomar decisões com eles já que cada banco de dados possui um esquema contendo os dados sobre os seus dados - os metadados. O nome desse esquema é information_schema e contém views que nos permitem, por exemplo, listar os campos de uma tabela com seus respectivos tipos, essa view é declarada como columns. Então o que tem nela?

  SELECT * FROM information_schema.columns;(saída muito grande aqui ...)

Testou? “Coisarada” né? Mas que tal listar as colunas de uma tabela especifica? Suponha que exista uma tabela ‘tb_pessoa’:

SELECT *  FROM information_schema.columns  WHERE table_name =  'tb_pessoa';

 table_catalog | table_schema |  table_name   |      column_name       | ordinal_position | column_default | is_nullable |          data_type          | character_maximum_length | character_octet_length | numeric_precision | numeric_precision_radix | numeric_scale | datetime_precision | interval_type | interval_precision | character_set_catalog | character_set_schema | character_set_name | collation_catalog | collation_schema | collation_name | domain_catalog | domain_schema | domain_name | udt_catalog | udt_schema | udt_name  | scope_catalog | scope_schema | scope_name | maximum_cardinality | dtd_identifier | is_self_referencing
---------------+--------------+---------------+------------------------+------------------+----------------+-------------+-----------------------------+--------------------------+------------------------+-------------------+-------------------------+---------------+--------------------+---------------+--------------------+-----------------------+----------------------+--------------------+-------------------+------------------+----------------+----------------+---------------+-------------+-------------+------------+-----------+---------------+--------------+------------+---------------------+----------------+---------------------
 esquema       | esquema      | tb_pessoa     | tipo_pessoa            |                3 |                | NO          | integer                     |                          |                        |                32 |                       2 |             0 |                    |               |                    |                       |                      |                    |                   |                  |                |                |               |             | esquema     | pg_catalog | int4      |               |              |            |                     | 3              | NO
 esquema       | esquema      | tb_pessoa     | nome                   |                2 |                | NO          | character varying           |                      150 |             1073741824 |                   |                         |               |                    |               |                    |                       |                      |                    |                   |                  |                |                |               |             | esquema     | pg_catalog | varchar   |               |              |            |                     | 2              | NO
 esquema       | esquema      | tb_pessoa     | nome_personalizado     |                9 |                | YES         | character varying           |                       25 |             1073741824 |                   |                         |               |                    |               |                    |                       |                      |                    |                   |                  |                |                |               |             | esquema     | pg_catalog | varchar   |               |              |            |                     | 9              | NO
 esquema       | esquema      | tb_pessoa     | dt_inclusao            |                5 |                | NO          | date                        |                          |                        |                   |                         |               |                    |               |                    |                       |                      |                    |                   |                  |                |                |               |             | esquema     | pg_catalog | date      |               |              |            |                     | 5              | NO
 esquema       | esquema      | tb_pessoa     | nro_documento          |                1 |                | NO          | numeric                     |                          |                        |                14 |                      10 |             0 |                    |               |                    |                       |                      |                    |                   |                  |                |                |               |             | esquema     | pg_catalog | numeric   |               |              |            |                     | 1              | NO

Melhorou né? Mas que tal agora mostrar só o que interessa? Como por exemplo, o nome ta tabela, o nome da coluna, o tipo da mesma e se ela aceita nulo?

SELECT    table_name      AS nome_tabela,

column_name     AS nome_coluna,

data_type       AS tipo,

is_nullable     AS aceita_nulo

FROM

information_schema.columns

WHERE

table_name = 'tb_pessoa';

nome_tabela  |      nome_coluna       |            tipo             | aceita_nulo

---------------+------------------------+-----------------------------+-------------

tb_pessoa     | tipo_pessoa            | integer                     | NO

tb_pessoa     | nome                   | character varying           | NO

tb_pessoa     | nome_personalizado     | character varying           | YES

tb_pessoa     | dt_inclusao            | date                        | NO

tb_pessoa     | nro_documento          | numeric                     | NO

Melhor ainda né? Se você analisar a descrição da view columns perceberá que pode melhorar a saida acima. Vejamos:

                      Visão "information_schema.columns"          Coluna          |                Tipo                | Modificadores

--------------------------+------------------------------------+---------------

table_catalog            | information_schema.sql_identifier  |

table_schema             | information_schema.sql_identifier  |

table_name               | information_schema.sql_identifier  |

column_name              | information_schema.sql_identifier  |

ordinal_position         | information_schema.cardinal_number |

column_default           | information_schema.character_data  |

is_nullable              | information_schema.character_data  |

data_type                | information_schema.character_data  |

character_maximum_length | information_schema.cardinal_number |

character_octet_length   | information_schema.cardinal_number |

numeric_precision        | information_schema.cardinal_number |

numeric_precision_radix  | information_schema.cardinal_number |

numeric_scale            | information_schema.cardinal_number |

datetime_precision       | information_schema.cardinal_number |

interval_type            | information_schema.character_data  |

interval_precision       | information_schema.character_data  |

character_set_catalog    | information_schema.sql_identifier  |

character_set_schema     | information_schema.sql_identifier  |

character_set_name       | information_schema.sql_identifier  |

collation_catalog        | information_schema.sql_identifier  |

collation_schema         | information_schema.sql_identifier  |

collation_name           | information_schema.sql_identifier  |

domain_catalog           | information_schema.sql_identifier  |

domain_schema            | information_schema.sql_identifier  |

domain_name              | information_schema.sql_identifier  |

udt_catalog              | information_schema.sql_identifier  |

udt_schema               | information_schema.sql_identifier  |

udt_name                 | information_schema.sql_identifier  |

scope_catalog            | information_schema.sql_identifier  |

scope_schema             | information_schema.sql_identifier  |

scope_name               | information_schema.sql_identifier  |

maximum_cardinality      | information_schema.cardinal_number |

dtd_identifier           | information_schema.sql_identifier  |

is_self_referencing      | information_schema.character_data  |

SELECT

table_name        AS nome_tabela,

column_name       AS nome_coluna,

data_type         AS tipo,

numeric_precision AS digitos,

numeric_scale     AS decimais,

is_nullable       AS aceita_nulo

FROM

information_schema.columns

WHERE

data_type = 'numeric';

Agora só falta juntar tudo isso numa panela, cozinhar por alguns minutos e servir o script que irá satisfazer o nosso problema inicial (lembra? mudar de numeric(12,2) para numeric(17,2)):

SELECT     'ALTER TABLE '   || table_name  ||

' ALTER COLUMN ' || column_name ||

' TYPE numeric(17,2);'

FROM

information_schema.columns

WHERE

data_type = 'numeric'  AND

numeric_precision = 12 AND

numeric_scale     = 2;

?column?

-----------------------------------------------------------------------------------

ALTER TABLE tb_funcionario ALTER COLUMN remuneracao_basica TYPE numeric(17,2);

ALTER TABLE tb_pessoa_juridica ALTER COLUMN valor_receita TYPE numeric(17,2);

ALTER TABLE tb_fonte_renda_pf ALTER COLUMN valor_renda TYPE numeric(17,2);

ALTER TABLE tb_caixa ALTER COLUMN saldo_dia TYPE numeric(17,2);

--- CORTE ---

Pronto, ai está o nosso script! Você precisa apenas executá-lo agora.

DESAFIO: como a saida do comando SQL é grande, redirecione a saida para um arquivo e execute-o via psql.

Bom, é isso “:D

Enviado em postgresql | Tagged: , , , | 4 Comentários »

Será que meu dump foi gerado com sucesso?

Escrito por Guedes em Março 26, 2008

Será que meu dump foi gerado com sucesso? Uma das atividades mais comuns de um DBA é a geração do arquivo de dump de suas bases de dados, que nada mais é do que um arquivo contendo a imagem do seu banco de dados em um determinado instante do tempo. Como existem ferramentas de linha de comando que geram esses arquivos, é bastante comum utilizá-las em scripts autônomos, agendados diariamente no período noturno. Mas nem tudo são flores e podemos ser supreendidos ao saber que justo aquele dump que precisávamos não foi executado com sucesso. E agora?

Bom, como já diz o ditado “é melhor prevenir do que remediar”… então, que tal melhorar o script que gera o dump?

AVISO: os passos a seguir não se aplicam ao S.O. Windows ‘puro’, você precisa ter o Cygwin instalado!

Nos sistemas operacionais unix-like possuimos a saida padrão (conhecida por stdout, cujo descritor de arquivo é 1), a saída padrão de erros (conhecida por stderr, cujo descritor de arquivo é 2) e a entrada padrão (conhecida por stdin, cujo descritor de arquivo é 0). Estes recursos podem ser utilizados para redirecionar as saidas de nossos programas. No caso do nosso amigo pg_dump geralmente utilizamos ele assim:

postgres@meu_banco ~$ pg_dump meu_banco > meu_banco.dump

O que estamos fazendo, nada mais é do que redirecionar a saída padrão (stdout) do pg_dump para um arquivo chamado ‘meu_banco.dump’. Mas e se ocorrer algum imprevisto, como falta de espaço em disco, por exemplo? Neste caso, podemos redirecionar a saída de erros (que por padrão é a console) para um arquivo com o seguinte comando:

postgres@meu_banco ~$ pg_dump meu_banco > meu_banco.dump 2> meu_banco.erro

A única diferença foi a adição de ‘2> meu_banco.erro’ ao final do comando. No caso isso indica que os dados enviados para a saída padrão de erros (stderr, descritor de arquivo 2), devem ser redirecionados para o arquivo ‘meu_banco.erro’. Sendo assim, após o comando ter sido executado, pode-se verificar se o arquivo ‘meu_banco.erro’ está vazio (indicando sucesso na operação) ou contém algo (indicando que houve erro).

Este método é interessante porque você guarda o erro ocorrido, o que via script pode ajudar a entender a origem do problema e até mesmo servir de conteúdo para um e-mail automaticamente enviado para o DBA.

Outro método que você pode utilizar é redirecionar a saida padrão de erros para /dev/null e utilizar os operadores ‘&&’ e ‘||’ do shell.

pg_dump > meu_banco.dump 2>/dev/null && echo "OK" || echo "ERRO"

No caso acima, se tudo ocorrer bem, ele ecoará “OK” do contrário “ERRO” será retornado.

Colocando tudo num script

Podemos utilizar os conceitos acima para criar um script que automatize este processo todo. Segue:

#!/bin/sh
###############################################
#
# Script de geração de dump full
#
# (c) 2006-2008 Dickson Guedes <guediz at gmail com>
#
###############################################

# Email DBA
CFG_EMAIL="dba@minhaempresa.com"

# Variaveis de mensagens
MSG_OK="Dump gerado com sucesso!"
MSG_ERRO="Dump gerado com erros!"
MSG_DATA=`date +"%Y-%m-%d"`

# Variaveis de caminhos dos utilitarios
PRG_PGDUMP="/usr/bin/pg_dump"

# Variaveis dos arquivos gerados
ARQ_DUMP="meu_banco"
ARQ_DUMP_OK="$ARQ_DUMP-$MSG_DATA.dump"
ARQ_DUMP_ERRO="$ARQ_DUMP-$MSG_DATA.erro"

###############################################

$PRG_PGDUMP >$ARQ_DUMP_OK 2>$ARQ_DUMP_ERRO && STATUS="SUCESSO" || STATUS="ERRO"

if [ "$STATUS" = "SUCESSO" ]; then
        echo "$MSG_OK"   | mail -s"$MSG_OK" $CFG_EMAIL
else
        echo "$MSG_ERRO" | mail -s"$MSG_ERRO" $CFG_EMAIL < $ARQ_DUMP_ERRO
fi

###############################################

DESAFIO: alterar o script acima adicionando a característica de passar o nome do banco de dados através de parâmetros de linha de comando.

Bom, é isso… “:)

Enviado em postgresql | Tagged: , , , | Nenhum comentário »