Transaction Autonomous – O Que, Quando, Onde e Por Que

Do que se trata o artigo:

Neste artigo será apresentada a utilização do pragma autonomous Transaction para escrita de códigos autônomos em rotinas PL/SQL, as quais são executadas e commitadas na base independentemente do resultado da transação master que invocou essa rotina.


Em que situação o tema é útil:

Esta funcionalidade é bastante utilizada para geração de logs de erro de transação, onde a transação master sofre rollback depois de uma falha, mas é possível gerar um log contento os dados da transação que resultaram no erro.

Um subprograma normalmente tem suas operações salvas ou não no banco de dados de acordo com o que acontece com o programa principal onde ele está inserido. Isso quer dizer que, se uma procedure chama uma função e a procedure falha, nem as alterações feitas pela procedure nem as alterações feitas pela função são salvas na base, afinal trata-se da mesma transação, a qual é atômica (indivisível, ou seja, ou ela toda é commitada ou ela toda sofre rollback). No entanto, se a função contiver o pragma autonomous_transaction, ela se comporta como uma segunda transação, que é isolada e independente, e suas alterações na base podem ser salvas ou não independentemente da transação master que a originou.

A diretiva AUTONOMOUS_TRANSACTION altera a forma com que a transação trata a um subprograma. Um pragma na verdade é uma diretiva de compilação e os subprogramas marcados com este pragma são processados em tempo de compilação e não em tempo de execução, e passam informações diretamente ao compilador.

O termo AUTONOMOUS_TRANSACTION se refere à habilidade do PL/SQL temporariamente suspender a transação corrente e iniciar uma nova transação, totalmente independente, que funciona de forma autônoma com relação à transação original.

Imagine a seguinte situação: Para fins de auditoria, criamos uma tabela de log que contém os dados referentes a todas as alterações feitas nos dados de 5 tabelas críticas do banco de dados da empresa, armazenando o IP da máquina que originou a transação, qual tabela sofreu alteração, o que foi feito, etc, e um trigger é responsável por inserir tais dados nessa tabela. Pois bem, vamos supor então que por um motivo ou outro essa transação tenha falhado. Não desejamos que os logs de auditoria também sofram rollback, pois estaremos perdendo dados preciosos de tentativas frustradas de acesso não autorizado.

Neste caso, o trigger deve disparar um subprograma autônomo, cujo sucesso da transação não dependa do resultado da transação principal que o originou.

A utilização em tratativas de logs de auditoria são comuns e não causam nenhum tipo de problema ao banco de dados, uma vez que não está lidando com tabelas de negócio, ou seja, que guardam dados essenciais para o negócio. Por este motivo a transação autônoma é segura, pois a integridade do banco de dados está resguardada.

Digo isso porque já vi muitos códigos resolvendo regras de negócio com transações autônomas, o que pode gerar um problema grande para o banco de dados. Imagine que a alteração de um valor em uma tabela deve causar alterações em outras tabelas. Se a primeira alteração falha, o ideal é que as demais alterações não ocorram… neste caso o procedimento que faria as demais alterações não poderia jamais ser autônomo!

Qualquer subprograma, como procedures, funções ou até mesmo blocos anônimos PL/SQL podem conter este pragma. No entanto, se for utilizado dentro de pacotes, o pragma deve ser declarado para as funções e procedures que fazem parte do pacote, e não para o pacote em si.

Exemplo de Utilização

Como um exemplo de utilização da transação autônoma, vamos assumir que precisamos gravar logs de erro em uma tabela do banco de dados. Precisamos fazer rollback da transação principal porque ela resultaria em um erro, mas não queremos perder o log do que aconteceu nessa transação. A tabela que conterá os logs de erro possui a seguinte estrutura:

CREATE TABLE tb_log_erros(

  codigo integer,

  msg varchar2(2000),

  data date,

  usuario varchar2(50),

  nm_mach varchar2(100),

  prog varchar2(100)

);

O procedimento que deve ser invocado para inserir o log do erro na tabela é:

CREATE OR REPLACE PROCEDURE grava_log_erros(

   log_codigo IN INTEGER,

   log_msg IN VARCHAR2) IS

PRAGMA AUTONOMOUS_TRANSACTION;

CURSOR cur_erro IS

SELECT machine, program

FROM v$session

WHERE audsid = USERENV(‘SESSIONID’);

PT = Parent Transaction;

CT = Child Autonomous Transaction;

rec cur_erro%ROWTYPE;

BEGIN

   —

   OPEN cur_erro;

   FETCH cur_erro INTO rec;

   CLOSE cur_erro;

   —

   INSERT INTO tb_log_erros values (

       log_codigo,

       log_msg,

       SYSDATE,

       USER,

       rec.machine,

       rec.program

   );

   COMMIT;

EXCEPTION

   WHEN OTHERS THEN

       ROLLBAACK;

END;

/

Para testar o código acima, podemos executar o seguinte bloco anônimo PL/SQL:

BEGIN

    INSERT INTO HR.EMPLOYEES (first_name) VALUES (‘Maria’);

    COMMIT;

EXCEPTION

    WHEN OTHERS THEN

         grava_log_erros(SQLCODE,SQLERRM);

    ROLLBACK;

    RAISE;

END;

Ao executar o código acima, basta verificar nas tabelas EMPLOYEES e TB_LOG_ERROS as linhas inseridas, como segue:

SQL> select * from employees where first_name = ‘Maria’;

no rows selected.

SQL> select codigo, msg from tb_log_erros;

CODIGOMSG

——————————————————————————————————–

-1400ORA-01400: cannot insert NULL into (“HR”.”EMPLOYEES”.”EMPLOYEE_ID”)

Referências

BURLESON CONSULTING. PL/SQL Autonomous Transaction Tips. Burleson Consulting, 2015. Disponivel em: http://www.dba-oracle.com/t_autonomous_transaction.htm

ORACLE HELP CENTER. Autonomous_transaction Pragma. Database PL/SQL User’s Guide and Reference, 2017. Disponivel em: https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/autonotransaction_pragma.htm

Gatilhos escritos em PL/pgSQL

A linguagem PL/pgSQL pode ser utilizada para definir procedimentos de gatilho. O procedimento de gatilho é criado pelo comando CREATE FUNCTION, declarando o procedimento como uma função sem argumentos e que retorna o tipo trigger. Deve ser observado que a função deve ser declarada sem argumentos, mesmo que espere receber os argumentos especificados no comando CREATE TRIGGER — os argumentos do gatilho são passados através de TG_ARGV, conforme descrito abaixo.

Quando uma função escrita em PL/pgSQL é chamada como um gatilho, diversas variáveis especiais são criadas automaticamente no bloco de nível mais alto. São estas:

NEW
Tipo de dado RECORD; variável contendo a nova linha do banco de dados, para as operações de INSERT/UPDATE nos gatilhos no nível de linha. O valor desta variável é NULL nos gatilhos no nível de instrução.
OLD
Tipo de dado RECORD; variável contendo a antiga linha do banco de dados, para as operações de UPDATE/DELETE nos gatilhos no nível de linha. O valor desta variável é NULL nos gatilhos no nível de instrução.
TG_NAME
Tipo de dado name; variável contendo o nome do gatilho disparado.
TG_WHEN
Tipo de dado text; uma cadeia de caracteres contendo BEFORE ou AFTER, dependendo da definição do gatilho.
TG_LEVEL
Tipo de dado text; uma cadeia de caracteres contendo ROW ou STATEMENT, dependendo da definição do gatilho.
TG_OP
Tipo de dado text; uma cadeia de caracteres contendo INSERT, UPDATE, ou DELETE, informando para qual operação o gatilho foi disparado.
TG_RELID
Tipo de dado oid; o ID de objeto da tabela que causou o disparo do gatilho.
TG_RELNAME
Tipo de dado name; o nome da tabela que causou o disparo do gatilho.
TG_NARGS
Tipo de dado integer; o número de argumentos fornecidos ao procedimento de gatilho na instrução CREATE TRIGGER.
TG_ARGV[]
Tipo de dado matriz de text; os argumentos da instrução CREATE TRIGGER. O contador do índice começa por 0. Índices inválidos (menor que 0 ou maior ou igual a tg_nargs) resultam em um valor nulo.

Uma função de gatilho deve retornar nulo, ou um valor registro/linha possuindo a mesma estrutura da tabela para a qual o gatilho foi disparado.

Os gatilhos no nível de linha disparados BEFORE (antes) podem retornar nulo, para sinalizar ao gerenciador do gatilho para pular o restante da operação para esta linha (ou seja, os gatilhos posteriores não serão disparados, e não ocorrerá o INSERT/UPDATE/DELETE para esta linha. Se for retornado um valor diferente de nulo, então a operação prossegue com este valor de linha. Retornar um valor de linha diferente do valor original de NEW altera a linha que será inserida ou atualizada (mas não tem efeito direto no caso do DELETE). Para alterar a linha a ser armazenada, é possível substituir valores individuais diretamente em NEW e retornar o NEW modificado, ou construir um novo registro/linha completo a ser retornado.

O valor retornado por um gatilho BEFORE ou AFTER no nível de instrução, ou por um gatilho AFTER no nível de linha, é sempre ignorado; pode muito bem ser nulo. Entretanto, qualquer um destes tipos de gatilho pode interromper toda a operação gerando um erro.

O Exemplo 35-1 mostra um exemplo de procedimento de gatilho escrito em PL/pgSQL.

Exemplo 35-1. Procedimento de gatilho PL/pgSQL

O gatilho deste exemplo garante que quando é inserida ou atualizada uma linha na tabela, fica sempre registrado nesta linha o usuário que efetuou a inserção ou a atualização, e quando isto ocorreu. Além disso, o gatilho verifica se é fornecido o nome do empregado, e se o valor do salário é um número positivo.

CREATE TABLE emp (
    nome_emp       text,
    salario        integer,
    ultima_data    timestamp,
    ultimo_usuario text
);

CREATE FUNCTION emp_gatilho() RETURNS trigger AS $emp_gatilho$
    BEGIN
        -- Verificar se foi fornecido o nome e o salário do empregado
        IF NEW.nome_emp IS NULL THEN
            RAISE EXCEPTION 'O nome do empregado não pode ser nulo';
        END IF;
        IF NEW.salario IS NULL THEN
            RAISE EXCEPTION '% não pode ter um salário nulo', NEW.nome_emp;
        END IF;

        -- Quem paga para trabalhar?
        IF NEW.salario < 0 THEN
            RAISE EXCEPTION '% não pode ter um salário negativo', NEW.nome_emp;
        END IF;

        -- Registrar quem alterou a folha de pagamento e quando
        NEW.ultima_data := 'now';
        NEW.ultimo_usuario := current_user;
        RETURN NEW;
    END;
$emp_gatilho$ LANGUAGE plpgsql;

CREATE TRIGGER emp_gatilho BEFORE INSERT OR UPDATE ON emp
    FOR EACH ROW EXECUTE PROCEDURE emp_gatilho();

INSERT INTO emp (nome_emp, salario) VALUES ('João',1000);
INSERT INTO emp (nome_emp, salario) VALUES ('José',1500);
INSERT INTO emp (nome_emp, salario) VALUES ('Maria',2500);

SELECT * FROM emp;

 nome_emp | salario |        ultima_data         | ultimo_usuario
----------+---------+----------------------------+----------------
 João     |    1000 | 2005-11-25 07:07:50.59532  | folha
 José     |    1500 | 2005-11-25 07:07:50.691905 | folha
 Maria    |    2500 | 2005-11-25 07:07:50.694995 | folha
(3 linhas)

Exemplo 35-2. Procedimento de gatilho PL/pgSQL para registrar inserção e atualização

O gatilho deste exemplo garante que quando é inserida ou atualizada uma linha na tabela, fica sempre registrado nesta linha o usuário que efetuou a inserção ou a atualização, e quando isto ocorreu. Porém, diferentemente do gatilho anterior, a criação e a atualização da linha são registradas em colunas diferentes. Além disso, o gatilho verifica se é fornecido o nome do empregado, e se o valor do salário é um número positivo. [1]

CREATE TABLE emp (
    nome_emp       text,
    salario        integer,
    usu_cria       text,        -- Usuário que criou a linha
    data_cria      timestamp,   -- Data da criação da linha
    usu_atu        text,        -- Usuário que fez a atualização
    data_atu       timestamp    -- Data da atualização
);

CREATE FUNCTION emp_gatilho() RETURNS trigger AS $emp_gatilho$
    BEGIN
        -- Verificar se foi fornecido o nome do empregado
        IF NEW.nome_emp IS NULL THEN
            RAISE EXCEPTION 'O nome do empregado não pode ser nulo';
        END IF;
        IF NEW.salario IS NULL THEN
            RAISE EXCEPTION '% não pode ter um salário nulo', NEW.nome_emp;
        END IF;

        -- Quem paga para trabalhar?
        IF NEW.salario < 0 THEN
            RAISE EXCEPTION '% não pode ter um salário negativo', NEW.nome_emp;
        END IF;

        -- Registrar quem criou a linha e quando
        IF (TG_OP = 'INSERT') THEN
            NEW.data_cria := current_timestamp;
            NEW.usu_cria  := current_user;
        -- Registrar quem alterou a linha e quando
        ELSIF (TG_OP = 'UPDATE') THEN
            NEW.data_atu := current_timestamp;
            NEW.usu_atu  := current_user;
        END IF;
        RETURN NEW;
    END;
$emp_gatilho$ LANGUAGE plpgsql;

CREATE TRIGGER emp_gatilho BEFORE INSERT OR UPDATE ON emp
    FOR EACH ROW EXECUTE PROCEDURE emp_gatilho();

INSERT INTO emp (nome_emp, salario) VALUES ('João',1000);
INSERT INTO emp (nome_emp, salario) VALUES ('José',1500);
INSERT INTO emp (nome_emp, salario) VALUES ('Maria',250);
UPDATE emp SET salario = 2500 WHERE nome_emp = 'Maria';

SELECT * FROM emp;

 nome_emp | salario | usu_cria |         data_cria          | usu_atu |          data_atu
----------+---------+----------+----------------------------+---------+----------------------------
 João     |    1000 | folha    | 2005-11-25 08:11:40.63868  |         |
 José     |    1500 | folha    | 2005-11-25 08:11:40.674356 |         |
 Maria    |    2500 | folha    | 2005-11-25 08:11:40.679592 | folha   | 2005-11-25 08:11:40.682394
(3 linhas)

Uma outra maneira de registrar as modificações na tabela envolve a criação de uma nova tabela contendo uma linha para cada inserção, atualização ou exclusão que ocorra. Esta abordagem pode ser considerada como uma auditoria das mudanças na tabela. O Exemplo 35-3 mostra um procedimento de gatilho de auditoria em PL/pgSQL.

Exemplo 35-3. Procedimento de gatilho PL/pgSQL para auditoria

Este gatilho garante que todas as inserções, atualizações e exclusões de linha na tabela emp são registradas na tabela emp_audit, para permitir auditar as operações efetuadas na tabela emp. O nome de usuário e a hora corrente são gravadas na linha, junto com o tipo de operação que foi realizada.

CREATE TABLE emp (
    nome_emp    text NOT NULL,
    salario     integer
);

CREATE TABLE emp_audit(
    operacao    char(1)   NOT NULL,
    usuario     text      NOT NULL,
    data        timestamp NOT NULL,
    nome_emp    text      NOT NULL,
    salario     integer
);

CREATE OR REPLACE FUNCTION processa_emp_audit() RETURNS TRIGGER AS $emp_audit$
    BEGIN
        --
        -- Cria uma linha na tabela emp_audit para refletir a operação
        -- realizada na tabela emp. Utiliza a variável especial TG_OP
        -- para descobrir a operação sendo realizada.
        --
        IF (TG_OP = 'DELETE') THEN
            INSERT INTO emp_audit SELECT 'E', user, now(), OLD.*;
            RETURN OLD;
        ELSIF (TG_OP = 'UPDATE') THEN
            INSERT INTO emp_audit SELECT 'A', user, now(), NEW.*;
            RETURN NEW;
        ELSIF (TG_OP = 'INSERT') THEN
            INSERT INTO emp_audit SELECT 'I', user, now(), NEW.*;
            RETURN NEW;
        END IF;
        RETURN NULL; -- o resultado é ignorado uma vez que este é um gatilho AFTER
    END;
$emp_audit$ language plpgsql;

CREATE TRIGGER emp_audit
AFTER INSERT OR UPDATE OR DELETE ON emp
    FOR EACH ROW EXECUTE PROCEDURE processa_emp_audit();

INSERT INTO emp (nome_emp, salario) VALUES ('João',1000);
INSERT INTO emp (nome_emp, salario) VALUES ('José',1500);
INSERT INTO emp (nome_emp, salario) VALUES ('Maria',250);
UPDATE emp SET salario = 2500 WHERE nome_emp = 'Maria';
DELETE FROM emp WHERE nome_emp = 'João';

SELECT * FROM emp;

 nome_emp | salario
----------+---------
 José     |    1500
 Maria    |    2500
(2 linhas)

SELECT * FROM emp_audit;

 operacao | usuario |            data            | nome_emp | salario
----------+---------+----------------------------+----------+---------
 I        | folha   | 2005-11-25 09:06:03.008735 | João     |    1000
 I        | folha   | 2005-11-25 09:06:03.014245 | José     |    1500
 I        | folha   | 2005-11-25 09:06:03.049443 | Maria    |     250
 A        | folha   | 2005-11-25 09:06:03.052972 | Maria    |    2500
 E        | folha   | 2005-11-25 09:06:03.056774 | João     |    1000
(5 linhas)

Exemplo 35-4. Procedimento de gatilho PL/pgSQL para auditoria no nível de coluna

Este gatilho registra todas as atualizações realizadas nas colunas nome_emp e salario da tabela emp na tabela emp_audit (isto é, as colunas são auditadas). O nome de usuário e a hora corrente são registrados junto com a chave da linha (id) e a informação atualizada. Não é permitido atualizar a chave da linha. Este exemplo difere do anterior pela auditoria ser no nível de coluna, e não no nível de linha. [2]

CREATE TABLE emp (
    id          serial  PRIMARY KEY,
    nome_emp    text    NOT NULL,
    salario     integer
);

CREATE TABLE emp_audit(
    usuario         text      NOT NULL,
    data            timestamp NOT NULL,
    id              integer   NOT NULL,
    coluna          text      NOT NULL,
    valor_antigo    text      NOT NULL,
    valor_novo      text      NOT NULL
);

CREATE OR REPLACE FUNCTION processa_emp_audit() RETURNS TRIGGER AS $emp_audit$
    BEGIN
        --
        -- Não permitir atualizar a chave primária
        --
        IF (NEW.id <> OLD.id) THEN
            RAISE EXCEPTION 'Não é permitido atualizar o campo ID';
        END IF;
        --
        -- Inserir linhas na tabela emp_audit para refletir as alterações
        -- realizada na tabela emp.
        --
        IF (NEW.nome_emp <> OLD.nome_emp) THEN
           INSERT INTO emp_audit SELECT current_user, current_timestamp,
                       NEW.id, 'nome_emp', OLD.nome_emp, NEW.nome_emp;
        END IF;
        IF (NEW.salario <> OLD.salario) THEN
           INSERT INTO emp_audit SELECT current_user, current_timestamp,
                       NEW.id, 'salario', OLD.salario, NEW.salario;
        END IF;
        RETURN NULL; -- o resultado é ignorado uma vez que este é um gatilho AFTER
    END;
$emp_audit$ language plpgsql;

CREATE TRIGGER emp_audit
AFTER UPDATE ON emp
    FOR EACH ROW EXECUTE PROCEDURE processa_emp_audit();

INSERT INTO emp (nome_emp, salario) VALUES ('João',1000);
INSERT INTO emp (nome_emp, salario) VALUES ('José',1500);
INSERT INTO emp (nome_emp, salario) VALUES ('Maria',2500);
UPDATE emp SET salario = 2500 WHERE id = 2;
UPDATE emp SET nome_emp = 'Maria Cecília' WHERE id = 3;
UPDATE emp SET id=100 WHERE id=1;
ERRO:  Não é permitido atualizar o campo ID

SELECT * FROM emp;

 id |   nome_emp    | salario
----+---------------+---------
  1 | João          |    1000
  2 | José          |    2500
  3 | Maria Cecília |    2500
(3 linhas)

SELECT * FROM emp_audit;

 usuario |            data            | id |  coluna  | valor_antigo |  valor_novo
---------+----------------------------+----+----------+--------------+---------------
 folha   | 2005-11-25 12:21:08.493268 |  2 | salario  | 1500         | 2500
 folha   | 2005-11-25 12:21:08.49822  |  3 | nome_emp | Maria        | Maria Cecília
(2 linhas)

Uma das utilizações de gatilho é para manter uma tabela contendo o sumário de outra tabela. O sumário produzido pode ser utilizado no lugar da tabela original em diversas consultas — geralmente com um tempo de execução bem menor. Esta técnica é muito utilizada em Armazém de Dados (Data Warehousing), onde as tabelas dos dados medidos ou observados (chamadas de tabelas fato) podem ser muito grandes. O Exemplo 35-5 mostra um procedimento de gatilho em PL/pgSQL para manter uma tabela de sumário de uma tabela fato em um armazém de dados.

Exemplo 35-5. Procedimento de gatilho PL/pgSQL para manter uma tabela sumário

O esquema que está detalhado a seguir é parcialmente baseado no exemplo Grocery Store do livro The Data Warehouse Toolkit de Ralph Kimball.

--
-- Main tables - time dimension and sales fact.
--
CREATE TABLE time_dimension (
    time_key                    integer NOT NULL,
    day_of_week                 integer NOT NULL,
    day_of_month                integer NOT NULL,
    month                       integer NOT NULL,
    quarter                     integer NOT NULL,
    year                        integer NOT NULL
);
CREATE UNIQUE INDEX time_dimension_key ON time_dimension(time_key);

CREATE TABLE sales_fact (
    time_key                    integer NOT NULL,
    product_key                 integer NOT NULL,
    store_key                   integer NOT NULL,
    amount_sold                 numeric(12,2) NOT NULL,
    units_sold                  integer NOT NULL,
    amount_cost                 numeric(12,2) NOT NULL
);
CREATE INDEX sales_fact_time ON sales_fact(time_key);

--
-- Summary table - sales by time.
--
CREATE TABLE sales_summary_bytime (
    time_key                    integer NOT NULL,
    amount_sold                 numeric(15,2) NOT NULL,
    units_sold                  numeric(12) NOT NULL,
    amount_cost                 numeric(15,2) NOT NULL
);
CREATE UNIQUE INDEX sales_summary_bytime_key ON sales_summary_bytime(time_key);

--
-- Function and trigger to amend summarized column(s) on UPDATE, INSERT, DELETE.
--
CREATE OR REPLACE FUNCTION maint_sales_summary_bytime() RETURNS TRIGGER AS $maint_sales_summary_bytime$
    DECLARE
        delta_time_key          integer;
        delta_amount_sold       numeric(15,2);
        delta_units_sold        numeric(12);
        delta_amount_cost       numeric(15,2);
    BEGIN

        -- Work out the increment/decrement amount(s).
        IF (TG_OP = 'DELETE') THEN

            delta_time_key = OLD.time_key;
            delta_amount_sold = -1 * OLD.amount_sold;
            delta_units_sold = -1 * OLD.units_sold;
            delta_amount_cost = -1 * OLD.amount_cost;

        ELSIF (TG_OP = 'UPDATE') THEN

            -- forbid updates that change the time_key -
            -- (probably not too onerous, as DELETE + INSERT is how most
            -- changes will be made).
            IF ( OLD.time_key != NEW.time_key) THEN
                RAISE EXCEPTION 'Update of time_key : % -> % not allowed', OLD.time_key, NEW.time_key;
            END IF;

            delta_time_key = OLD.time_key;
            delta_amount_sold = NEW.amount_sold - OLD.amount_sold;
            delta_units_sold = NEW.units_sold - OLD.units_sold;
            delta_amount_cost = NEW.amount_cost - OLD.amount_cost;

        ELSIF (TG_OP = 'INSERT') THEN

            delta_time_key = NEW.time_key;
            delta_amount_sold = NEW.amount_sold;
            delta_units_sold = NEW.units_sold;
            delta_amount_cost = NEW.amount_cost;

        END IF;


        -- Update the summary row with the new values.
        UPDATE sales_summary_bytime
            SET amount_sold = amount_sold + delta_amount_sold,
                units_sold = units_sold + delta_units_sold,
                amount_cost = amount_cost + delta_amount_cost
            WHERE time_key = delta_time_key;


        -- There might have been no row with this time_key (e.g new data!).
        IF (NOT FOUND) THEN
            BEGIN
                INSERT INTO sales_summary_bytime (
                            time_key,
                            amount_sold,
                            units_sold,
                            amount_cost)
                    VALUES (
                            delta_time_key,
                            delta_amount_sold,
                            delta_units_sold,
                            delta_amount_cost
                           );
            EXCEPTION
                --
                -- Catch race condition when two transactions are adding data
                -- for a new time_key.
                --
                WHEN UNIQUE_VIOLATION THEN
                    UPDATE sales_summary_bytime
                        SET amount_sold = amount_sold + delta_amount_sold,
                            units_sold = units_sold + delta_units_sold,
                            amount_cost = amount_cost + delta_amount_cost
                        WHERE time_key = delta_time_key;

            END;
        END IF;
        RETURN NULL;

    END;
$maint_sales_summary_bytime$ LANGUAGE plpgsql;

CREATE TRIGGER maint_sales_summary_bytime
AFTER INSERT OR UPDATE OR DELETE ON sales_fact
    FOR EACH ROW EXECUTE PROCEDURE maint_sales_summary_bytime();

Exemplo 35-6. Procedimento de gatilho para controlar sobreposição de datas

O gatilho deste exemplo verifica se o compromiso sendo agendado ou modificado se sobrepõe a outro compromisso já agendado. Se houver sobreposição, emite mensagem de erro e não permite a operação. [3]

Abaixo está mostrado o script utilizado para criar a tabela, a função de gatilho e os gatilhos de inserção e atualização.

CREATE TABLE agendamentos (
    id          SERIAL PRIMARY KEY,
    nome        TEXT,
    evento      TEXT,
    data_inicio TIMESTAMP,
    data_fim    TIMESTAMP
);

CREATE FUNCTION fun_verifica_agendamentos() RETURNS "trigger" AS
$fun_verifica_agendamentos$
    BEGIN
        /* Verificar se a data de início é maior que a data de fim */
        IF NEW.data_inicio > NEW.data_fim THEN
           RAISE EXCEPTION 'A data de início não pode ser maior que a data de fim';
        END IF;
        /* Verificar se há sobreposição com agendamentos existentes */
        IF EXISTS (
            SELECT 1
                FROM agendamentos
                WHERE nome = NEW.nome
                  AND ((data_inicio, data_fim) OVERLAPS
                       (NEW.data_inicio, NEW.data_fim))
        )
        THEN
            RAISE EXCEPTION 'impossível agendar - existe outro compromisso';
        END IF;
        RETURN NEW;
    END;
$fun_verifica_agendamentos$ LANGUAGE plpgsql;

COMMENT ON FUNCTION fun_verifica_agendamentos() IS
    'Verifica se o agendamento é possível';

CREATE TRIGGER trg_agendamentos_ins
    BEFORE INSERT ON agendamentos
    FOR EACH ROW
    EXECUTE PROCEDURE fun_verifica_agendamentos();

CREATE TRIGGER trg_agendamentos_upd
    BEFORE UPDATE ON agendamentos
    FOR EACH ROW
    EXECUTE PROCEDURE fun_verifica_agendamentos();

Abaixo está mostrado um exemplo de utilização do gatilho. Deve ser observado que os intervalos (‘2005-08-23 14:00:00’, ‘2005-08-23 15:00:00’) e (‘2005-08-23 15:00:00’, ‘2005-08-23 16:00:00’) não se sobrepõem, uma vez que o primeiro intervalo termina às quinze horas, enquanto o segundo intervalo inicia às quinze horas, estando, portanto, o segundo intervalo imediatamente após o primeiro.

=> INSERT INTO agendamentos VALUES (DEFAULT,'Joana','Congresso','2005-08-23','2005-08-24');
=> INSERT INTO agendamentos VALUES (DEFAULT,'Joana','Viagem','2005-08-24','2005-08-26');
=> INSERT INTO agendamentos VALUES (DEFAULT,'Joana','Palestra','2005-08-23','2005-08-26');
ERRO:  impossível agendar - existe outro compromisso
=> INSERT INTO agendamentos VALUES (DEFAULT,'Maria','Cabeleireiro','2005-08-23 14:00:00','2005-08-23 15:00:00');
=> INSERT INTO agendamentos VALUES (DEFAULT,'Maria','Manicure','2005-08-23 15:00:00','2005-08-23 16:00:00');
=> INSERT INTO agendamentos VALUES (DEFAULT,'Maria','Médico','2005-08-23 14:30:00','2005-08-23 15:00:00');
ERRO:  impossível agendar - existe outro compromisso
=> UPDATE agendamentos SET data_inicio='2005-08-24' WHERE id=2;
ERRO:  impossível agendar - existe outro compromisso
=> SELECT * FROM agendamentos;

 id | nome  |    evento    |     data_inicio     |      data_fim
----+-------+--------------+---------------------+---------------------
  1 | Joana | Congresso    | 2005-08-23 00:00:00 | 2005-08-24 00:00:00
  2 | Joana | Viagem       | 2005-08-24 00:00:00 | 2005-08-26 00:00:00
  4 | Maria | Cabeleireiro | 2005-08-23 14:00:00 | 2005-08-23 15:00:00
  5 | Maria | Manicure     | 2005-08-23 15:00:00 | 2005-08-23 16:00:00
(4 linhas)

Notas

[1] Exemplo escrito pelo tradutor, não fazendo parte do manual original.
[2] Exemplo escrito pelo tradutor, não fazendo parte do manual original.
[3] Exemplo escrito pelo tradutor, não fazendo parte do manual original, baseado em exemplo da lista de discussão pgsql-sql.

 

Fonte: http://pgdocptbr.sourceforge.net/pg80/plpgsql-trigger.html#PLPGSQL-TRIGGER-EXAMPLE1

Sistemas de Banco de Dados 6ª Edição – Elmasri

 

sistemas-de-banco-de-dados-6

Download Sistemas de Banco de Dados 6ª Edição Elmasris

Referência acadêmica tanto teórica como prática, Sistemas de banco de dados apresenta os aspectos mais importantes não apenas dos sistemas, mas também das aplicações de banco de dados, além de diversas tecnologias relacionadas ao assunto.

Atualizada, a obra aborda:
– Conceitos fundamentais para projetar e usar os sistemas de banco de dados.
– Fundamentos de modelagem e de projeto de banco de dados.
– Linguagens e modelos fornecidos pelos sistemas de gerenciamento de banco de dados.
– Técnicas de implementação do sistema de banco de dados, com exemplos práticos.
Indicado para os cursos de ciências da computação, desenvolvimento de sistemas, sistemas de informação e engenharia da computação, este livro é também bibliografia básica para cursos de análise de redes, análise de sistemas e processamento de dados.

Sumário
Parte 1. Introdução aos bancos de dados.
1. Bancos de dados e usuários de banco de dados.
2. Conceitos e arquitetura do sistema de banco de dados.

Parte 2. Modelo de dados relacional e SQL.
3. O modelo de dados relacional e as restrições em bancos de dados relacionais.
4. SQL básica.
5. Mais SQL: Consultas complexas, triggers, views e modificação de esquema.
6. Álgebra e cálculo relacional.

Parte 3. Modelagem conceitual e projeto de banco de dados.
7. Modelagem de dados usando o modelo de Entidade-Relacionamento (ER).
8. O modelo de entidade-relacionamento estendido (EER).
9. Projeto de banco de dados relacional por mapeamento de ER e EER para relacional.
10. Metodologia prática de projeto de banco de dados e uso de diagramas UML.

Parte 4. Objeto, objeto-relacional e XML: conceitos, modelos, linguagens e padrões.
11. Bancos de dados de objeto e objeto-relacional.
12. XML: Extensible Markup Language.

Parte 5. Técnicas de programação de banco de dados.
13. Introdução às técnicas de programação SQL.
14. Programação de banco de dados Web usando PHP.

Parte 6. Teoria e normalização de projeto de banco de dados.
15. Fundamentos de dependências funcionais e normalização para bancos de dados relacionais.
16. Algoritmos de projeto de banco de dados relacional e demais dependências.

Parte 7. Estruturas de arquivo, indexação e hashing.
17. Armazenamento de disco, estruturas de arquivo básicas e hashing.
18. Estruturas de indexação para arquivos.

Parte 8. Processamento de consulta, otimização e ajuste de banco de dados; 19. Algoritmos para processamento e otimização de consulta.
20. Projeto físico e ajuste de banco de dados.

Parte 9. Processamento de transações, controle de concorrência e recuperação; 21. Introdução aos conceitos e teoria de processamento de transações.
22. Técnicas de controle de concorrência.
23. Técnicas de recuperação de banco de dados.

Parte 10. Tópicos adicionais de banco de dados: segurança e distribuição
24.Segurança de banco de dados
25. Bancos de dados distribuídos.

Parte 11. Modelos, sistemas e aplicações de bancos de dados avançados.
26. Modelos de dados avançados para aplicações avançadas.
27. Introdução à recuperação de informações e busca na Web.
28. Conceitos de data mining.
29. Visão geral de data warehousing e OLAP; Apêndices; Bibliografia; Índice remissivo.

Estilo: Curso
Tamanho: 131 mb
Ano de Lançamento: 2011
Idioma: Português – BR
Formato: Rar / Pdf
Hospedagem: Depositfiles / Freakshare / Bitshare

Depositfiles Download
Freakshare Download

Freakshare Bitshare

 

Fonte: http://www.sempredownloadfull.net/sistemas-de-banco-de-dados-6-edico-elmasri.html

Mais de 600GB de material para estudo em TI: Cursos, vídeo aulas, livros, apostilas de todas as variantes da Tecnologia da informação:

 60 GB em vídeos aulas de Java 16 DVDS – Senha = pr0mp7.torrent

Tamanho:153 KB
https://mega.co.nz/#!JRgjRLBT!nNg8JO31WWskPXH96xn1efu9mZqfgM%20jVZo24v6CAiLg

Livro Python para Pentester e Hackers

https://mega.nz/#!atQHACib!jff1wMGqCDMq1s8CjGWcbLDAcgol53DXvWYrwehV6tE

Curso de PHP

https://mega.nz/#F!WJVmQI4K!oosRA55mOWFMGR5qu9ssJg

Curso DreamWeaver

https://mega.nz/#F!AUhkiSpK!HlSxR0lexLecXjCowGG3AQ

Curso de Redes

https://mega.co.nz/#F!hZxDHLIZ!Pw8xfRmJirbL9Jvvip_iKw

Segurança em Redes

https://mega.co.nz/#F!cdQWjA5S!cX1sn4-sDpl1iWTH2b8-8w

Banco de Dados

https://mega.co.nz/#F!4R4ywJYb!-QLSTcDQ7GyhLeauC9HOlA

Curso de Eletrônica

https://mega.co.nz/#F!EYplFZRJ!Hd3g53t4SWuZ_ocF1fGLaw

Curso de JOOMLA completo

https://mega.co.nz/#F!kAohEChQ!C0XDspJDpw7tVxAgZizcaw

Curso de Linux

https://mega.co.nz/#F!YNI3kS5R!VsbYhu0sYIidqlKwwnH14Q

Curso Hardware

https://mega.co.nz/#F!EBAUCBDC!M2L3z07ypj05HtAQSeXkGA

Mega pacote de cursos Alura

https://mega.nz/#!FhxXwK7K!-Kzt-IDBs-rhVWC1_DgaULd7vSkZG7dWULCi_99kiOY

Curso Wireless Hacking

https://mega.co.nz/#F!AFJm2TLK!I6f4pZSX2ltoGBs0b1ztsQ

Curso WordPress

https://mega.co.nz/#F!cBIUBDTZ!Qtx1ahx-YeXUPdzIghwatA

Engenharia de software

https://mega.co.nz/#F!gUAmjbpD!BW7cylJHD_rcO1rryJ1sVQ

Hacking

https://mega.co.nz/#F!ER53kboI!H2RKhe5oMegv0APK2cQoFQ

https://mega.co.nz/#F!9QhWHbTI!oarMp7t3tzyY_yu08KHoEQ

Hardware

https://mega.co.nz/#F!oIZW3AzQ!LqcZV5fNLLmsxKfXAl6EtA

Introdução aos Sistemas Operacionais

https://mega.co.nz/#F!oZpVgbTR!MnX35yBQTexHPm4J8nIP2A

Linux

https://mega.co.nz/#F!YNg3xYhY!KQxsOV5rOF4ZhZm5LaiTwQ

Linux Essentials

https://mega.co.nz/#F!sBZhXDAI!NCWJslFznUXBaymdg_kmuA

Lógica de Programação Usando Python

https://mega.co.nz/#F!QAZ31aYY!JtCs0a5who41VK3jNsBa4Q

OYS pentest – Curso Teste de Invasão em Redes e Sistemas

https://mega.co.nz/#F!dVQkDTIQ!MLNKb5ZELHuIarpqHA0HxQ

Programação WEB

https://mega.co.nz/#F!AQQU3LYI!MIYAsxFZtfFTxpIqfHfIBg

Redes

https://mega.co.nz/#F!NMh1SZQC!5CKtEXGJy2JrIafPhvUuew

Segurança

https://mega.co.nz/#F!MN402QIb!_S4Jg-opFAFQVtl3lR4yJQ

Sistemas Operacionais

https://mega.co.nz/#F!JJAVwQAC!FB-jqhynRl_3CUuNzt7oMw

Software Livre

https://mega.co.nz/#F!EMgUkKxI!Wmv2SRC5bQNiLaZdbNBa9w

Teste de Invasão em Redes Sem Fio

https://mega.co.nz/#F!AUQwgIpa!NFW83TBeph3-7A7-LZqy4Q

Apostila HTML CSS

https://mega.co.nz/#!8FpXjbKB!11EMXK2wdfH3OC5BseR0PMbT9MYSGO%20tMtJrfiv5umEE

Artigo – wireshark

https://mega.co.nz/#!pc43VIpR!qy50wLU0yM7TsaeJtNu7RdaFw88BId%20VmDxCqd_E7ouQ

Curso Android Básico

https://mega.co.nz/#!pRAglZqB!hxJ9kG6dvUVukuT5tKQFMzf7_2jKdx%20V4SjM-IFzl2ns

Curso Banco de dados SQL e Modelagem

https://mega.co.nz/#!QYZSlCLB!FudRrApaiBV1oshkcHo2Rm38KeKSk1%20i_WN_0G84Q41M

Curso completo de Python

https://mega.co.nz/#!pEwA1IBL!REq1z_rnrc-ttqhEI-aGnxHcxc__0x%20gix5F98CwCkKI

Curso Linux

https://mega.co.nz/#!JIxVgYTZ!2aVR4SMtttlGoaEbTl7NGXa8n_VuhE%20K9XzjrlchSqss

Curso ipv6

https://mega.co.nz/#!xd50wAjA!sXt5m6tdZkZ_0ppNw7RKAw9gWgNYsM%20qVR12tr9FoTvM

Hackeando Mentes

https://mega.co.nz/#!kIBzmYAQ!VEYe_yI1Q6xBBsq_m5yvv_eIG3DH3n%20Xbp2AKkqLly88

Hacker inside

https://mega.co.nz/#!9ZgSyCCY!sBTV9Mva-fCYw5QKF0TkJfolcDsuox%20KqadjDqrjQTIM

Kevinmitnick a arte de enganar

https://mega.co.nz/#!INJglDRQ!H1KGBLTP9pEWtfZrp5VAbspu0Uo_Me%20_hkvtNh4B3Dm0

Banco de dados

https://mega.nz/#F!edRGmCIC!RS7TIjy7Krd4blcpLk2_hw

Computação Forense

https://mega.nz/#F!LVZgyKxT!0UEl9uphWKK5XN2iHo2ZTg

Curso inglês

https://mega.nz/#F!rMQW2CiD!nUNJvZ1nIeRHBMx33Vw8oQ

DeepWeb

https://mega.nz/#F!SdACSJSL!ck9c2S2FvjdI-L1ji-8JkQ

Edição de imagens

https://mega.nz/#F!vFIGFBpI!eRnEOpNziIS_mZx4IAIUsg

Engenharia de software

https://mega.nz/#F!ScwiGDhY!mFZz6mdkPMGVs5_6ZPOQeQ

Hacking

https://mega.nz/#F!vVoUhSrY!CCRwM3BC7U31BaAFZHl5SQ

Introdução a sistemas operacionais

https://mega.nz/#F!3doigIaC!pbDI81QC_3K2sD-Y08i1_g

Microsoft office

https://mega.nz/#F!KE4h2KQJ!ARugbDhPAqm9WWet6R606g

Normas para a apresentação de trabalhos acadêmicos

https://mega.nz/#F!2YpWWYrQ!njzFN2wdEjcL-n48ouCwvA

Programação WEB

https://mega.nz/#F!Lc4jwILR!YjIOrB8spSKjbwHmNvP8hQ

Redes

https://mega.nz/#F!vdIXgCRB!LpBx2GGbuthGu7FLHL5CsA

Segurança

https://mega.nz/#F!bFgHiBZB!XHC6bDoVYO3JEMJzf3pPmg

Sistemas operacionais

https://mega.nz/#F!fBxDULYK!g6jOZV3cjXwLYzuWhqCUnA

Software Livre

https://mega.nz/#F!HFABDDgQ!eH-cL2wdBu5y_fbY8yV78A

Teoria da computação

https://mega.nz/#F!rRwjTSiC!QOCkako5vL8sIarKYrZHPA

Vídeo aulas

https://mega.nz/#F!iJgkhDRI!LcvTfLA5rRUe1fwdqa1BUA

São tantos cursos que não dá nem pra mencionar aqui do que eles tratam, mas tem coisa muito boa lá, e grande parte deles são bem atuais, tratando sobre Web, Deepweb, Programação, Pentest, Hacker, Linux. Office, Idiomas, e muitos mais.

+BONUS DE MAIS 380GB em cursos ainda não catalogados:

https://mega.co.nz/#F!98cg2TSR!1q1OctEo3sOq25J11JAbOg

https://mega.nz/#F!V55BFDbD!3cBs3zMuk168LXfhfRmm-g
https://mega.nz/#F!wVsCjS7A!K7jrAMW6b7RX_AC6TT3msA!tZcAXCrK
https://mega.nz/#F!mIcTSRgJ!or6uaG2MJdh4jEKuHPYo_g!SAEDHBbB
https://mega.nz/#F!wVsCjS7A!K7jrAMW6b7RX_AC6TT3msA!ARcBlRhZ
https://mega.nz/#F!WJVmQI4K!oosRA55mOWFMGR5qu9ssJg
https://mega.nz/#F!wVsCjS7A!K7jrAMW6b7RX_AC6TT3msA
https://mega.nz/#F!WcBzgZhK!pJ1WsYkq8Evo1EhJi5oiJA
https://mega.nz/#F!mBB1BSrJ!RPojuKs757rJAIk-hVo4vw

https://mega.nz/#F!khhRAbwa!W5xZdG5Yat_y10Em_rmCng

https://mega.nz/#F!AE9GlDRT!mQQ1laUDxLw52-q1DljDsg

https://mega.nz/#F!CV9WFJYK!cjNuwXYg5wm6rc0YZTqaIg

https://mega.nz/#F!YF12iJ6B!933zM4O_EAxQWR16jC7I3Q

https://mega.nz/#F!ml8xGDYT!8LXsPyDMvQj8jWaM1k4rYQ

https://mega.nz/#F!tsNijbTR!Qj–39YrI4RsIwu6NTrfTQ

http://suporteninja.com/mais-de-300gb-de-cursos-em-ti-para-download-no-mega/

( Na verdade tem mais de 600GB de conteúdo)

Restaurando backup com pg_restore

Restaurando backup com pg_restore

pg_restore —  restaura um banco de dados do PostgreSQL a partir de um arquivo gerado pelo pg_dump

Synopsis

pg_restore [ -a ] [ -c ] [ -C ] [ -d nome_bd ] [ -f arquivo_de_saída ] [ -F formato ] [ -i índice ] [ -l ] [ -L arquivo_da_listagem ] [ -N | -o | -r ] [ -O ] [ -P nome_da_função ] [ -R ] [ -s ] [ -S ] [ -t tabela ] [ -T gatilho ] [ -v ] [ -x ] [ -X palavra_chave] [ -h hospedeiro ] [ -p porta ] [ -U nome_do_usuário ] [ -W ] [ arquivo_de_exportação ]

Descrição:

O pg_restore é um utilitário para restaurar um banco de dados do PostgreSQL a partir de um arquivo gerado pelo pg_dump em um dos formatos não-texto-puro. São executados os comandos necessários para criar novamente todos os tipos, funções, tabelas, índices, agregações e operadores definidos pelo usuário, assim como os dados das tabelas.

Os arquivos de exportação contêm informações para o pg_restore reconstruir o banco de dados, mas também permitem ao pg_restore selecionar o que deve ser restaurado, ou mesmo reordenar a restauraração dos itens. Os arquivos de exportação são projetados para serem portáveis entre arquiteturas.

O pg_restore pode operar de dois modos: Se um nome de banco de dados for especificado, o arquivo de exportação é restaurado diretamente no banco de dados. Senão, um script contendo os comandos SQL necessários para reconstruir o banco de dados é criado (e escrito em um arquivo ou na saída padrão), semelhante aos scripts criados pelo pg_dump no formato texto-puro. Algumas das opções que controlam a criação do script são, portanto, análogas às opções do pg_dump.

Obviamente, o pg_restore não pode restaurar informações que não estejam presentes no arquivo de exportação; por exemplo, se o arquivo de exportação foi gerado usando a opção “exportar dados como INSERT”, o pg_restore não poderá importar os dados usando o comando COPY.
Opções

O pg_restore aceita os seguintes argumentos de linha de comando (As formas longas das opções estão disponíveis em algumas plataformas apenas).

nome_do_arquivo_exportado
Especifica a localização do arquivo de exportação a ser restaurado. Se não for especificado, a entrada padrão é usada.

-a
–data-only

Importa somente os dados, não o esquema (definições dos dados).

-c
–clean

Exclui (drop) os objetos do banco de dados antes de criá-los..

-C
–create

Cria o banco de dados antes de restaurá-lo (Quando esta opção está presente, o banco de dados designado por -d é usado apenas para executar o comando CREATE DATABASE inicial. Todos os dados são restaurados no banco de dados cujo nome aparece no arquivo de exportação).

-d nome_bd
–dbname=nome_bd

Conecta ao nome_bd e restaura diretamente no banco de dados. Os objetos grandes somente podem ser restaurados usando uma conexão direta ao banco de dados.

-f arquivo_de_saída
–file=arquivo_de_saída

Especifica o nome do arquivo contendo o script gerado, ou a listagem quando for utilizado com a opção -l. Por padrão a saída padrão.

-F formato
–format=formato

Especifica o formato do arquivo de exportação. Não é necessário especificar o formato, porque o pg_restore reconhece o formato automaticamente. Se for especificado, poderá ser um dos seguintes:

t

O arquivo de exportação está no formato tar. Este formato de arquivo de exportação permite reordenar e/ou excluir elementos do esquema durante a importação. Também permite limitar quais dados são recarregados durante a importação.

c

O arquivo de exportação está no formato personalizado do pg_dump. Este é o formato mais flexível porque permite a reordenação da importação dos dados e dos elementos do esquema. Este formato também é comprimido por padrão.

-i índice
–index=índice

Restaura a definição do índice para o índice especificado apenas.

-l
–list

Lista o conteúdo do arquivo de exportação. A saída deste comando pode ser usada com a opção -L para restringir e reordenar os itens que são restaurados.

-L arquivo_da_listagem
–use-list=arquivo_da_listagem

Restaura apenas os elementos presentes no arquivo_da_listagem, e na ordem em que aparecem neste arquivo. As linhas podem ser movidas e, também, podem virar comentário colocando-se um ; no seu início.

-N
–orig-order

Restaura os itens na ordem original de exportação. Por padrão, o pg_dump irá exportar os itens em uma ordem conveniente para o pg_dump, e depois salvar o arquivo de exportação em uma ordem de OID modificada. Esta opção substitui a da ordem de OID.

-o
–oid-order

Restaura os itens na ordem de OID. Por padrão o pg_dump irá exportar exporta os itens em uma ordem conveniente para o pg_dump, e depois salvar o arquivo de exportação em uma ordem de OID modificada. Esta opção impõe a estrita ordem de OID.

-O
–no-owner

Impede qualquer tentativa de restaurar o dono original do objeto. O dono dos objetos será o usuário conectado ao banco de dados.

-P nome_da_função
–function=nome_da_função

Especifica o procedimento ou a função a ser restaurada.

-r
–rearrange

Restaura os itens na ordem modificada de OID. Por padrão, o pg_dump irá exportar os itens em uma ordem conveniente para o pg_dump, e depois salvar o arquivo de exportação em uma ordem de OID modificada. A maior parte dos objetos é restaurada na ordem de OID, mas alguns elementos (por exemplo, regras e índices) são restaurados no fim do processo sem respeitar os OIDs. Esta é a opção padrão.

-R
–no-reconnect

Durante a restauração do arquivo de exportação, o pg_restore usualmente necessita reconectar ao banco de dados vária vezes com nomes de usuário diferentes, para definir o dono correto dos objetos criados. Se isto não for desejável (por exemplo, se a intervenção manual for necessária para cada reconexão), esta opção proíbe o pg_restore requisitar reconexões (uma requisição de conexão em modo texto-puro, não conectado ao banco de dados, é feita emitindo o comando \connect do psql). Entretanto, esta opção é um instrumento bastante rudimentar, porque faz o pg_restore perder a informação sobre o dono, a menos que seja usada a opção -X use-set-session-authorization.

-s
–schema-only

Restaura somente o esquema (definições dos dados), sem os dados. Os valores das seqüências são substituídos.

-S nome_do_usuário
–superuser=nome_do_usuário

Especifica o nome do superusuário a ser usado para desativar os gatilhos e/ou definir o dono dos elementos do esquema. Por padrão, o pg_restore usa o nome do usuário corrente se este for um superusuário.

-t tabela
–table=tabela

Restaurar o esquema/dados da tabela apenas.

-T gatilho
–trigger=gatilho

Restaurar a definição do gatilho apenas.

-v
–verbose

Especifica o modo verboso.

-x
–no-privileges
–no-acl

Proíbe a restauração dos privilégios de acesso (comandos GRANT/REVOKE).

-X use-set-session-authorization
–use-set-session-authorization

Normalmente, se ao restaurar um arquivo de exportação for necessário trocar o usuário corrente do banco de dados (por exemplo, para definir o dono correto do objeto), uma nova conexão ao banco de dados deve ser aberta, o que poderá requerer intervenção manual (por exemplo, senhas). Se for usada a opção -X use-set-session-authorization, então o pg_restore vai usar o comando SET SESSION AUTHORIZATION. Embora produza o mesmo efeito, requer que o usuário que for fazer a importação do banco de dados a partir do arquivo de exportação gerado seja um superusuário. Esta opção substitui a opção -R.

O pg_restore também aceita os seguintes argumentos de linha de comando para os parâmetros de conexão:

-h hospedeiro
–host=hospedeiro

Especifica o nome da máquina onde o servidor está executando. Se o nome iniciar por uma barra (/), é considerado como sendo o diretório do soquete do domínio Unix.

-p porta
–port=porta

Especifica a porta Internet TCP/IP, ou o soquete do domínio local Unix, onde o servidor está aguardando as conexões. O padrão para o número da porta é 5432, ou o valor da variável de ambiente PGPORT (se estiver definida).

-U nome_do_usuário

Nome do usuário para se conectar.

-W

Força a solicitação da senha. Deve acontecer automaticamente se o servidor requerer autenticação por senha.


Exemplos:

$ pg_restore -d bd_novo bd.tar

http://www.postgresql.org/docs/9.2/static/app-pgrestore.html

[MySQL] – Habilitando acesso remoto ao servidor

Dica antiga que de vez em quando é necessário relembrar, deste modo irei deixar registrado aqui para não ter que ficar procurando no google sempre que precisar.

Executar todos os passos abaixo como root:
1 – Edite o arquivo:
/etc/mysql/my.cnf

2 – Altere a seguinte linha:
bind-address = 127.0.0.1
Deixando assim:
bind-address = 0.0.0.0
3 – Reinicie o Mysql
# /etc/init.d/mysql restart
4 – Vamos agora dar GRANT no usuário root, logue no mysql:
# mysql -u root -p
5 – Após se logar, digite o seguinte comando:
GRANT ALL ON *.* TO root@’%’ IDENTIFIED BY ‘sua_senha’;
Dessa forma você libera o acesso ao seu servidor Mysql vindo de qualquer máquina externa, caso queira liberar somente o acesso da sua máquina, é só verificar qual é seu IP e entrar com o comando:
GRANT ALL ON *.* TO root@’192.168.0.2′ IDENTIFIED BY ‘sua_senha’;
6. Após isso, basta dar uma reiniciada novamente no Mysql e realiazar a conexão remota.
# /etc/init.d/mysql restart
====================================================
Caso você queira desfazer o acesso remoto é bem simples também.
1 – Altere a seguinte linha:
bind-address = 0.0.0.0
Deixando assim:
bind-address = 127.0.0.1
2. Logue no Mysql:
# mysql -u root -p
3. Delete todos os privilégios remotos:
DELETE FROM mysql.user WHERE User = ‘root’ AND Host = ‘%’;
FLUSH PRIVILEGES;
4. Reinicie o Mysql e pronto, não estará mais acessível remotamente.
Fonte:
http://jf.eti.br/habilitando-acesso-remoto-ao-servidor-mysql/