# Aplicativos em PHP/Administração dos SGBDs/PostgreSQL

Aqui apenas passo o link para o livro

## PostgreSQL Prático

* PostgreSQL Prático
** Aplicativos em PHP/Trabalhando em PHP com/PostgreSQL
Com isso evitando repetições ou a reinvenção da roda.

## Tutorial sobre o phpPgAdmin

- Baixar de - http://phppgadmin.sourceforge.net/
- Copiar para o diretório web e descompactar no diretório "phppgadmin"
- Editar o arquivo conf/config.inc.php e alterar para dois servidores (um local e outro remoto) caso assim queira:
- Pronto, basta abrir http://localhost/phppgadmin

## Criando Chave Estrangeira Composta no phpPgAdmin e no PGAdmin

O exemplo é para uma chave com 4 campos, mas o procedimento é válido para qualquer chave composta.
Relacionar composicoes com precos.
Quero que ao digitar um preço em composições o SGBD verifique a integridade do mesmo em precos.
Temos uma tabela cuja chave primária é composta por 4 campos:
tabela, insumo_grupo, insumo, fornecedor e queremos relacionar com outra tabela que também contém os mesmos campos com os mesmos tipos de dados.
Como isso pode ter algum engano, seguem os passos.
Esquema das tabelas:

### phpPgAdmin

Observe que na tabela de destino (precos), de onde queremos trazer uma informação, a ordem da chave é "tabela, insumo_grupo, insumo e fornecedor". Já em coposicoes, estes campos estão em ordem diferente. Mas no momento de criar a chave estrangeira devemos adicionar na mesma ordem da precos. Veja abaixo.
- Abrir a tabela (composicoes) para a qual queremos inserir uma chave estrangeira no phpPgAdmin
- Clicar na aba Restrição
- Clicar em adicionar chave estrangeira
- Digitar um nome para a chave: composicoes_precos_fk
- Agora vem a dica: selecione nesta ordem à esquerda e clique na seta dupla após selecionar cada um:
- Em Tabela alvo selecione preco
- Clique em Adicionar (abaixo)
- Á esquerda selecione os quatro campos de precos (tabela, insumo_grupo, insumo e fornecedor) e clique na seta dupla para a direita.
- Clique em Adicionar abaixo.

### PGAdmin

- Abrir a tabela no PgAdmin (duplo clique no nome da tabela à esquerda)
- Clique em Constraints
- Selecione Fireign Key abaixo e clique em Add
- Digite um nome em name "composicoes_precos_fk"
- Em references selecione "precos"
- Clique na aba Columns
- Em Local column selecione 'tabela'
- Em Referecing selecione 'tabela' e clique em Add
- De forma semelhante adicione os 3 pares restantes: insumo_grupo - insumo_grupo, insumo - insumo e fornecedor - fornecedor.
Tive problema ao adicionar insumo, então adicionei fornecedor antes e depois insumo e foi bem.
- Então clique em OK, confira e OK novamente.

## PlPgSQL Tutorial

Esta é uma das linguagens de funções armazenadas com que trabalha o PostgreSQL. É a mais popular das linguagens no PostgreSQL.

### Delimitadores

O código de uma função plpgsql é especificado em CREATE FUNCTION como uma string literal delimitado por aspas.
1 Apóstrofo (corpo da função)
CREATE FUNCTION olamundo RETURNS integer AS '
' LANGUAGE plpgsql;
Inicia após AS e termina antes de LANGUAGE
2 Apóstrofos (mascar string literal no corpo da função)
a_output := Blah;
SELECT * FROM users WHERE f_name=foobar;
4 Apóstrofos (string constante no corpo da função)
a_output := a_output || AND name LIKE 'foobar' AND xyz
Mais detalhes na documentação oficial.

### Declaração de Variáveis

Sintaxe geral da declaração de variáveis:
nome [ CONSTANT ] tipo [ NOT NULL ] [ { DEFAULT | := } expressão ];
Exemplos:

### Declarado Funções

Obs.: O psql exibe as mensagens disparadas pelo RAISE.
Obs2.: BEGIN e END na plpgsql não agrupa transações, apenas grupos de comandos.

### Alias para Parâmetros de Funções

Sintaxe:
nome ALIAS FOR $n;
Exemplos:
Também podemos (mais claro) usar os nomes dos parâmetros explicitamente:

### Executando Funções

Usa-se o select para executar uma função, como se fosse uma view ou consulta comum.
select sum_n_product(5, 6);

### Tipos Polimórficos

Quanto tipos polimórficos (anyelement e anyarray) são usados para declarar de funções, um parâmetro especial ($0) é criado. Este tipo de dados é o atual retorno da função.
É inicializado como NULL e pode ser modificado pela função.
Exemplo
Função que trabalha com qualquer tipo de dados e que suporta o operador +:
Veja, que ao usar OUT não há necessidade de retorno (já está implícito).

### Copiando Tipos

variavel%TYPE
%TYPE fornece o tipo de dados de uma variável ou de um campo de tabela.
Para declarar uma variável com o mesmo tipo de dado de usuarios.id_usuario deve ser escrito:
id_usuario usuarios.id_usuario%TYPE;

### Tipos row

Pode armazenar um registro resultante de um SELECT ou de um FOR.
nome nome_da_tabela%ROWTYPE;
nome nome_do_tipo_composto;
Os campos podem ser acessados com nomevariavel.nomecampo;
Exemplo de uso:

### Tipo registro (record)

nome record;

### Renomeando Variáveis

RENAME nome_antigo TO novo_nome;

### Atribuições

identificador := expressão;

### Execução de Expressão ou Consulta sem Resultado

PERFORM create_mv('cs_session_page_requests_mv', my_query);
Não Fazer Nada
NULL;
Por exemplo, os dois fragmentos de código a seguir são equivalentes:

### Execução de Comandos Dinâmicos

EXECUTE cadeia_de_caracteres_do_comando;

### Estruturas de Controle

Return next
RETURN NEXT expressão;
Quando uma função PL/pgSQL é declarada como retornando SETOF algum_tipo, o procedimento a ser seguido é um pouco diferente. Neste caso, os itens individuais a serem retornados são especificados em comandos RETURN NEXT, e um comando RETURN final, sem nenhum argumento, é utilizado para indicar que a função chegou ao fim de sua execução. O comando RETURN NEXT pode ser utilizado tanto com tipos de dado escalares quanto compostos; no último caso toda uma “tabela” de resultados é retornada.
As funções que utilizam RETURN NEXT devem ser chamadas da seguinte maneira:
SELECT * FROM alguma_função;

### Declaração de Variáveis do tipo Cursor

Todos os acessos aos cursores na linguagem PL/pgSQL são feitos através de variáveis cursor, que sempre são do tipo de dado especial refcursor. Uma forma de criar uma variável cursor é simplesmente declará-la como sendo do tipo refcursor. Outra forma é utilizar a sintaxe de declaração de cursor, cuja forma geral é:
nome CURSOR [ ( argumentos ) ] FOR comando ;
Exemplos:

### Erros e Mensagens

RAISE nível 'formato' [, variável [, ...]];
Os níveis possíveis são DEBUG, LOG, INFO, NOTICE, WARNING, e EXCEPTION. O nível EXCEPTION causa um erro (que normalmente interrompe a transação corrente); os outros níveis apenas geram mensagens com diferentes níveis de prioridade. Se as mensagens de uma determinada prioridade são informadas ao cliente, escritas no log do servidor, ou as duas coisas, é controlado pelas variáveis de configuração log_min_messages e client_min_messages.

### Procedimentos de Gatilho (Trigger)

É 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

### 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.
Exemplo:
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
- 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.

### Gatilho para auditoria

Todas as operações na tabela emp serão registradas na tabela emp_audit

### Gatilho 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.
Este é um resumo da documentação oficial em inglês e em português do Brasil, que devem ser consultados para informações mais detalhadas em:
- http://www.postgresql.org/docs/8.2/interactive/index.html
- http://pgdocptbr.sourceforge.net/pg80/index.html