Você está na página 1de 130

POSTGRESQL Banco de dados SQL

ID: PG-510 Evolutiontech Training Services


www.evolutiontech.com.br COURSEWARE

Banco de Dados SQL


PostgreSQL

Evolutiontech Treinamento e Desenvolvimento Pgina |2


POSTGRESQL Banco de dados SQL

O que o PostgreSQL? 5

Iniciao do PostgreSQL 7

A linguagem SQL 11
Introduo ............................................................................................................................. 11
Conceitos ............................................................................................................................... 11
Criao e Excluso de tabelas .................................................................................................11
Insero de linhas em tabelas ................................................................................................ 12
Consultar tabelas ................................................................................................................... 13
Usando Expresses Matemticas (Campos Calculados) .......................................................... 14
Usando JOINS (Join, Left Join, right join e full join) .................................................................17
Apelidos ou abreviaes de campos ....................................................................................... 18
Funes de agregao ............................................................................................................19
Usando SubQueries ................................................................................................................19
Usando Funes de Agregao e Clasula GROUP BY ............................................................. 20
Uando o operador LIKE ..........................................................................................................21

Funcionalidades avanadas 24
Trabalhando com VIEWs ........................................................................................................24
Transaes (Begin, Rollback, Commit e Savepoints) ............................................................... 26
Unificando Resultados na consulta (UNION)...........................................................................31
Herana .................................................................................................................................32

Sintaxe da linguagem SQL 34


Estrutura lxica ...................................................................................................................... 34
Subconsultas escalares ...........................................................................................................42

Definio de dados 43
Noes bsicas de tabela .......................................................................................................43
Restries (CONSTRAINTS) .....................................................................................................44
Valor padro (constraint DEFAULT) ........................................................................................ 45
Restries de verificao (constraint CHECK)..........................................................................46
Restries de no-nulo (constraint NOT NULL) .......................................................................48
Restries de unicidade (constraint NOT NULL) ......................................................................49
Chaves primrias (constraint PRIMARY KEY) ...........................................................................50
Chaves Compostas (constraint PRIMARY KEY em dois ou mais campos) .................................50
Chaves Estrangeiras (constraint PRIMARY KEY) ......................................................................51

Evolutiontech Treinamento e Desenvolvimento Pgina |3


POSTGRESQL Banco de dados SQL

Quando usar Chave Primria e Chave Estrangeira na mesma coluna ......................................52


Modificao de tabelas ..........................................................................................................56

Manipulao de dados 66
Insero de dados (INSERT) ....................................................................................................66
Atualizao de dados (UPDATE) ............................................................................................. 67
Excluso de dados (DELETE) ...................................................................................................68

Consultas (SELECT) 70
A clusula FROM .................................................................................................................... 71
Juno de tabelas (JOIN) ........................................................................................................71
A clusula WHERE .................................................................................................................. 76
Utilizao de HAVING sem GROUP BY no SELECT ...................................................................80
Utilizao da expresso CASE para agrupar valores ................................................................ 82
Select DISTINCT ...................................................................................................................... 85
Ordenao de linhas ..............................................................................................................88

Tipos de dado 91

Funes e Operadores 111


Operadores lgicos .............................................................................................................. 111
Operadores de comparao ................................................................................................. 112

Converso de tipo 124


Viso geral sobre converso ................................................................................................. 124
Funes ................................................................................................................................ 124

ndices 127

Evolutiontech Treinamento e Desenvolvimento Pgina |4


POSTGRESQL Banco de dados SQL

O que o PostgreSQL?
O PostgreSQL um sistema gerenciador de banco de dados objeto-relacional (SGBDOR), 1 2
baseado no POSTGRES Verso 4.2 (http://s2k-ftp.CS.Berkeley.EDU:8000/postgres/postgres.html)
desenvolvido pelo Departamento de Cincia da Computao da Universidade da Califrnia em
Berkeley. O POSTGRES foi pioneiro em vrios conceitos que somente se tornaram disponveis
muito mais tarde em alguns sistemas de banco de dados comerciais.
O PostgreSQL um descendente de cdigo fonte aberto deste cdigo original de Berkeley.
suportada grande parte do padro SQL:2003, alm de serem oferecidas muitas funcionalidades
modernas, como:
comandos complexos
chaves estrangeiras
gatilhos
vises
integridade transacional
controle de simultaneidade multiverso
Alm disso, o PostgreSQL pode ser estendido pelo usurio de muitas maneiras como, por
exemplo, adicionando novos
tipos de dado
funes
operadores
funes de agregao
mtodos de ndice
linguagens procedurais
Devido sua licena liberal, o PostgreSQL pode ser utilizado, modificado e distribudo por
qualquer pessoa para qualquer finalidade, seja privada, comercial ou acadmica, livre de
encargos.

Histria do PostgreSQL
O sistema gerenciador de banco de dados objeto-relacional hoje conhecido por PostgreSQL,
derivado do pacote POSTGRES escrito na Universidade da Califrnia em Berkeley. Com mais de
uma dcada de desenvolvimento por trs, o PostgreSQL atualmente o mais avanado banco de
dados de cdigo aberto disponvel em qualquer lugar.

O projeto POSTGRES de Berkeley


O projeto POSTGRES, liderado pelo Professor Michael Stonebraker, foi patrocinado pela DARPA
(Defense Advanced Research Projects Agency), pelo ARO (Army Research Office), pela NSF
(National Science Foundation) e pela ESL, Inc. A implementao do POSTGRES comeou em
1986. Os conceitos iniciais para o sistema foram apresentados em The design of POSTGRES, e a
definio do modelo de dados inicial foi descrita em The POSTGRES data model. O projeto do
sistema de regras desta poca foi descrito em The design of the POSTGRES rules system. Os

Evolutiontech Treinamento e Desenvolvimento Pgina |5


POSTGRESQL Banco de dados SQL

fundamentos lgicos e a arquitetura do gerenciador de armazenamento foram detalhados em The


design of the POSTGRES storage system.

O Postgres95
Em 1994, Andrew Yu e Jolly Chen adicionaram um interpretador da linguagem SQL ao POSTGRES.
Sob um novo nome, o Postgres95 foi em seguida liberado na Web para encontrar seu prprio
caminho no mundo, como descendente de cdigo aberto do cdigo original do POSTGRES de
Berkeley.
Alm da correo de erros, as principais melhorias foram as seguintes:
A linguagem de comandos PostQUEL foi substituda pela linguagem SQL (implementada no
servidor). No foram permitidas subconsultas at o PostgreSQL (veja abaixo), mas estas podiam
ser simuladas no Postgres95 por meio de funes SQL definidas pelo usurio. As funes de
agregao foram reimplementadas. Tambm foi adicionado suporte a clusula GROUP BY nas
consultas.
Foi fornecido um novo programa para executar comandos SQL interativos, o psql, utilizando
o Readline do GNU, que substituiu com vantagens o programa monitor antigo.
Uma nova biblioteca cliente, a libpgtcl, dava suporte a clientes baseados no Tcl. O
interpretador de comandos pgtclsh fornecia novos comandos Tcl para interfacear programas
Tcl com o servidor Postgres95.
A interface para objetos grandes foi revisada. A inverso de objetos grandes 3 era o nico
mecanismo para armazenar objetos grandes (O sistema de arquivos inverso foi removido).
O sistema de regras no nvel de instncia foi removido. As regras ainda eram disponveis
como regras de reescrita.
Um breve tutorial introduzindo as funcionalidades regulares da linguagem SQL, assim como
as do Postgres95, foi distribudo junto com o cdigo fonte.
O utilitrio make do GNU (em vez do make do BSD) foi utilizado para a gerao. Alm disso,
o Postgres95 podia ser compilado com o GCC sem correes (o alinhamento de dados para a
preciso dupla foi corrigido).

O PostgreSQL
Em 1996 ficou claro que o nome Postgres95 no resistiria ao teste do tempo. Foi escolhido um
novo nome, PostgreSQL, para refletir o relacionamento entre o POSTGRES original e as verses
mais recentes com capacidade SQL. Ao mesmo tempo, foi mudado o nmero da verso para
comear em 6.0, colocando a numerao de volta seqncia original comeada pelo projeto
POSTGRES de Berkeley.
Com o PostgreSQL a nfase foi reorientada para o aumento das funcionalidades e recursos,
embora o trabalho continuasse em todas as reas.

Evolutiontech Treinamento e Desenvolvimento Pgina |6


POSTGRESQL Banco de dados SQL

Iniciao do PostgreSQL

Instalao
Para que se possa usar o PostgreSQL necessrio instal-lo, obviamente. possvel que o
PostgreSQL j esteja instalado na mquina, seja porque est includo na distribuio do sistema
operacional, ou porque o administrador do sistema fez a instalao. Se este for o caso, devem ser
obtidas informaes na documentao do sistema operacional, ou com o administrador do
sistema, sobre como acessar o PostgreSQL.
No havendo certeza se o PostgreSQL est disponvel, ou se pode ser utilizado para seus
experimentos, ento voc mesmo poder fazer a instalao. Proceder desta maneira no difcil,
podendo ser um bom exerccio. O PostgreSQL pode ser instalado por qualquer usurio sem
privilgios, porque no necessrio nenhum acesso de superusurio (root).
Se for instalar o PostgreSQL por si prprio, ento leia o Captulo 14 para conhecer as instrues de
instalao, e depois retorne para este guia quando a instalao estiver terminada.

Criao de banco de dados


O primeiro teste para verificar se possvel acessar o servidor de banco de dados tentar criar
um banco de dados. Um servidor PostgreSQL pode gerenciar muitos bancos de dados.
Normalmente utilizado um banco de dados em separado para cada projeto ou para cada
usurio.
Possivelmente, o administrador j criou um banco de dados para seu uso. Ele deve ter dito qual
o nome do seu banco de dados. Neste caso esta etapa pode ser omitida, indo-se direto para a
prxima seo.
Para criar um novo banco de dados, chamado meu_bd neste exemplo, deve ser utilizado o
comando:
$ createdb meu_bd

Que deve produzir a seguinte resposta:


CREATE DATABASE

O PostgreSQL permite a criao de qualquer nmero de bancos de dados em uma instalao. Os


nomes dos bancos de dados devem ter o primeiro caractere alfabtico, sendo limitados a um
comprimento de 63 caracteres. Uma escolha conveniente criar o banco de dados com o mesmo
nome do usurio corrente. Muitas ferramentas assumem este nome de banco de dados como
sendo o nome padro, evitando a necessidade de digit-lo. Para criar este banco de dados deve
ser digitado simplesmente:
$ createdb meu_bd

Evolutiontech Treinamento e Desenvolvimento Pgina |7


POSTGRESQL Banco de dados SQL

Caso no deseje mais utilizar o seu banco de dados, pode remov-lo. Por exemplo, se voc for o
dono (criador) do banco de dados meu_bd, poder remov-lo utilizando o seguinte comando:

$ dropdb meu_bd

Para este comando o nome da conta no utilizado como nome padro do banco de dados: o
nome sempre deve ser especificado. Esta ao remove fisicamente todos os arquivos associados
ao banco de dados no podendo ser desfeita, portanto esta operao somente deve ser feita aps
um longo perodo de reflexo.
Podem ser encontradas informaes adicionais sobre os comandos createdb e dropdb em
createdb e dropdb, respectivamente.

Acesso a banco de dados


Aps o banco de dados ter sido criado, este pode ser acessado pela:
Execuo do programa de terminal interativo do PostgreSQL chamado psql, que permite
entrar, editar e executar comandos SQL interativamente.
Utilizao de uma ferramenta cliente grfica existente como o PgAccess, ou de um pacote
de automao de escritrios com suporte a ODBC.
Criao de aplicativos personalizados.
Voc provavelmente vai desejar ativar o psql para executar os exemplos deste tutorial. O psql
pode ser ativado para usar o banco de dados meu_bd digitando o comando:

$ psql meu_bd

Se o nome do banco de dados for omitido, ento ser usado o nome padro igual ao nome da
conta do usurio. Isto j foi visto na seo anterior.
O psql sada o usurio com a seguinte mensagem:

Welcome to psql 9.5.0, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms


\h for help with SQL commands
\? for help on internal slash commands
\g or terminate with semicolon to execute query
\q to quit

meu_bd=>

Evolutiontech Treinamento e Desenvolvimento Pgina |8


POSTGRESQL Banco de dados SQL

ou

meu_bd=#

Significando que o usurio um superusurio do banco de dados, acontecendo geralmente


quando se instala o PostgreSQL por si prprio. Ser um superusurio significa no estar sujeito a
controles de acesso. Para as finalidades deste tutorial isto no tem importncia.
Caso aconteam problemas ao inicializar o psql, ento retorne seo anterior. Os diagnsticos
do psql e do createdb so semelhantes, e se um funcionou o outro deve funcionar tambm.
A ltima linha exibida pelo psql o prompt, indicando que o psql est lhe aguardando, e que
voc pode digitar comandos SQL dentro do espao de trabalho mantido pelo psql. Tente estes
comandos:

meu_bd=> SELECT version();

version
----------------------------------------------------------------
PostgreSQL 9.5.0 on i586-pc-linux-gnu, compiled by GCC 2.96
(1 linha)

meu_bd=> SELECT current_date;

date
------------
2005-05-17
(1 linha)

Evolutiontech Treinamento e Desenvolvimento Pgina |9


POSTGRESQL Banco de dados SQL

meu_bd=> SELECT 2 + 2;

?column?
----------
4
(1 linha)

O programa psql possui vrios comandos internos que no so comandos SQL. Eles comeam
pelo caractere de contrabarra, \. Alguns destes comandos so mostrados na mensagem de boas
vindas. Por exemplo, pode ser obtida ajuda sobre a sintaxe de vrios comandos SQL do
PostgreSQL digitando:

meu_bd=> \h

Para sair do psql digite


meu_bd=> \q

o psql terminar retornando para o interpretador de comandos (para conhecer outros comandos
internos digite \? no prompt do psql). Todas as funcionalidades do psql esto documentadas em
psql. Se o PostgreSQL tiver sido instalado corretamente, tambm pode-se digitar man psql na
linha de comando do sistema operacional para ver a documentao. Neste tutorial no
utilizaremos estas funcionalidades explicitamente, mas use por si prprio quando julgar
adequado.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 10


POSTGRESQL Banco de dados SQL

A linguagem SQL

Introduo
Este captulo fornece uma viso geral sobre como utilizar a linguagem SQL para realizar operaes
simples. O propsito deste tutorial apenas fazer uma introduo e, de forma alguma, ser um
tutorial completo sobre a linguagem SQL. Existem muitos livros escritos sobre a linguagem SQL,
incluindo Understanding the New SQL e A Guide to the SQL Standard. preciso estar ciente que
algumas funcionalidades da linguagem SQL do PostgreSQL so extenses ao padro.

Conceitos
O PostgreSQL um sistema de gerenciamento de banco de dados relacional (SGBDR). Isto significa
que um sistema para gerenciar dados armazenados em relaes. Relao , essencialmente, um
termo matemtico para tabela. A noo de armazenar dados em tabelas to trivial hoje em dia
que pode parecer totalmente bvio, mas existem vrias outras formas de organizar bancos de
dados. Arquivos e diretrios em sistemas operacionais tipo Unix so um exemplo de banco de
dados hierrquico. Um desenvolvimento mais moderno so os bancos de dados orientados a
objeto.
Cada tabela uma coleo nomeada de linhas. Todas as linhas de uma determinada tabela
possuem o mesmo conjunto de colunas nomeadas, e cada coluna de um tipo de dado
especfico. Enquanto as colunas possuem uma ordem fixa nas linhas, importante lembrar que o
SQL no garante a ordem das linhas dentro de uma tabela (embora as linhas possam ser
explicitamente ordenadas para a exibio).
As tabelas so agrupadas em bancos de dados, e uma coleo de bancos de dados gerenciados
por uma nica instncia do servidor PostgreSQL forma um agrupamento de bancos de dados.

Criao e Excluso de tabelas


Pode-se criar uma tabela especificando o seu nome juntamente com os nomes das colunas e seus
tipos de dado:
CREATE TABLE clima (
cidade varchar(80),
temp_min int, -- temperatura mnima
temp_max int, -- temperatura mxima
data date );

Evolutiontech Treinamento e Desenvolvimento P g i n a | 11


POSTGRESQL Banco de dados SQL

Este comando pode ser digitado no psql com quebras de linha. O psql reconhece que o comando
s termina quando encontrado o ponto-e-vrgula.
Espaos em branco (ou seja, espaos, tabulaes e novas linhas) podem ser utilizados livremente
nos comandos SQL. Isto significa que o comando pode ser digitado com um alinhamento diferente
do mostrado acima, ou mesmo tudo em uma nica linha. Dois hfens (--) iniciam um
comentrio; tudo que vem depois ignorado at o final da linha. A linguagem SQL no diferencia
letras maisculas e minsculas nas palavras chave e nos identificadores, a no ser que os
identificadores sejam colocados entre aspas ( ") para preservar letras maisculas e minsculas, o
que no foi feito acima.
No comando, varchar(80) especifica um tipo de dado que pode armazenar cadeias de caracteres
arbitrrias com comprimento at 80 caracteres; int o tipo inteiro normal; real o tipo para
armazenar nmeros de ponto flutuante de preciso simples; date o tipo para armazenar data e
hora (a coluna do tipo date pode se chamar date, o que tanto pode ser conveniente quanto pode
causar confuso).
O PostgreSQL suporta os tipos SQL padro int, smallint, real, double precision, char(N), varchar(N),
date, time, timestamp e interval, assim como outros tipos de utilidade geral, e um conjunto
abrangente de tipos geomtricos. O PostgreSQL pode ser personalizado com um nmero
arbitrrio de tipos definidos pelo usurio. Como conseqncia, sintaticamente os nomes dos tipos
no so palavras chave, exceto onde for requerido para suportar casos especiais do padro SQL.
Para terminar deve ser mencionado que, quando a tabela no mais necessria, ou se deseja
recri-la de uma forma diferente, possvel remov-la por meio do comando:

DROP TABLE nome_da_tabela;

Insero de linhas em tabelas


utilizado o comando INSERT para inserir linhas nas tabelas:

INSERT INTO clima


VALUES ('So Francisco', 46, 50, '1994-11-27');

Repare que todos os tipos de dado possuem formato de entrada de dados bastante bvios. As
constantes, que no so apenas valores numricos, geralmente devem estar entre apstrofos ( '),
como no exemplo acima. O tipo date , na verdade, muito flexvel em relao aos dados que
aceita, mas para este tutorial vamos nos fixar no formato sem ambigidade mostrado acima.
Se for desejado, pode-se declarar as colunas em uma ordem diferente, e pode-se, tambm, omitir
algumas colunas. Por exemplo, se a precipitao no for conhecida:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 12


POSTGRESQL Banco de dados SQL

INSERT INTO clima (data, cidade, temp_max, temp_min)


VALUES ('1994-11-29', 'Hayward', 54, 37);

Muitos desenvolvedores consideram declarar explicitamente as colunas um estilo melhor que


confiar na ordem implcita.
Por favor, entre todos os comando mostrados acima para ter alguns dados para trabalhar nas
prximas sees.
Tambm pode ser utilizado o comando COPY para carregar uma grande quantidade de dados a
partir de arquivos texto puro. Geralmente mais rpido, porque o comando COPY otimizado
para esta finalidade, embora possua menos flexibilidade que o comando INSERT. Para servir de
exemplo:

COPY clima FROM '/home/user/clima.txt';

O arquivo contendo os dados deve poder ser acessado pelo servidor e no pelo cliente, porque o
servidor l o arquivo diretamente. Podem ser obtidas mais informaes sobre o comando COPY
em COPY.

Consultar tabelas
Para trazer os dados de uma tabela, a tabela deve ser consultada. Para esta finalidade utilizado
o comando SELECT do SQL. Este comando dividido em lista de seleo (a parte que especifica as
colunas a serem trazidas), lista de tabelas (a parte que especifica as tabelas de onde os dados vo
ser trazidos), e uma qualificao opcional (a parte onde so especificadas as restries). Por
exemplo, para trazer todas as linhas da tabela clima digite:

SELECT * FROM clima;

uma forma abreviada de todas as colunas.

Seriam obtidos os mesmos resultados usando:

SELECT cidade, temp_min, temp_max, prcp, data FROM clima;


A sada deve ser:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 13


POSTGRESQL Banco de dados SQL

cidade | temp_min | temp_max | data


-----------------+----------+----------+------------
So Francisco | 46 | 50 | 1994-11-27
So Francisco | 43 | 57 | 1994-11-29
Hayward | 37 | 54 | 1994-11-29
(3 linhas)

Usando Expresses Matemticas (Campos


Calculados)

Na lista de seleo podem ser especificadas expresses, e no apenas referncias a colunas. Por

exemplo, pode ser escrito:

SELECT cidade, (temp_max+temp_min)/2


AS temp_media, data FROM clima;

Devendo produzir:
cidade | temp_media | data
-----------------+------------+------------
So Francisco | 48 | 1994-11-27
So Francisco | 50 | 1994-11-29
Hayward | 45 | 1994-11-29 (3 linhas)

Perceba que a clusula AS foi utilizada para mudar o nome da coluna de sada (a clusula AS
opcional).

Evolutiontech Treinamento e Desenvolvimento P g i n a | 14


POSTGRESQL Banco de dados SQL

Usando a Clasula Where para filtrar os resultados


A consulta pode ser qualificada, adicionando a clusula WHERE para especificar as linhas
desejadas. A clusula WHERE contm expresses booleanas (valor verdade), e somente so
retornadas as linhas para as quais o valor da expresso booleana for verdade. So permitidos os
operadores booleanos usuais (AND, OR e NOT) na qualificao. Por exemplo, o comando abaixo
retorna os registros do clima de So Francisco nos dias de chuva:

SELECT * FROM clima WHERE


cidade = 'So Francisco' AND prcp > 0.0;

Resultado:

cidade | temp_min | temp_max | data


-----------------+----------+----------+------------
So Francisco | 46 | 50 | 1994-11-27
(1 linha)

Pode ser solicitado que os resultados da consulta sejam retornados em


uma determinada ordem:

SELECT * FROM clima ORDER BY cidade;

cidade | temp_min | temp_max | data


-----------------+----------+----------+------------
Hayward | 37 | 54 | 1994-11-29
So Francisco | 43 | 57 | 1994-11-29
So Francisco | 46 | 50 | 1994-11-27

Neste exemplo a ordem de classificao no est totalmente especificada e, portanto, as linhas de


So Francisco podem retornar em qualquer ordem. Mas sempre seriam obtidos os resultados
mostrados acima se fosse executado:

SELECT * FROM clima ORDER BY cidade, temp_min;

Pode ser solicitado que as linhas duplicadas sejam removidas do resultado


da consulta:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 15


POSTGRESQL Banco de dados SQL

SELECT DISTINCT cidade FROM clima;

cidade
---------------
Hayward
So Francisco (2 linhas)

Novamente, neste exemplo a ordem das linhas pode variar. Pode-se garantir resultados
consistentes utilizando DISTINCT e ORDER BY juntos:

SELECT DISTINCT cidade FROM clima ORDER BY cidade;

Junes entre tabelas

At agora as consultas somente acessaram uma tabela de cada vez. As consultas podem acessar
vrias tabelas de uma vez, ou acessar a mesma tabela de uma maneira que vrias linhas da tabela
sejam processadas ao mesmo tempo. A consulta que acessa vrias linhas da mesma tabela, ou de
tabelas diferentes, de uma vez, chamada de consulta de juno. Como exemplo, suponha que se
queira listar todas as linhas de clima junto com a localizao da cidade associada. Para se fazer
isto, necessrio comparar a coluna cidade de cada linha da tabela clima com a coluna nome de
todas as linhas da tabela cidades, e selecionar os pares de linha onde estes valores so
correspondentes.

Esta operao pode ser efetuada por meio da seguinte consulta:

SELECT * FROM clima, cidades WHERE cidade = nome;

cidade | temp_min | temp_max | data | nome | localizacao


----------------+----------+----------+------------+---------------+-------------
So Francisco | 46 | 50 | 1994-11-27 | So Francisco | (-194,53)
So Francisco | 43 | 57 | 1994-11-29 | So Francisco | (-194,53)
(2 linhas)

Duas coisas devem ser observadas no resultado produzido:


No existe nenhuma linha para a cidade Hayward. Isto acontece porque no existe entrada
correspondente na tabela cidades para Hayward, e a juno ignora as linhas da tabela clima sem
correspondncia. Veremos em breve como isto pode ser mudado.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 16


POSTGRESQL Banco de dados SQL

Existem duas colunas contendo o nome da cidade, o que est correto porque a lista de
colunas das tabelas clima e cidades esto concatenadas. Na prtica isto no desejado, sendo
prefervel, portanto, escrever a lista das colunas de sada explicitamente em vez de utilizar o *:

SELECT cidade, temp_min, temp_max, data,


localizacao
FROM clima, cidades WHERE cidade = nome;

Como todas as colunas possuem nomes diferentes, o analisador encontra automaticamente a


tabela que a coluna pertence, mas um bom estilo qualificar completamente os nomes das
colunas nas consultas de juno:

SELECT clima.cidade, clima.temp_min,


clima.temp_max,
clima.data, cidades.localizacao
FROM clima, cidades
WHERE cidades.nome = clima.cidade;

Usando JOINS (Join, Left Join, right join e full join)


As consultas de juno do tipo visto at agora tambm poderiam ser
escritas da seguinte forma alternativa:

SELECT * FROM clima INNER JOIN cidades


ON (clima.cidade = cidades.nome);

A utilizao desta sintaxe no to comum quanto a usada acima, mas mostrada para ajudar a
entender os prximos tpicos.
Agora vamos descobrir como se faz para obter as linhas de Hayward. Desejamos o seguinte: que
a consulta varra a tabela clima e, para cada uma de suas linhas, encontre a linha correspondente
na tabela cidades. Se no for encontrada nenhuma linha correspondente, desejamos que sejam
colocados valores vazios nas colunas da tabela cidades. Este tipo de consulta chamada de
juno externa (outer join). As consultas vistas at agora so junes internas (inner join). O
comando ento fica assim:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 17


POSTGRESQL Banco de dados SQL

SELECT * FROM clima LEFT OUTER JOIN cidades


ON (clima.cidade = cidades.nome);

cidade | temp_min | temp_max | data | nome | localizao


-----------------+----------+----------+------------+---------------+------------
Hayward | 37 | 54 | 1994-11-29 | |
So Francisco | 46 | 50 | 1994-11-27 | So Francisco | (-194,53)
So Francisco | 43 | 57 | 1994-11-29 | So Francisco | (-194,53) (3
linhas)

Esta consulta chamada de juno externa esquerda (left outer join), porque a tabela mencionada
esquerda do operador de juno ter cada uma de suas linhas aparecendo na sada pelo menos
uma vez, enquanto a tabela direita ter somente as linhas correspondendo a alguma linha da
tabela esquerda aparecendo na sada. Ao listar uma linha da tabela esquerda, para a qual no
existe nenhuma linha correspondente na tabela direita, so colocados valores vazios (null) nas
colunas da tabela direita.
Tambm possvel fazer a juno da tabela consigo mesma. Isto chamado de autojuno (self
join). Como exemplo, suponha que desejamos descobrir todas as linhas de clima que esto no
intervalo de temperatura de outros registros de clima. Para isso necessrio comparar as colunas
temp_min e temp_max de cada registro de clima com as colunas temp_min e temp_max de todos os
outros registros da tabela clima, o que pode ser feito utilizando a seguinte consulta:

Apelidos ou abreviaes de campos

SELECT C1.cidade, C1.temp_min AS menor, C1.temp_max AS


maior, C2.cidade, C2.temp_min AS menor, C2.temp_max AS
maior
FROM clima C1, clima C2
WHERE C1.temp_min < C2.temp_min AND C1.temp_max >
C2.temp_max;

cidade | menor | maior | cidade | menor | maior


-----------------+-------+-------+---------------+-------+-------
So Francisco | 43 | 57 | So Francisco | 46 | 50
Hayward | 37 | 54 | So Francisco | 46 | 50
(2 linhas)

Evolutiontech Treinamento e Desenvolvimento P g i n a | 18


POSTGRESQL Banco de dados SQL

A tabela clima teve seu nome mudado para C1 e C2, para permitir distinguir o lado esquerdo do
lado direito da juno. Estes tipos de aliases tambm podem ser utilizados em outras consultas
para reduzir a digitao como, por exemplo:

SELECT * FROM clima w, cidades c


WHERE w.cidade = c.nome;

Ser vista esta forma de abreviar com bastante freqncia.

Funes de agregao
Como a maioria dos produtos de banco de dados relacional, o PostgreSQL suporta funes de
agregao. Uma funo de agregao computa um nico resultado para vrias linhas de entrada.
Por exemplo, existem funes de agregao para contar ( count), somar (sum), calcular a mdia
(avg), o valor mximo (max) e o valor mnimo (min) para um conjunto de linhas.
Para servir de exemplo, possvel encontrar a maior temperatura mnima ocorrida em qualquer
lugar usando

SELECT max(temp_min) FROM clima;

max
-----
46
(1 linha)

Usando SubQueries
Se for desejado saber a cidade (ou cidades) onde esta temperatura ocorreu pode-se tentar:

SELECT cidade FROM clima WHERE temp_min = max(temp_min);


ERRADO !!!!!

No vai funcionar, porque a funo de agregao max no pode ser usada na clusula WHERE (Esta
restrio existe porque a clusula WHERE determina as linhas que vo passar para o estgio de
agregao e, portanto, precisa ser avaliada antes das funes de agregao serem computadas).
Entretanto, como geralmente o caso, a consulta pode ser reformulada para obter o resultado
pretendido, o que ser feito por meio de uma subconsulta:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 19


POSTGRESQL Banco de dados SQL

SELECT cidade FROM clima


WHERE temp_min = (SELECT max(temp_min)
FROM clima);

cidade
---------------
So Francisco
(1 linha)

Isto est correto porque a subconsulta uma ao independente, que calcula sua agregao em
separado do que est acontecendo na consulta externa.

Usando Funes de Agregao e Clasula GROUP BY


As agregaes tambm so muito teis em combinao com a clusula GROUP BY. Por exemplo,
pode ser obtida a maior temperatura mnima observada em cada cidade usando produzindo uma
linha de sada para cada cidade.

SELECT cidade, max(temp_min)


FROM clima
GROUP BY cidade;

cidade | max
-----------------+-----
Hayward | 37
So Francisco | 46 (2 linhas)

Cada resultado da agregao computado sobre as linhas da tabela correspondendo a uma


cidade. As linhas agrupadas podem ser filtradas utilizando a clusula HAVING que mostra os
mesmos resultados, mas apenas para as cidades que possuem todos os valores de temp_min
abaixo de 40.

SELECT cidade, max(temp_min)


FROM clima
GROUP BY cidade
HAVING max(temp_min) < 40;

Evolutiontech Treinamento e Desenvolvimento P g i n a | 20


POSTGRESQL Banco de dados SQL

cidade | max
-----------+-----
Hayward | 37 (1 linha)

Para concluir, se desejarmos somente as cidades com nome comeando


pela letra S podemos escrever:

SELECT cidade, max(temp_min) FROM clima


WHERE cidade LIKE 'S%'
GROUP BY cidade
HAVING max(temp_min) < 40;

Uando o operador LIKE


importante compreender a interao entre as agregaes e as clusulas WHERE e HAVING do SQL.
A diferena fundamental entre WHERE e HAVING esta: WHERE seleciona as linhas de entrada antes
dos grupos e agregaes serem computados (portanto, controla quais linhas iro para o computo
da agregao), enquanto HAVING seleciona linhas de grupo aps os grupos e agregaes serem
computados. Portanto, a clusula WHERE no pode conter funes de agregao; no faz sentido
tentar utilizar uma agregao para determinar quais linhas sero a entrada da agregao. Por
outro lado, a clusula HAVING sempre contm funes de agregao (A rigor, permitido escrever
uma clusula HAVING que no possua agregao, mas desperdcio: A mesma condio poderia
ser utilizada de forma mais eficiente no estgio do WHERE). 7
No exemplo anterior, a restrio do nome da cidade pode ser aplicada na clusula WHERE, porque
no necessita de nenhuma agregao, sendo mais eficiente que colocar a restrio na clusula
HAVING, porque evita realizar os procedimentos de agrupamento e agregao em todas as linhas
que no atendem a clusula WHERE.

Atualizando Registros (UPDATE)


As linhas existentes podem ser atualizadas utilizando o comando UPDATE. Suponha que foi
descoberto que as leituras de temperatura esto todas mais altas 2 graus aps 28 de novembro
de 1994. Os dados podem ser atualizados da seguinte maneira:

UPDATE clima
SET temp_max = temp_max - 2,
temp_min = temp_min - 2
WHERE data > '1994-11-28';

Evolutiontech Treinamento e Desenvolvimento P g i n a | 21


POSTGRESQL Banco de dados SQL

Agora vejamos o novo estado dos dados:


SELECT * FROM clima;

cidade | temp_min | temp_max | data


-----------------+----------+----------+------------
So Francisco | 46 | 50 | 1994-11-27
So Francisco | 41 | 55 | 1994-11-29
Hayward | 35 | 52 | 1994-11-29
(3 linhas)

Excluindo Regitros (DELETE)

As linhas podem ser removidas da tabela atravs do comando DELETE. Suponha que no
estamos mais interessados nos registros do clima em Hayward. Ento precisamos excluir estas
linhas da tabela.

DELETE FROM clima WHERE cidade = 'Hayward';

Todos os registros de clima pertencentes a Hayward so removidos.

SELECT * FROM clima;

cidade | temp_min | temp_max | data


---------------+----------+----------+------------
So Francisco | 46 | 50 | 1994-11-27
So Francisco | 41 | 55 | 1994-11-29
(2 linhas)

Deve-se tomar cuidado com comandos na forma:

DELETE FROM nome_da_tabela;

Sem uma qualificao, o comando DELETE remove todas as linhas da tabela, deixando-a vazia. O
sistema no solicita confirmao antes de realizar esta operao!

Evolutiontech Treinamento e Desenvolvimento P g i n a | 22


POSTGRESQL Banco de dados SQL

DELETE FROM clima;

Evolutiontech Treinamento e Desenvolvimento P g i n a | 23


POSTGRESQL Banco de dados SQL

Funcionalidades avanadas

Introduo
Nos captulos anteriores foi descrita a utilizao bsica da linguagem SQL para armazenar e
acessar dados no PostgreSQL. Agora sero mostradas algumas funcionalidades mais avanadas da
linguagem SQL que simplificam a gerncia, e evitam a perda e a corrupo dos dados. No final
sero vistas algumas extenses do PostgreSQL.
Em certas ocasies este captulo faz referncia aos exemplos encontrados no Captulo 2 para
modific-los ou melhor-los, portanto recomenda-se que este captulo j tenha sido lido. Alguns
exemplos do presente captulo tambm se encontram no arquivo advanced.sql (./advanced.sql)
no diretrio do tutorial. Este arquivo tambm contm dados dos exemplos a serem carregados,
que no sero repetidos aqui (consulte a Seo 2.1 para saber como usar este arquivo).

Trabalhando com VIEWs


Reveja as consultas na Seo 2.6. Supondo que a consulta combinando os registros de clima e de
localizao das cidades seja de particular interesse para um aplicativo, mas que no se deseja
digitar esta consulta toda vez que for necessria, ento possvel criar uma viso baseada na
consulta, atribuindo um nome a esta consulta pelo qual ser possvel referenci-la como se fosse
uma tabela comum.

Para criar uma VIEW execute a instruo a baixo, e depois execute um


Select simplificado usando o nome da VIEW:

CREATE VIEW minha_visao AS SELECT cidade, temp_min, temp_max, prcp,


data, localizacao
FROM clima, cidades
WHERE cidade = nome;

Depois use um select simples

SELECT * FROM minha_visao;

Fazer livre uso de vises um aspecto chave de um bom projeto de banco de dados SQL. As
vises permitem encapsular, atrs de interfaces que no mudam, os detalhes da estrutura das
tabelas, que podem mudar na medida em que os aplicativos evoluem.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 24


POSTGRESQL Banco de dados SQL

As vises podem ser utilizadas em praticamente todos os lugares onde uma tabela real pode ser
utilizada. Construir vises baseadas em vises no raro.

Chaves estrangeiras
Vamos considerar as seguintes necessidades para o negcio: Desejamos ter certeza que no sero
inseridas linhas na tabela clima sem que haja um registro correspondente na tabela cidades. Isto
chamado de manter a integridade referencial dos dados. Em sistemas de banco de dados muito
simples poderia ser implementado (caso fosse) olhando primeiro a tabela cidades para verificar
se existe a linha correspondente e, depois, inserir ou rejeitar a nova linha de clima. Esta
abordagem possui vrios problemas, e muito inconveniente, por isso o PostgreSQL pode realizar
esta operao por voc.
Para impor estas restries nas tabelas vamos re-criar as tabelas de cidade e de clima.

Para criar a tabela de cidade:

CREATE TABLE cidades (


cidade varchar(80) primary key,
localizacao point );

Para criar a tabela de climas:

CREATE TABLE clima (


cidade varchar(80) references cidades(cidade),
temp_min int,
temp_max int,
prcp real,
data date );

Depois dessa configurao na estrutura da tabela, se tentar inserir uma


linha invlida:
INSERT INTO clima VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28');

Evolutiontech Treinamento e Desenvolvimento P g i n a | 25


POSTGRESQL Banco de dados SQL

ERROR: insert or update on table "clima" violates foreign key constraint


"clima_cidade_fkey" DETAIL: Key (cidade)=(Berkeley) is not present in table
"cidades".
-- Traduo da mensagem
...

O comportamento das chaves estrangeiras pode receber ajuste fino no aplicativo. No iremos
alm deste exemplo simples neste tutorial, mas consulte o Captulo 5 para obter informaes
adicionais. Com certeza o uso correto de chaves estrangeiras melhora a qualidade dos aplicativos
de banco de dados, portanto incentivamos muito que se aprenda a us-las.

Transaes (Begin, Rollback, Commit e Savepoints)


Transao um conceito fundamental de todo sistema de banco de dados. O ponto essencial da
transao englobar vrios passos em uma nica operao de tudo ou nada.
Por exemplo, considere um banco de dados de uma instituio financeira contendo o saldo da
conta corrente de vrios clientes, assim como o saldo total dos depsitos de cada agncia.
Suponha que se deseje transferir $100.00 da conta da Alice para a conta do Bob.

Exemplo 1 Sem suporte a transaes


Simplificando barbaramente, os comandos SQL para esta operao
seriam:
UPDATE conta_corrente SET saldo = saldo - 100.00
WHERE nome = 'Alice';

UPDATE filiais SET saldo = saldo - 100.00


WHERE nome = (SELECT nome_filial FROM conta_corrente WHERE nome = 'Alice');

Assim assumimos que o debto foi feito das contas referente a Alice. O
Proximo passo creditar na conta de Bob

Evolutiontech Treinamento e Desenvolvimento P g i n a | 26


POSTGRESQL Banco de dados SQL

UPDATE conta_corrente SET saldo = saldo + 100.00


WHERE nome = 'Bob';

UPDATE filiais SET saldo = saldo + 100.00


WHERE nome = (SELECT nome_filial FROM conta_corrente WHERE nome = 'Bob');

Os detalhes destes comandos no so importantes aqui; o importante o fato de existirem vrias


atualizaes distintas envolvidas para realizar uma operao bem simples. A contabilidade quer
ter certeza que todas as atualizaes so realizadas, ou que nenhuma delas realizada. No
interessante uma falha no sistema fazer com que Bob receba $100.00 que no foi debitado da
Alice. Tambm a Alice no continuar sendo uma cliente satisfeita se o dinheiro for debitado da
conta dela e no for creditado na de Bob. necessrio garantir que, caso acontea algo errado no
meio da operao, nenhum dos passos executados at este ponto iro valer. Agrupar as
atualizaes em uma transao d esta garantia. Uma transao dita como sendo atmica: do
ponto de vista das outras transaes, ou a transao acontece completamente ou nada acontece.
Desejamos, tambm, ter a garantia de estando a transao completa e aceita pelo sistema de
banco de dados, que esta fique permanentemente gravada, e no seja perdida mesmo no caso de
acontecer uma pane logo em seguida. Por exemplo, se estiver sendo registrado saque em
dinheiro pelo Bob no se deseja, de forma alguma, que o dbito em sua conta corrente
desaparea por causa de uma pane ocorrida logo depois dele sair da agncia. Um banco de dados
transacional garante que todas as atualizaes realizadas por uma transao ficam registradas em
meio de armazenamento permanente (ou seja, em disco), antes da transao ser considerada
completa.
Outra propriedade importante dos bancos de dados transacionais est muito ligada noo de
atualizaes atmicas: quando vrias transaes esto executando simultaneamente, cada uma
delas no deve enxergar as alteraes incompletas efetuadas pelas outras. Por exemplo, se uma
transao est ocupada totalizando o saldo de todas as agncias, no pode ser visto o dbito
efetuado na agncia da Alice mas ainda no creditado na agncia do Bob, nem o contrrio.
Portanto, as transaes devem ser tudo ou nada no apenas em termos do efeito permanente no
banco de dados, mas tambm em termos de visibilidade durante o processamento. As
atualizaes feitas por uma transao em andamento no podem ser vistas pelas outras
transaes enquanto no terminar, quando todas as atualizaes se tornam visveis ao mesmo
tempo.

Exemplo 2 Com suporte a transaes


No PostgreSQL a transao definida envolvendo os comandos SQL da transao pelos comandos
BEGIN e COMMIT. Sendo assim, a nossa transao bancria ficaria:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 27


POSTGRESQL Banco de dados SQL

BEGIN;
UPDATE conta_corrente SET saldo = saldo - 100.00
WHERE nome = 'Alice';

UPDATE filiais SET saldo = saldo - 100.00


WHERE nome = (SELECT nome_filial FROM conta_corrente WHERE nome =
'Alice');

UPDATE conta_corrente SET saldo = saldo + 100.00


WHERE nome = 'Bob';

UPDATE filiais SET saldo = saldo + 100.00


WHERE nome = (SELECT nome_filial FROM conta_corrente WHERE nome =
'Bob');
COMMIT ou ROLLBACK;

Se no meio da transao for decidido que esta no deve ser efetivada (talvez porque tenha sido
visto que o saldo da Alice ficou negativo), pode ser executado o comando ROLLBACK em vez do
COMMIT para fazer com que todas as atualizaes sejam canceladas.
O PostgreSQL, na verdade, trata todo comando SQL como sendo executado dentro de uma
transao. Se no for utilizado o comando BEGIN, ento cada comando possui um BEGIN e, se der
tudo certo, um COMMIT individual envolvendo-o. Um grupo de comandos envolvidos por um BEGIN
e um COMMIT algumas vezes chamado de bloco de transao.

possvel controlar os comandos na transao de uma forma mais granular utilizando os pontos
de salvamento (savepoints). Os pontos de salvamento permitem cancelar partes da transao
seletivamente, e efetivar as demais partes. Aps definir o ponto de salvamento, atravs da
instruo SAVEPOINT, possvel cancelar a transao at o ponto de salvamento, se for
necessrio, usando ROLLBACK TO. Todas as alteraes no banco de dados efetuadas entre a
definio do ponto de salvamento e o cancelamento so desprezadas, mas as alteraes
efetuadas antes do ponto de salvamento so mantidas.
Aps cancelar at o ponto de salvamento este ponto de salvamento continua definido e,
portanto, possvel cancelar vrias vezes. Ao contrrio, havendo certeza que no vai ser mais
necessrio cancelar at o ponto de salvamento, o ponto de salvamento pode ser liberado, para
que o sistema possa liberar alguns recursos. Deve-se ter em mente que liberar ou cancelar at um
ponto de salvamento libera, automaticamente, todos os ponto de salvamento definidos aps o
mesmo.
Tudo isto acontece dentro do bloco de transao e, portanto, nada disso visto pelas outras
sesses do banco de dados. Quando o bloco de transao efetivado, as aes efetivadas se
tornam visveis como uma unidade para as outras sesses, enquanto as aes canceladas nunca
se tornam visveis.
Recordando o banco de dados da instituio financeira, suponha que devesse ser debitado
$100.00 da conta da Alice e creditado na conta do Bob, mas que foi descoberto em seguida que
era para ser creditado na conta do Wally. Isso poderia ser feito utilizando pontos de salvamento
como mostrado abaixo:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 28


POSTGRESQL Banco de dados SQL

BEGIN;
UPDATE conta_corrente SET saldo = saldo - 100.00 WHERE nome = 'Alice';
SAVEPOINT meu_ponto_de_salvamento;
UPDATE conta_corrente SET saldo = saldo + 100.00 WHERE nome = 'Bob';
-- uai ... o certo na conta do Wally
ROLLBACK TO meu_ponto_de_salvamento;
UPDATE conta_corrente SET saldo = saldo + 100.00 WHERE nome = 'Wally';
COMMIT;

Obviamente este exemplo est simplificado ao extremo, mas possvel efetuar um grau elevado
de controle sobre a transao atravs do uso de pontos de salvamento. Alm disso, a instruo
ROLLBACK TO a nica forma de obter novamente o controle sobre um bloco de transao
colocado no estado interrompido devido a um erro, fora cancelar completamente e comear tudo
de novo.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 29


POSTGRESQL Banco de dados SQL

Exemplo 3 Usando Ponto de Salvamentos


No PostgreSQL a transao definida envolvendo os comandos SQL da transao pelos comandos
BEGIN e COMMIT. Sendo assim, a nossa transao bancria ficaria:

BEGIN;
UPDATE conta_corrente SET saldo = saldo - 100.00
WHERE nome = 'Alice';
SAVEPOINT ps1;

UPDATE filiais SET saldo = saldo - 100.00


WHERE nome = (SELECT nome_filial FROM conta_corrente WHERE nome =
'Alice');
SAVEPOINT ps2;

UPDATE conta_corrente SET saldo = saldo + 100.00


WHERE nome = 'Bob';
SAVEPOINT ps3;

UPDATE filiais SET saldo = saldo + 100.00


WHERE nome = (SELECT nome_filial FROM conta_corrente WHERE nome =
'Bob');
COMMIT;

Evolutiontech Treinamento e Desenvolvimento P g i n a | 30


POSTGRESQL Banco de dados SQL

Unificando Resultados na consulta (UNION)

Vamos criar duas tabelas: a tabela cidades e a tabela capitais. Como natural, as capitais
tambm so cidades e, portanto, deve existir alguma maneira para mostrar implicitamente as
capitais quando todas as cidades so mostradas. Se formos bastante perspicazes, poderemos criar
um esquema como este:

Criando a tabela de capitais


CREATE TABLE capitais (nome text,
Populacao real, altitude int, estado char(2));

Criando a tabela de interior


CREATE TABLE interior (nome text,
populacao real, altitude int);

Aplicando um Select para unir os dois resultados


SELECT nome, populacao, altitude FROM capitais
UNION
SELECT nome, populacao, altitude FROM interior;

Criando uma view para unificar os dois resultados


CREATE VIEW cidades AS
SELECT nome, populacao, altitude FROM capitais
UNION
SELECT nome, populacao, altitude FROM interior;

Este esquema funciona bem para as consultas, mas no bom quando


necessrio atualizar vrias linhas, entre outras coisas.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 31


POSTGRESQL Banco de dados SQL

Herana
Herana um conceito de banco de dados orientado a objeto, que abre novas possibilidades
interessantes ao projeto de banco de dados.

Criando a tabela1
CREATE TABLE cidades (nome text,
Populacao real, altitude int);

Criando a tabela2 e aplicando a herana na tabela cidades


CREATE TABLE capitais (estado char(2))
INHERITS (cidades);

Neste caso, as linhas da tabela capitais herdam todas as colunas (nome, populacao e altitude)
da sua tabela ancestral cidades. O tipo da coluna nome text, um tipo nativo do PostgreSQL para
cadeias de caracteres de tamanho varivel. As capitais dos estados possuem uma coluna a mais
chamada estado, que armazena a sigla do estado. No PostgreSQL uma tabela pode herdar de
nenhuma, uma, ou de vrias tabelas.
Por exemplo, a consulta abaixo retorna os nomes de todas as cidades, incluindo as capitais dos
estados, localizadas a uma altitude superior a 500 ps:

SELECT nome, altitude FROM cidades


WHERE altitude > 500;
nome | altitude
-----------+----------
Las Vegas | 2174
Mariposa | 1953
Madison | 845
(3 linhas)

Por outro lado, a consulta abaixo traz todas as cidades que no so capitais de estado e esto
situadas a uma altitude superior a 500 ps:
SELECT nome, altitude FROM ONLY cidades
WHERE altitude > 500;
nome | altitude
-----------+----------
Las Vegas | 2174
Mariposa | 1953
(2 linhas)

Evolutiontech Treinamento e Desenvolvimento P g i n a | 32


POSTGRESQL Banco de dados SQL

Nesta consulta a palavra chave ONLY antes de cidades indica que a consulta deve ser efetuada
apenas na tabela cidades, sem incluir as tabelas abaixo de cidades na hierarquia de herana.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 33


POSTGRESQL Banco de dados SQL

Sintaxe da linguagem SQL


Este captulo descreve a sintaxe da linguagem SQL, estabelecendo a base para compreender os
prximos captulos que descrevem detalhadamente como os comandos SQL so utilizados para
definir e modificar os dados.
Aconselha-se aos usurios j familiarizados com a linguagem SQL a leitura cuidadosa deste
captulo, porque existem vrias regras e conceitos implementados pelos bancos de dados SQL de
forma inconsistente, ou especficos do PostgreSQL.

Estrutura lxica
Uma entrada SQL constituda por uma seqncia de comandos. Um comando composto por
uma seqncia de smbolos terminada por um ponto-e-vrgula (;). O fim do fluxo de entrada
tambm termina o comando. Quais smbolos so vlidos depende da sintaxe particular de cada
comando.

Um smbolo pode ser uma palavra chave, um identificador, um identificador entre aspas, um
literal (ou constante), ou um caractere especial. Geralmente os smbolos so separados por
espao em branco (espao, tabulao ou nova-linha), mas no h necessidade se no houver
ambigidade (o que geralmente s acontece quando um caractere especial est adjacente a outro
tipo de smbolo).
Alm disso, podem existir comentrios na entrada SQL. Os comentrios no so smbolos, so
efetivamente equivalentes a espao em branco.
Por exemplo, o que vem a seguir uma entrada SQL vlida (sintaticamente):

SELECT * FROM MINHA_TABELA;


UPDATE MINHA_TABELA SET A = 5;
INSERT INTO MINHA_TABELA VALUES (3, 'oi voc');

Esta uma seqncia de trs comandos, um por linha (embora isto no seja requerido; pode
haver mais de um comando na mesma linha, e um nico comando pode ocupar vrias linhas).
A sintaxe do SQL no muito consistente com relao a quais smbolos identificam comandos e
quais so operandos ou parmetros. Geralmente os primeiros smbolos so o nome do comando
e, portanto, no exemplo mostrado acima pode-se dizer que esto presentes os comandos
SELECT, UPDATE e INSERT. Mas, por exemplo, o comando UPDATE sempre requer que o
smbolo SET aparea em uma determinada posio, e esta forma particular do comando INSERT
tambm requer a presena do smbolo VALUES para estar completa.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 34


POSTGRESQL Banco de dados SQL

Identificadores e palavras chave


Os smbolos, como SELECT, UPDATE e VALUES presentes no exemplo acima, so exemplos de
palavras chave, ou seja, palavras que possuem o significado definido na linguagem SQL. Os
smbolos MINHA_TABELA e A so exemplos de identificadores, os quais identificam nomes de
tabelas, colunas e outros objetos do banco de dados, dependendo do comando onde so
utilizados. Portanto, algumas vezes so simplesmente chamados de nomes.
Os identificadores e as palavras chave do SQL devem iniciar por uma letra (a-z e, tambm, letras
com diacrtico 9 - ... - e letras no latinas), ou o caractere sublinhado ( _). Os demais caracteres
de um identificador, ou da palavra chave, podem ser letras, sublinhados, dgitos ( 0-9) ou o cifro
($). Deve ser observado que, de acordo com o padro SQL, o cifro no permitido em
identificadores e, portanto, pode tornar o aplicativo menos portvel. O padro SQL no ir definir
palavra chave contendo dgitos, ou comeando ou terminando por sublinhado e, portanto, os
identificadores com esta forma esto a salvo contra possveis conflitos com extenses futuras do
padro.
O sistema no utiliza mais que NAMEDATALEN-1 caracteres de um identificador; podem ser escritos
nomes mais longos nos comandos, mas so truncados. Por padro NAMEDATALEN 64 e, portanto,
o comprimento mximo de um identificador 63.
Os identificadores e as palavras chave no fazem distino entre letras maisculas e minsculas.
Portanto,
UPDATE MINHA_TABELA SET A = 5;

pode ser escrito de forma equivalente como

uPDaTE minha_tabela SeT a = 5;

Normalmente utiliza-se a conveno de escrever as palavras chave em letras maisculas e os


nomes em letras minsculas, como mostrado abaixo:

UPDATE minha_tabela SET a = 5;

Existe um segundo tipo de identificador: o identificador delimitado ou identificador entre aspas,


formado pela colocao de uma seqncia arbitrria de caracteres entre aspas ( "). Um
identificador delimitado sempre um identificador, e nunca uma palavra chave. Portanto,
"select" pode ser usado para fazer referncia a uma tabela ou coluna chamada select,
enquanto select sem aspas sempre uma palavra chave ocasionando, por isso, um erro do
analisador quando usado onde um nome de tabela ou de coluna for esperado. O exemplo acima
pode ser reescrito utilizando identificadores entre aspas como mostrado abaixo:

UPDATE "minha_tabela" SET "a" = 5;

Identificadores entre aspas podem conter qualquer caractere que no seja a prpria aspas (Para
incluir uma aspas, devem ser escritas duas aspas). Esta funcionalidade permite criar nomes de

Evolutiontech Treinamento e Desenvolvimento P g i n a | 35


POSTGRESQL Banco de dados SQL

tabelas e de colunas que no seriam possveis de outra forma, como os contendo espaos ou e-
comercial (&). O limite do comprimento ainda se aplica.
Colocar um identificador entre aspas torna diferente as letras maisculas e minsculas, enquanto
as letras dos nomes no envoltos por aspas so sempre convertidas em minsculas. Por exemplo,
os identificadores FOO, foo e "foo" so considerados o mesmo identificador pelo PostgreSQL, mas
"Foo" e "FOO" so diferentes dos trs primeiros e entre si.

A transformao das letras dos nomes que no esto entre aspas em minsculas feita pelo
PostgreSQL incompatvel com o padro SQL, que especifica a transformao em maisculas das
letras dos nomes que no esto entre aspas. Portanto, foo deveria ser equivalente a "FOO", e no
a "foo", de acordo com o padro. Se for desejado desenvolver aplicativos portveis, aconselha-se
a colocar o nome sempre entre aspas, ou nunca entre aspas.

Utilizao de letras acentuadas em nomes de tabelas


Este exemplo tem por finalidade mostrar a utilizao de letras acentuadas nos nomes de tabelas.
Deve ser observado o problema na converso de letras maisclas e minsculas acentuadas
utilizando o idioma C.
=> CREATE TABLE AO(cod_ao int, nome_ao text);

=> \dt

Esquema | Nome | Tipo | Dono


--------+-----------+--------+----------
public | ao | tabela | postgres
public | teste_abc | tabela | postgres
public | testeaabc | tabela | postgres (3 linhas)

4.1.2. Constantes

Existem trs tipos de constante com tipo implcito no PostgreSQL: cadeias de caracteres, cadeias
de bits e numricas. As constantes tambm podem ser especificadas com tipo explcito, o que
permite uma representao mais precisa, e um tratamento mais eficiente por parte do sistema.
Estas alternativas so mostradas nas prximas subsees. 11 12 13 14

Constantes do tipo cadeia de caracteres


Uma constante cadeia de caracteres no SQL uma seqncia arbitrria de caracteres envolta por
apstrofos (') como, por exemplo, 'Esta uma cadeia de caracteres'. A forma de escrever
um apstrofo dentro de uma constante cadeia de caracteres, em conformidade com o padro
SQL, colocar dois apstrofos adjacentes como, por exemplo, 'Maria D''Almeida'. O
PostgreSQL tambm permite utilizar a contrabarra (\) como caractere de escape para colocar
apstrofos dentro de cadeia de caracteres como, por exemplo, 'Maria D\'Almeida'.
Outra extenso do PostgreSQL permitir a utilizao dos escapes de contrabarra no estilo da
linguagem C: \b para voltar apagando (backspace), \f para avano de formulrio (form feed), \n
para nova-linha (newline), \r para retorno do carro (carriage return), \t para tabulao (tab) e
\xxx, onde xxx um nmero octal, o byte com o cdigo correspondente ( sua responsabilidade

Evolutiontech Treinamento e Desenvolvimento P g i n a | 36


POSTGRESQL Banco de dados SQL

que as seqncias de byte criadas sejam caracteres vlidos no conjunto de codificao de


caracteres do servidor). Qualquer outro caractere vindo aps a contrabarra interpretado
literalmente. Portanto, para incluir uma contrabarra em uma constante do tipo cadeia de
caracteres devem ser escritas duas contrabarras adjacentes.

Constantes do tipo cadeia de bits


Uma constante do tipo cadeia de bits se parece com uma constante do tipo cadeia de caracteres
contendo a letra B (maiscula ou minscula) imediatamente antes do apstrofo de abertura (sem
espaos separadores) como, por exemplo, B'1001'. Os nicos caracteres permitidos dentro de
uma constante do tipo cadeia de bits so 0 e 1.
Como forma alternativa, constantes do tipo cadeia de bits podem ser especificadas usando a
notao hexadecimal, colocando a letra X (maiscula ou minscula) no incio como, por exemplo,
X'1FF'. Esta notao equivale a uma constante do tipo cadeia de bits contendo quatro dgitos
binrios para cada dgito hexadecimal.
As duas formas de constantes do tipo cadeia de bits podem ocupar mais de uma linha, da mesma
forma que uma constante do tipo cadeia de caracteres. A delimitao por cifro no pode ser
utilizada para o tipo cadeia de bits.

Constantes numricas
So aceitas constantes numricas nas seguintes formas gerais:

Onde dgitos so um ou mais dgitos decimais (0 a 9). Deve haver pelo menos um dgito antes ou
depois do ponto decimal, se este for usado. Deve haver pelo menos um dgito aps a marca de
expoente (e), caso esteja presente. No podem existir espaos ou outros caracteres incorporados
constante. Deve ser observado que os sinais menos e mais que antecedem a constante no so,
na verdade, considerados parte da constante, e sim um operador aplicado constante.
Abaixo so mostrados alguns exemplos de constantes numricas vlidas:
42
3.5
4.
.001
5e2
1.925e-3

Uma constante numrica no contendo o ponto decimal nem o expoente presumida,


inicialmente, como sendo do tipo integer, se o seu valor for apropriado para o tipo integer (32
bits); seno presumida como sendo do tipo bigint, se o seu valor for apropriado para o tipo
bigint (64 bits); caso contrrio, assumida como sendo do tipo numeric. As constantes que
contm pontos decimais e/ou expoentes so sempre presumidas inicialmente como sendo do
tipo numeric.
O tipo de dado atribudo inicialmente para a constante numrica apenas o ponto de partida

Evolutiontech Treinamento e Desenvolvimento P g i n a | 37


POSTGRESQL Banco de dados SQL

Constantes de outros tipos


Pode ser declarada uma constante de um tipo arbitrrio utilizando uma das seguintes notaes:

O texto da constante cadeia de caracteres passado para a rotina de converso da entrada para o
tipo chamado tipo. O resultado uma constante do tipo indicado. A converso explcita de tipo
pode ser omitida caso no haja ambigidade com relao ao tipo que a constante deva ter (por
exemplo, quando atribuda diretamente para uma coluna de uma tabela), neste caso
convertida automaticamente.
A constante cadeia de caracteres pode ser escrita utilizando tanto a notao regular do padro
SQL quanto a delimitao por cifro.

Operadores
Um nome de operador uma seqncia com at NAMEDATALEN-1 (por padro 63) caracteres da
seguinte lista:

+ - * / < > = ~ ! @ # % ^ & | ` ?

Entretanto, existem algumas poucas restries para os nomes de operadores:


No podem ocorrer as seqncias -- e /* em nenhuma posio no nome do operador,
porque so consideradas incio de comentrio.
Um nome de operador com vrios caracteres no pode terminar por + ou por -, a no ser
que o nome tambm contenha ao menos um dos seguintes caracteres: ~ ! @ # % ^ & | ` ?.
Por exemplo, @- um nome de operador permitido, mas *- no . Esta restrio permite ao
PostgreSQL analisar comandos em conformidade com o padro SQL sem requerer espaos entre
os smbolos.
Ao trabalhar com nomes de operadores fora do padro SQL, normalmente necessrio separar
operadores adjacentes por espao para evitar ambigidade. Por exemplo, se for definido um
operador unrio-esquerdo chamado @, no poder ser escrito X*@Y; dever ser escrito X* @Y,
para garantir que o PostgreSQL leia dois nomes de operadores e no apenas um.

Caracteres especiais
Alguns caracteres no alfanumricos possuem significado especial diferente de ser um operador.
Os detalhes da utilizao podem ser encontrados nos locais onde a sintaxe do respectivo
elemento descrita. Esta seo se destina apenas a informar a existncia e fazer um resumo das
finalidades destes caracteres.
O caractere cifro ($) seguido por dgitos utilizado para representar parmetros
posicionais no corpo da definio de uma funo ou declarao preparada. Em outros contextos,
o caractere cifro pode ser parte de um identificador ou de uma constante cadeia de caracteres
delimitada por cifro.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 38


POSTGRESQL Banco de dados SQL

Os parnteses (()) possuem seu significado usual de agrupar expresses e impor a


precedncia. Em alguns casos, os parnteses so requeridos como parte da sintaxe fixada para
um determinado comando SQL.
Os colchetes ([]) so utilizados para selecionar elementos da matriz.
As vrgulas (,) so utilizadas em algumas construes sintticas para separar elementos da
lista.
O ponto-e-vrgula (;) termina um comando SQL, no podendo aparecer em nenhum lugar
dentro do comando, exceto dentro de constante cadeia ou identificador entre aspas.
Os dois-pontos (:) so utilizados para selecionar fatias de matrizes (consulte a Seo
8.10). Em certos dialetos do SQL, como a linguagem SQL incorporada, os dois-pontos so
utilizados como prefixo dos nomes das variveis.
O asterisco (*) utilizado em alguns contextos para denotar todos os campos da linha de
uma tabela ou de um valor composto. Tambm possui um significado especial quando utlizado
como argumento da funo de agregao COUNT.
O ponto (.) utilizado nas constantes numricas, e para separar os nomes de esquemas,
tabelas e colunas.

Comentrios
Um comentrio uma seqncia arbitrria de caracteres comeando por dois hfens e
prosseguindo at o fim da linha como, por exemplo:

-- Este um comentrio padro SQL-92

Como alternativa, podem ser utilizados blocos de comentrios no estilo C:

/* comentrio de vrias linhas


* com aninhamento: /* bloco de comentrio aninhado */
*/

onde o comentrio comea por /* e se estende at encontrar a ocorrncia correspondente de */.


Estes blocos de comentrios podem estar aninhados, conforme especificado no padro SQL, mas
diferentemente da linguagem C, permitindo transformar em comentrio grandes blocos de cdigo
contendo blocos de comentrios.
Os comentrios so removidos do fluxo de entrada antes de prosseguir com a anlise sinttica,
sendo substitudos por espao em branco.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 39


POSTGRESQL Banco de dados SQL

4.1.6. Precedncia lxica

A Tabela 4-1 mostra a precedncia e a associatividade dos operadores no PostgreSQL. A maioria


dos operadores possui a mesma precedncia e associatividade esquerda. A precedncia e a
associatividade dos operadores est codificada no analisador, podendo ocasionar um
comportamento contra-intuitivo; por exemplo, os operadores booleanos < e > possuem uma
precedncia diferente dos operadores booleanos <= e >=. Tambm, em alguns casos necessrio
adicionar parnteses ao utilizar uma combinao de operadores unrios e binrios. Por exemplo,

SELECT 5 ! - 6;

ser analisado como

SELECT 5 ! (- 6);

porque o analisador no possui a menor idia at ser tarde demais que o ! definido como
operador unrio-direito (postfix), e no um operador binrio colocado entre os operandos (infix).
Neste caso, para obter o comportamento desejado deve ser escrito:

SELECT (5 !) - 6;

Este o preo a ser pago pela extensibilidade.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 40


POSTGRESQL Banco de dados SQL

Operador/Elemento Descrio
. separador de nome de tabela/coluna
- menos unrio
^ exponenciao
*/% multiplicao, diviso, mdulo
+- adio, subtrao
IS IS TRUE, IS FALSE, IS UNKNOWN, IS NULL

ISNULL teste de nulo


NOTNULL teste de no nulo
IN membro de um conjunto
BETWEEN contido em um intervalo
OVERLAPS sobreposio de intervalo de tempo
LIKE ILIKE SIMILAR correspondncia de padro em cadeia de caracteres
<> menor que, maior que
= igualdade, atribuio
NOT negao lgica
AND conjuno lgica
OR disjuno lgica

Expresses de valor
As expresses de valor so utilizadas em diversos contextos, como na lista de seleo do comando
SELECT, como novos valores das colunas nos comandos INSERT e UPDATE, e na condio de
procura em vrios comandos. Algumas vezes o resultado de uma expresso de valor chamado
de escalar, para distingui-lo do resultado de uma expresso de tabela (que uma tabela). As
expresses de valor so, portanto, chamadas tambm de expresses escalares (ou mesmo
simplesmente de expresses). A sintaxe da expresso permite o clculo de valores a partir de
partes primitivas utilizando operaes aritmticas, lgicas, de conjunto e outras.

A expresso de valor uma das seguintes:


Um valor constante ou literal.
Uma referncia a coluna.
Uma referncia a parmetro posicional, no corpo da definio de funo ou de comando
preparado.
Uma expresso de ndice.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 41


POSTGRESQL Banco de dados SQL

Uma expresso de seleo de campo.


Uma chamada de operador.
Uma chamada de funo.
Uma expresso de agregao.
Uma converso de tipo.
Uma subconsulta escalar.
Um construtor de matriz.
Um construtor de linha.
Outra expresso de valor entre parnteses, til para agrupar subexpresses e mudar
precedncias.
Em acrscimo a esta lista, existem diversas construes que podem ser classificadas como uma
expresso, mas que no seguem qualquer regra geral de sintaxe. Possuem, normalmente, a
semntica de uma funo ou de um operador, sendo explicadas no local apropriado no Captulo 9.
Um exemplo a clusula IS NULL.
As constantes j foram mostradas na Seo 4.1.2. As prximas sees discutem as demais opes.

Referncias a coluna
Uma coluna pode ser referenciada usando a forma correlao.nome_da_coluna onde
correlao o nome de uma tabela (possivelmente qualificado pelo nome do esquema), ou
um alis para a tabela definido por meio da clusula FROM, ou uma das palavras chave NEW ou
OLD (NEW e OLD somente podem aparecer nas regras de reescrita, enquanto os outros nomes
de correlao podem ser usados em qualquer declarao SQL).

Subconsultas escalares
Uma subconsulta escalar um comando SELECT comum, entre parnteses, que retorna
exatamente uma linha com uma coluna (consulte o Captulo 7 para obter informaes sobre como
escrever consultas). O comando SELECT executado e o nico valor retornado utilizado na
expresso de valor envoltria. errado utilizar uma consulta que retorne mais de uma linha ou
mais de uma coluna como subconsulta escalar (porm, se durante uma determinada execuo a
subconsulta no retornar nenhuma linha, no acontece nenhum erro: o resultado escalar
assumido como nulo). A subconsulta pode fazer referncia a variveis da consulta envoltria, as
quais atuam como constantes durante a avaliao da subconsulta. Veja, tambm, outras
expresses envolvendo subconsultas na Seo 9.16. 23
Por exemplo, a consulta abaixo retorna a maior populao de cidade de cada estado:
SELECT nome,
(SELECT max(populacao) FROM cidades
WHERE cidades.estado = estados.nome)
FROM estados;

Evolutiontech Treinamento e Desenvolvimento P g i n a | 42


POSTGRESQL Banco de dados SQL

Definio de dados
Este captulo mostra como criar as estruturas de banco de dados que armazenam os dados. Nos
bancos de dados relacionais os dados so armazenados em tabelas, por isso a maior parte deste
captulo dedica-se a explicar como as tabelas so criadas e modificadas, e as funcionalidades
disponveis para controlar que dados podem ser armazenados nas tabelas. Em seguida
mostrado como as tabelas podem ser organizadas em esquemas, e como atribuir privilgios s
tabelas. No final so vistas, superficialmente, outras funcionalidades que afetam o
armazenamento dos dados, como vises, funes e gatilhos.

Noes bsicas de tabela


Uma tabela em um banco de dados relacional muito semelhante a uma tabela no papel:
formada por linhas e colunas. O nmero e a ordem das colunas so fixos, e cada coluna possui um
nome. O nmero de linhas varivel, refletindo a quantidade de dados armazenados em um
determinado instante. O padro SQL no d nenhuma garantia sobre a ordem das linhas na
tabela. Quando a tabela lida, as linhas aparecem em uma ordem aleatria, a no ser que a
classificao seja requisitada explicitamente. Esta parte descrita no Captulo 7. Alm disso, o SQL
no atribui identificadores nicos para as linhas e, portanto, possvel existirem vrias linhas
totalmente idnticas na tabela. Isto uma conseqncia do modelo matemtico subjacente ao
SQL, mas geralmente no desejvel. Mais adiante neste captulo ser mostrado como lidar com
esta questo.
Cada coluna possui um tipo de dado. O tipo de dado restringe o conjunto de valores que podem
ser atribudos coluna e atribui semntica 1 aos dados armazenados na coluna, de forma que
estes possam ser processados. Por exemplo, uma coluna declarada como sendo de um tipo
numrico no aceita cadeias de caracteres com texto arbitrrio, e os dados armazenados nesta
coluna podem ser utilizados para efetuar clculos matemticos. Ao contrrio, uma coluna
declarada como sendo do tipo cadeia de caracteres aceita praticamente qualquer espcie de
dado, mas no pode ser usada para efetuar clculos matemticos, embora possam ser efetuadas
outras operaes, como a concatenao de cadeias de caracteres.
Para criar uma tabela utiliza-se o comando CREATE TABLE. Neste comando so especificados, ao
menos, o nome da nova tabela, os nomes das colunas, e o tipo de dado de cada coluna. Por
exemplo:

CREATE TABLE minha_primeira_tabela (


primeira_coluna text,
segunda_coluna integer );

Este comando cria a tabela chamada minha_primeira_tabela contendo duas colunas. A primeira
coluna chama-se primeira_coluna, e possui o tipo de dado text; a segunda coluna chama-se
segunda_coluna, e possui o tipo de dado integer. O nome da tabela e das colunas obedecem a
sintaxe para identificadores explicada na Seo 4.1.1. Normalmente os nomes dos tipos tambm
so identificadores, mas existem algumas excees. Deve ser observado que a lista de colunas
envolta por parnteses, e os elementos da lista so separados por vrgula.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 43


POSTGRESQL Banco de dados SQL

Obviamente, o exemplo anterior muito artificial. Normalmente so dados nomes para as tabelas
e para as colunas condizentes com as informaes armazenadas. Sendo assim, vejamos um
exemplo mais prximo da realidade:

CREATE TABLE produtos ( cod_prod integer, nome text,


preco numeric );

Existe um limite de quantas colunas uma tabela pode conter. Dependendo dos tipos das colunas,
pode ser entre 250 e 1600. Entretanto, definir uma tabela com esta quantidade de colunas
muito raro e, geralmente, torna o projeto questionvel.
Se uma tabela no for mais necessria, pode-se remov-la utilizando o comando DROP TABLE. Por
exemplo:

DROP TABLE minha_primeira_tabela;


DROP TABLE produtos;

Tentar remover uma tabela no existente um erro. Entretanto, comum os arquivos de script
SQL tentarem remover a tabela incondicionalmente antes de cri-la, ignorando a mensagem de
erro.
Se for necessrio modificar uma tabela existente consulte a Seo 5.6 mais adiante neste captulo.
Utilizando as ferramentas mostradas at este ponto possvel criar tabelas totalmente funcionais.
O restante deste captulo est relacionado com a adio de funcionalidades na definio da tabela
para garantir a integridade dos dados, a segurana, ou a comodidade. Se voc est ansioso para
colocar dados nas tabelas neste instante, ento pode ir direto para o Captulo 6 e ler o restante
deste captulo depois.

Restries (CONSTRAINTS)
Os tipos de dado so uma forma de limitar os dados que podem ser armazenados na tabela.
Entretanto, para muitos aplicativos a restrio obtida no possui o refinamento necessrio. Por
exemplo, uma coluna contendo preos de produtos provavelmente s pode aceitar valores
positivos, mas no existe nenhum tipo de dado que aceite apenas nmeros positivos. Um outro
problema que pode ser necessrio restringir os dados de uma coluna com relao a outras
colunas ou linhas. Por exemplo, em uma tabela contendo informaes sobre produtos deve haver
apenas uma linha para cada cdigo de produto.
Para esta finalidade, a linguagem SQL permite definir restries em colunas e tabelas. As
restries permitem o nvel de controle sobre os dados da tabela que for desejado. Se o usurio
tentar armazenar dados em uma coluna da tabela violando a restrio, ocasiona erro. Isto se
aplica at quando o erro originado pela definio do valor padro.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 44


POSTGRESQL Banco de dados SQL

Valor padro (constraint DEFAULT)


Pode ser atribudo um valor padro a uma coluna. Quando criada uma nova linha, e no
especificado nenhum valor para algumas de suas colunas, estas colunas so preenchidas com o
valor padro de cada uma delas. Alm disso, um comando de manipulao de dados pode
requerer explicitamente que a coluna receba o seu valor padro, sem saber qual este valor (os
detalhes sobre os comandos de manipulao de dados esto no Captulo 6).
Se no for declarado explicitamente nenhum valor padro, o valor nulo ser o valor padro. Isto
geralmente faz sentido, porque o valor nulo pode ser considerado como representando um dado
desconhecido.

Na definio da tabela, o valor padro posicionado aps o tipo de dado


da coluna. Por exemplo:

CREATE TABLE produtos (


cod_prod integer PRIMARY KEY,
nome text,
preco numeric DEFAULT 9.99 );

O valor padro pode ser uma expresso, avaliada sempre que for inserido o valor padro (e no
quando a tabela criada). Um exemplo comum uma coluna do tipo timestamp com o valor
padro now(), para que receba a data e hora de insero da linha.

Outro exemplo comum a gerao de um nmero serial para cada linha. No PostgreSQL isto
feito tipicamente atravs de algo como:

CREATE TABLE produtos (


cod_prod integer DEFAULT nextval('produtos_cod_prod_seq'),
...
);

onde a funo nextval() fornece valores sucessivos do objeto de seqncia (consulte a Seo
9.12).
Esta situao to comum que existe uma forma abreviada da mesma:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 45


POSTGRESQL Banco de dados SQL

CREATE TABLE produtos ( cod_prod SERIAL,


...
);

Restries de verificao (constraint CHECK)


Uma restrio de verificao o tipo mais genrico de restrio. Permite especificar que os
valores de uma determinada coluna devem estar de acordo com uma expresso booleana (valor-
verdade). Por exemplo, para permitir apenas preos com valores positivos utiliza-se:

CREATE TABLE produtos (


cod_prod integer,
nome text,
preco numeric CHECK (preco > 0) );

Como pode ser observado, a definio da restrio vem aps o tipo de dado, assim como a
definio do valor padro. O valor padro e a restrio podem estar em qualquer ordem. A
restrio de verificao formada pela palavra chave CHECK seguida por uma expresso entre
parnteses. A expresso da restrio de verificao deve envolver a coluna sendo restringida,
seno no far muito sentido.
Tambm pode ser atribudo um nome individual para a restrio. Isto torna mais clara a
mensagem de erro, e permite fazer referncia restrio quando se desejar alter-la. A sintaxe :

CREATE TABLE produtos (


cod_prod integer,
nome text,
preco numeric CONSTRAINT chk_preco_positivo CHECK (preco >
0) );

Portanto, para especificar o nome da restrio deve ser utilizada a palavra chave CONSTRAINT,
seguida por um identificador, seguido por sua vez pela definio da restrio (Se no for escolhido
o nome da restrio desta maneira, o sistema escolhe um nome para a restrio).
Uma restrio de verificao tambm pode referenciar vrias colunas. Supondo que sero
armazenados o preo normal e o preo com desconto, e que se deseje garantir que o preo com
desconto seja menor que o preo normal:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 46


POSTGRESQL Banco de dados SQL

CREATE TABLE produtos (


cod_prod integer,
nome text,
preco numeric CHECK (preco > 0),
preco_com_desconto numeric CHECK (preco_com_desconto > 0),
CHECK (preco > preco_com_desconto) );

As duas primeiras formas de restrio j devem ser familiares. A terceira utiliza uma nova sintaxe,
e no est anexada a uma coluna em particular. Em vez disso, aparece como um item parte na
lista de colunas separadas por vrgula. As definies das colunas e as definies destas restries
podem estar em qualquer ordem.
Dizemos que as duas primeiras restries so restries de coluna, enquanto a terceira uma
restrio de tabela, porque est escrita separado das definies de colunas. As restries de
coluna tambm podem ser escritas como restries de tabela, enquanto o contrrio nem sempre
possvel, porque supostamente a restrio de coluna somente faz referncia coluna em que
est anexada (O PostgreSQL no impe esta regra, mas deve-se segui-la se for desejado que a
definio da tabela sirva para outros sistemas de banco de dados). O exemplo acima tambm
pode ser escrito do seguinte modo:

CREATE TABLE produtos (


cod_prod integer,
nome text,
preco numeric,
CHECK (preco > 0),
preco_com_desconto numeric,
CHECK (preco_com_desconto > 0),
CHECK (preco > preco_com_desconto) );

ou ainda

CREATE TABLE produtos (


cod_prod integer,
nome text,
preco numeric CHECK (preco > 0),
preco_com_desconto numeric,
CHECK (preco_com_desconto > 0
AND preco > preco_com_desconto) );

Evolutiontech Treinamento e Desenvolvimento P g i n a | 47


POSTGRESQL Banco de dados SQL

uma questo de gosto.

Restries de no-nulo (constraint NOT NULL)

Uma restrio de no-nulo simplesmente especifica que uma coluna no pode assumir o valor
nulo. Um exemplo da sintaxe:

CREATE TABLE produtos (


cod_prod integer NOT NULL,
nome text NOT NULL,
preco numeric );

A restrio de no-nulo sempre escrita como restrio de coluna. A restrio de no-nulo


funcionalmente equivalente a criar uma restrio de verificao CHECK (nome_da_coluna IS NOT
NULL), mas no PostgreSQL a criao de uma restrio de no-nulo explcita mais eficiente. A
desvantagem que no pode ser dado um nome explcito para uma restrio de no nulo criada
deste modo.
Obviamente, uma coluna pode possuir mais de uma restrio, bastando apenas escrever uma
restrio em seguida da outra:
CREATE TABLE produtos (
cod_prod integer NOT NULL,
nome text NOT NULL,
preco numeric NOT NULL CHECK (preco > 0) );

A ordem das restries no importa, porque no determina, necessariamente, a ordem de


verificao das restries.
A restrio NOT NULL possui uma inversa: a restrio NULL. Isto no significa que a coluna deva ser
nula, o que com certeza no tem utilidade. Em vez disto simplesmente definido o
comportamento padro dizendo que a coluna pode ser nula. A restrio NULL no definida no
padro SQL, no devendo ser utilizada em aplicativos portveis (somente foi adicionada ao
PostgreSQL para torn-lo compatvel com outros sistemas de banco de dados). Porm, alguns
usurios gostam porque torna fcil inverter a restrio no script de comandos. Por exemplo,
possvel comear assim:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 48


POSTGRESQL Banco de dados SQL

CREATE TABLE produtos (


cod_prod integer NULL,
nome text NULL,
preco numeric NULL );

Depois colocar a palavra chave NOT onde se desejar.

Restries de unicidade (constraint NOT NULL)


A restrio de unicidade garante que os dados contidos na coluna, ou no grupo de colunas,
nico em relao a todas as outras linhas da tabela. A sintaxe :

CREATE TABLE produtos (


cod_prod integer UNIQUE,
nome text,
preco numeric );

quando escrita como restrio de coluna, e


CREATE TABLE produtos (
cod_prod integer,
nome text,
preco numeric,
UNIQUE (cod_prod));

quando escrita como restrio de tabela.

Se uma restrio de unicidade faz referncia a um grupo de colunas, as colunas so listadas


separadas por vrgula:

CREATE TABLE exemplo (


a integer,
b integer,
c integer,
UNIQUE (a, c) );

Evolutiontech Treinamento e Desenvolvimento P g i n a | 49


POSTGRESQL Banco de dados SQL

Observao:

Isto especifica que a combinao dos valores das colunas indicadas deve
ser nico para toda a tabela, embora no seja necessrio que cada uma
das colunas seja nica (o que geralmente no ).
De um modo geral, uma restrio de unicidade violada quando existem duas ou mais linhas na
tabela onde os valores de todas as colunas includas na restrio so iguais. Entretanto, os valores
nulos no so considerados iguais nesta comparao. Isto significa que, mesmo na presena da
restrio de unicidade, possvel armazenar um nmero ilimitado de linhas que contenham o
valor nulo em pelo menos uma das colunas da restrio. Este comportamento est em
conformidade com o padro SQL, mas j ouvimos dizer que outros bancos de dados SQL no
seguem esta regra. Portanto, seja cauteloso ao desenvolver aplicativos onde se pretenda haver
portabilidade.

Chaves primrias (constraint PRIMARY KEY)

Tecnicamente a restrio de chave primria simplesmente a combinao da restrio de


unicidade com a restrio de nonulo. Portanto, as duas definies de tabela abaixo aceitam os
mesmos dados:
CREATE TABLE produtos (
cod_prod integer UNIQUE NOT NULL,
nome text,
preco numeric );

Usando a contraint Primary Key ficar assim:

CREATE TABLE produtos (


cod_prod integer PRIMARY KEY,
nome text, preco numeric );

Chaves Compostas (constraint PRIMARY KEY em


dois ou mais campos)

Evolutiontech Treinamento e Desenvolvimento P g i n a | 50


POSTGRESQL Banco de dados SQL

As chaves primrias tambm podem restringir mais de uma coluna; a


sintaxe semelhante da restrio de unicidade:

CREATE TABLE exemplo (


a integer,
b integer,
c integer,
PRIMARY KEY (a, c)
);

A chave primria indica que a coluna, ou grupo de colunas, pode ser utilizada como identificador
nico das linhas da tabela (Isto uma conseqncia direta da definio da chave primria. Deve
ser observado que a restrio de unicidade no fornece, por si s, um identificador nico, porque
no exclui os valores nulos).
Uma tabela pode ter no mximo uma chave primria (embora possa ter muitas restries de
unicidade e de no-nulo). A teoria de banco de dados relacional dita que toda tabela deve ter uma
chave primria. Esta regra no imposta pelo PostgreSQL, mas normalmente melhor segui-la.

Chaves Estrangeiras (constraint PRIMARY KEY)


A restrio de chave estrangeira especifica que o valor da coluna (ou grupo de colunas) deve
corresponder a algum valor existente em uma linha de outra tabela. Diz-se que a chave
estrangeira mantm a integridade referencial entre duas tabelas relacionadas.
Supondo que j temos a tabela de produtos utilizada diversas vezes anteriormente:

CREATE TABLE produtos (


cod_prod integer UNIQUE NOT NULL,
nome text,
preco numeric );

Agora vamos assumir a existncia de uma tabela armazenando os pedidos destes produtos.
Desejamos garantir que a tabela de pedidos contenha somente pedidos de produtos que
realmente existem. Para isso definida uma restrio de chave estrangeira na tabela de pedidos
fazendo referncia tabela de produtos:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 51


POSTGRESQL Banco de dados SQL

CREATE TABLE pedidos (


cod_pedido integer PRIMARY KEY,
cod_prod integer REFERENCES produtos (cod_prod),
quantidade integer );

Isto torna impossvel criar um pedido com cod_prod no existente na tabela de produtos.
Nesta situao dito que a tabela de pedidos a tabela que faz referncia, e a tabela de produtos
a tabela referenciada.
Da mesma forma existem colunas fazendo referncia e sendo referenciadas.
O comando acima pode ser abreviado escrevendo
CREATE TABLE pedidos (
cod_pedido integer PRIMARY KEY,
cod_prod integer FOREIGN
REFERENCES produtos,
KEY REFERENCES produtos(id_produto) ,

quantidade integer );

Porque, na ausncia da lista de colunas, a chave primria da tabela referenciada usada como a
coluna referenciada.
A chave estrangeira tambm pode restringir e referenciar um grupo de colunas. Como usual,
necessrio ser escrito na forma de restrio de tabela. Abaixo est mostrado um exemplo artificial
da sintaxe:

CREATE TABLE t1 (
a integer PRIMARY KEY,
b integer,
c integer,
FOREIGN KEY (b, c) REFERENCES outra_tabela (c1, c2) );

Obviamente, o nmero e tipo das colunas na restrio devem corresponder ao nmero e tipo das
colunas referenciadas.
Pode ser atribudo um nome restrio de chave estrangeira da forma habitual.

Quando usar Chave Primria e Chave Estrangeira na


mesma coluna
Uma tabela pode conter mais de uma restrio de chave estrangeira, o que utilizado para
implementar relacionamentos muitos-para-muitos entre tabelas. Digamos que existam as tabelas
de produtos e de pedidos, e desejamos permitir que um pedido posa conter vrios produtos (o
que no permitido na estrutura anterior). Podemos, ento, utilizar a seguinte estrutura de
tabela:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 52


POSTGRESQL Banco de dados SQL

Evolutiontech Treinamento e Desenvolvimento P g i n a | 53


POSTGRESQL Banco de dados SQL

Tabela de chave primaria PRODUTOS


CREATE TABLE produtos (
cod_prod integer PRIMARY KEY,
nome text,
preco numeric );

Tabela de chave primria PEDIDOS


CREATE TABLE pedidos (
cod_pedido integer PRIMARY KEY,
endereco_entrega text,
...
);

Tabela de chave estrangeira ITENS_PEDIDOS


CREATE TABLE itens_pedidos (
cod_prod integer REFERENCES produtos,
cod_pedido integer REFERENCES pedidos,
quantidade integer,
PRIMARY KEY (cod_prod, cod_pedido) );

Deve ser observado, tambm, que a chave primria est sobreposta s chaves estrangeiras na
ltima tabela.
Sabemos que a chave estrangeira no permite a criao de pedidos no relacionados com algum
produto. Porm, o que acontece se um produto for removido aps a criao de um pedido
fazendo referncia a este produto? A linguagem SQL permite tratar esta situao tambm.
Intuitivamente temos algumas opes:

No permitir a excluso de um produto referenciado


Excluir o pedido tambm
Algo mais?

Para ilustrar esta situao, vamos implementar a seguinte poltica no exemplo de relacionamento
muitos-para-muitos acima: Quando se desejar remover um produto referenciado por um pedido
(atravs de itens_pedidos), isto no ser permitido. Se um pedido for removido, os itens do
pedido tambm sero removidos.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 54


POSTGRESQL Banco de dados SQL

CREATE TABLE produtos (


cod_prod integer PRIMARY KEY,
nome text,
preco numeric );

CREATE TABLE pedidos (


cod_pedido integer PRIMARY KEY,
endereco_entrega text,
...
);

CREATE TABLE itens_pedidos (


cod_prod integer REFERENCES produtos ON DELETE
RESTRICT,
cod_pedido integer REFERENCES pedidos ON DELETE
CASCADE, quantidade integer,
PRIMARY KEY (cod_prod, cod_pedido) );

As duas opes mais comuns so restringir, ou excluir em cascata. RESTRICT no permite excluir a
linha referenciada. NO ACTION significa que, se as linhas referenciadas ainda existirem quando a
restrio for verificada, ser gerado um erro; este o comportamento padro se nada for
especificado (A diferena essencial entre estas duas opes que NO ACTION permite postergar a
verificao para mais tarde na transao, enquanto RESTRICT no permite). CASCADE especifica
que, quando a linha referenciada excluda, as linhas que fazem referncia tambm devem ser
excludas automaticamente. Existem outras duas opes: SET NULL e SET DEFAULT. Estas opes
fazem com que as colunas que fazem referncia sejam definidas como nulo ou com o valor
padro, respectivamente, quando a linha referenciada excluda. Deve ser observado que isto
no evita a observncia das restries. Por exemplo, se uma ao especificar SET DEFAULT, mas o
valor padro no satisfizer a chave estrangeira, a operao no ser bem-sucedida.
Semelhante a ON DELETE existe tambm ON UPDATE, chamada quando uma coluna referenciada
alterada (atualizada).
As aes possveis so as mesmas.
Mais informaes sobre atualizao e excluso de dados podem ser encontradas no Captulo 6.
Para terminar, devemos mencionar que a chave estrangeira deve referenciar colunas de uma
chave primria ou de uma restrio de unicidade. Se a chave estrangeira fizer referncia a uma
restrio de unicidade, existem algumas possibilidades adicionais sobre como os valores nulos so
correspondidos. Esta parte est explicada na documentao de referncia para CREATE TABLE.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 55


POSTGRESQL Banco de dados SQL

Modificao de tabelas
Quando percebemos, aps a tabela ser criada, que foi cometido um erro ou que os requisitos do
aplicativo mudaram, possvel remover a tabela e cri-la novamente. Porm, esta opo no
conveniente quando existem dados na tabela, ou se a tabela referenciada por outros objetos do
banco de dados (por exemplo, uma restrio de chave estrangeira); por isso, o PostgreSQL
disponibiliza um conjunto de comandos para realizar modificaes em tabelas existentes. Deve
ser observado que esta operao conceitualmente distinta da alterao dos dados contidos na
tabela, aqui o interesse est em mudar a definio, ou estrutura, da tabela.
possvel:
Adicionar coluna;
Remover coluna;
Adicionar restrio;
Remover restrio;
Mudar valor padro;
Mudar tipo de dado de coluna;
Mudar nome de coluna;
Mudar nome de tabela.

Todas estas atividades so realizadas utilizando o comando ALTER


TABLE.

Adicionar coluna
Para adicionar uma coluna, utiliza-se:

ALTER TABLE produtos ADD COLUMN descricao text;

Inicialmente a nova coluna preenchida com o valor padro especificado, ou nulo se a clusula
DEFAULT no for especificada.

Tambm podem ser definidas, ao mesmo tempo, restries para a coluna utilizando a sintaxe
habitual:

ALTER TABLE produtos ADD COLUMN descricao text CHECK (descricao <>
'');

Na verdade, todas as opes que podem ser aplicadas descrio da coluna no comando CREATE
TABLE podem ser utilizadas aqui. Entretanto, tenha em mente que o valor padro deve satisfazer
as restries especificadas, ou o ADD no ser bem-sucedido. Como alternativa, as restries

Evolutiontech Treinamento e Desenvolvimento P g i n a | 56


POSTGRESQL Banco de dados SQL

podem ser adicionadas posteriormente (veja abaixo), aps a nova coluna ter sido preenchida com
dados adequados.

Remover coluna
Para remover uma coluna, utiliza-se:

ALTER TABLE produtos DROP COLUMN descricao;

Os dados presentes na coluna desaparecem. As restries de tabela que envolvem a coluna


tambm so removidas. Entretanto, se a coluna for referenciada por uma restrio de chave
estrangeira de outra tabela, o PostgreSQL no ir remover esta restrio em silncio. Pode ser
autorizada a remoo de tudo que depende da coluna adicionando CASCADE:

ALTER TABLE produtos DROP COLUMN descricao CASCADE;

Adicionar restrio
utilizada a sintaxe de restrio de tabela para adicionar uma restrio. Por exemplo:

ALTER TABLE produtos ADD CHECK (nome <> '');

ALTER TABLE produtos ADD CONSTRAINT


unq_cod_prod UNIQUE (cod_prod);

ALTER TABLE produtos ADD FOREIGN KEY


(fk_grupo_produtos) REFERENCES grupo_produtos;

Para adicionar a restrio de no nulo, que no pode ser escrita na forma de restrio de tabela,
deve ser utilizada a sintaxe:

ALTER TABLE produtos ALTER COLUMN cod_prod SET NOT NULL;

A restrio ser verificada imediatamente, portanto os dados da tabela devem satisfazer a


restrio para esta poder ser adicionada.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 57


POSTGRESQL Banco de dados SQL

Remover restrio
Para remover uma restrio necessrio conhecer seu nome. Se foi atribudo um nome
restrio fcil, caso contrrio o sistema atribui restrio um nome gerado que precisa ser
descoberto. O comando \d nome_da_tabela do psql pode ser til nesta situao; outras interfaces
tambm podem oferecer uma forma de inspecionar os detalhes das tabelas. O comando utilizado
para remover restrio :

ALTER TABLE produtos


DROP CONSTRAINT nome_da_restrio;

Da mesma forma que para remover uma coluna, necessrio adicionar CASCADE se for desejado
remover uma restrio que outro objeto dependa. Um exemplo a restrio de chave
estrangeira, que depende da restrio de unicidade ou de chave primria nas colunas
referenciadas.
Esta sintaxe serve igualmente para todos os tipos de restrio, exceto no-nulo. Para remover
uma restrio de no-nulo, utiliza-se:

ALTER TABLE produtos


ALTER COLUMN cod_prod DROP NOT NULL;

Evolutiontech Treinamento e Desenvolvimento P g i n a | 58


POSTGRESQL Banco de dados SQL

Mudar valor padro da coluna

Para definir um novo valor padro para a coluna, utiliza-se:

ALTER TABLE produtos


ALTER COLUMN preco SET DEFAULT 7.77;

Deve ser observado que este comando no afeta nenhuma coluna existente na tabela, apenas
muda o valor padro para os prximos comandos INSERT.
Para remover o valor padro para a coluna, utiliza-se:

ALTER TABLE produtos


ALTER COLUMN preco DROP DEFAULT;

Efetivamente o mesmo que definir o valor nulo como sendo o valor padro. Como
conseqncia, no errado remover um valor padro que no tenha sido definido, porque
implicitamente o valor nulo o valor padro.

Mudar o tipo de dado da coluna

Para converter a coluna em um tipo de dado diferente, utiliza-se:

ALTER TABLE produtos


ALTER COLUMN preco TYPE numeric(10,2);

Este comando somente ser bem-sucedido se todas as entradas existentes na coluna puderem ser
convertidas para o novo tipo atravs de uma converso implcita. Se for necessria uma
converso mais complexa, pode ser adicionada a clusula USING especificando como calcular os
novos valores a partir dos antigos.
O PostgreSQL tenta converter o valor padro da coluna (se houver) para o novo tipo, assim bem
como todas as restries que envolvem a coluna. Mas estas converses podem falhar, ou podem
produzir resultados surpreendentes. Geralmente melhor remover todas as restries da coluna
antes de alterar o seu tipo, e depois adicionar novamente estas restries modificadas de forma
apropriada.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 59


POSTGRESQL Banco de dados SQL

Mudar nome de coluna

Para mudar o nome de uma coluna, utiliza-se:

ALTER TABLE produtos


RENAME COLUMN cod_prod TO cod_produto;

Mudar nome de tabela

Para mudar o nome de uma tabela, utiliza-se:

ALTER TABLE produtos


RENAME TO equipamentos;

Privilgios
Quem cria o objeto no banco de dados se torna o seu dono. Por padro, apenas o dono do objeto
pode fazer qualquer coisa com o objeto. Para permitir outros usurios utilizarem o objeto, devem
ser concedidos privilgios (entretanto, os usurios que possuem o atributo de superusurio
sempre podem acessar qualquer objeto).

Existem vrios privilgios diferentes: SELECT, INSERT, UPDATE, DELETE, RULE, REFERENCES,
TRIGGER, CREATE, TEMPORARY, EXECUTE e USAGE. Os privilgios aplicveis a um determinado tipo
de objeto variam de acordo com o tipo do objeto (tabela, funo, etc.). Para obter informaes
completas sobre os diferentes tipos de privilgio suportados pelo PostgreSQL, deve ser consultada
a pgina de referncia do comando GRANT. As prximas sees e captulos tambm mostram
como os privilgios so utilizados.
O direito de modificar e destruir um objeto so sempre privilgios exclusivos do seu criador.

Para conceder privilgios utiliza-se o comando GRANT. Por exemplo, se joel for um usurio
existente, e contas for uma tabela existente, o privilgio de poder atualizar esta tabela pode ser
concedido por meio do comando:

GRANT UPDATE ON tab_contas TO joel;

Para conceder o privilgio para um grupo utilizada a sintaxe:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 60


POSTGRESQL Banco de dados SQL

GRANT SELECT ON contas TO GROUP contabilidade;

O nome especial de usurio PUBLIC pode ser utilizado para conceder privilgios para todos os
usurios do sistema.
Escrever ALL no lugar do nome especfico do privilgio concede todos os privilgios relevantes
para o tipo do objeto.
Para revogar um privilgio utiliza-se o comando REVOKE:

REVOKE ALL ON contas FROM PUBLIC;

Os privilgios especiais do dono da tabela (ou seja, os direitos de DROP, GRANT, REVOKE, etc.) so
sempre inerentes condio de ser o dono, no podendo ser concedidos ou revogados. Porm, o
dono do objeto pode decidir revogar seus prprios privilgios comuns como, por exemplo, tornar
a tabela somente para leitura para o prprio, assim como para os outros.
Normalmente, somente o dono do objeto (ou um superusurio) pode conceder ou revogar
privilgios para um objeto. Entretanto, possvel conceder um privilgio com a opo de
concesso, o que d a quem recebe o direito de conceder o privilgio para outros. Se mais tarde
esta opo de concesso for revogada, ento todos aqueles que receberam o privilgio a partir
desta pessoa (diretamente ou atravs de uma cadeia de concesses), perdem este privilgio. Para
obter mais detalhes consulte as pginas de referncia dos comandos GRANT e REVOKE.

Esquemas
Um agrupamento de bancos de dados do PostgreSQL contm um ou mais bancos de dados com
nome. Os usurios e os grupos de usurios so compartilhados por todo o agrupamento, mas
nenhum outro dado compartilhado entre os bancos de dados. Todas as conexes dos clientes
com o servidor podem acessar somente os dados de um nico banco de dados, quele que foi
especificado no pedido de conexo.

Um banco de dados contm um ou mais esquemas com nome, os quais por sua vez contm
tabelas. Os esquemas tambm contm outros tipos de objetos com nome, incluindo tipos de
dado, funes e operadores. O mesmo nome de objeto pode ser utilizado em esquemas
diferentes sem conflito; por exemplo, tanto o esquema_1 quanto o meu_esquema podem conter
uma tabela chamada minha_tabela. Diferentemente dos bancos de dados, os esquemas no so
separados rigidamente: um usurio pode acessar objetos de vrios esquemas no banco de dados
em que est conectado, caso possua os privilgios necessrios para faz-lo.
Existem diversas razes pelas quais pode-se desejar utilizar esquemas:

Para permitir vrios usurios utilizarem o mesmo banco de dados sem que um interfira com
o outro.
Para organizar objetos do banco de dados em grupos lgicos tornando-os mais
gerenciveis.
Os aplicativos desenvolvidos por terceiros podem ser colocados em esquemas separados,
para no haver coliso com nomes de outros objetos.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 61


POSTGRESQL Banco de dados SQL

Os esquemas so anlogos a diretrios no nvel do sistema operacional, exceto que os esquemas


no podem ser aninhados.

Criao de esquema
Para criar um esquema utiliza-se o comando CREATE SCHEMA. O nome do esquema escolhido
livremente pelo usurio.
Por exemplo:

CREATE SCHEMA meu_esquema;


Para criar ou acessar objetos em um esquema deve ser escrito um nome qualificado, formado

pelo nome do esquema e pelo nome da tabela separados por um ponto:

nome_do_esquema.nome_da_tabela

Esta forma funciona em qualquer local onde esperado o nome de uma tabela, inclusive nos
comandos de modificao de tabela e nos comandos de acesso a dado mostrados nos prximos
captulos (Para abreviar falaremos apenas das tabelas, mas a mesma idia se aplica a outros tipos
de objetos com nome, tais como tipos e funes). Na verdade, tambm pode ser utilizada a
sintaxe mais geral:

nome_do_banco_de_dados.nome_do_esquema.nome_da_tabela

mas atualmente apenas uma conformidade pr-forma com o padro SQL; se for escrito o nome
do banco de dados, este dever ter o mesmo nome do banco de dados que se est conectado.
Portanto, para criar uma tabela no novo esquema utiliza-se:

CREATE TABLE meu_esquema.minha_tabela ( ... );

Evolutiontech Treinamento e Desenvolvimento P g i n a | 62


POSTGRESQL Banco de dados SQL

Para remover um esquema vazio (todos os seus objetos j foram removidos), utiliza-se:

DROP SCHEMA meu_esquema;

Para remover um esquema junto com todos os objetos que este contm, utiliza-se:

DROP SCHEMA meu_esquema CASCADE;

O esquema pblico

Nas sees anteriores foram criadas tabelas sem que fosse especificado nenhum nome de
esquema. Por padro, estas tabelas (e outros objetos) so colocadas automaticamente no
esquema chamado public. Todo banco de dados novo possui este esquema.

Portanto, as duas formas abaixo so equivalentes:

CREATE TABLE produtos ( ... );

e
CREATE TABLE public.produtos ( ... );

Esquemas e privilgios
Por padro, os usurios no podem acessar objetos em esquemas que no so seus. Para
poderem acessar, o dono do esquema precisa conceder o privilgio USAGE para o esquema. Para
permitir os usurios utilizarem os objetos do esquema necessrio conceder privilgios
adicionais, conforme seja apropriado para cada objeto.
Pode ser permitido, tambm, que um usurio crie objetos no esquema de outro usurio. Para
permitir que isto seja feito, deve ser concedido o privilgio CREATE para o esquema. Deve ser
observado que, por padro, todos os usurios possuem o privilgio CREATE e USAGE para o
esquema public. Isto permite a todos os usurios que podem se conectar ao banco de dados
criar objetos no esquema public. Se isto no for desejado, este privilgio pode ser revogado:
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

O primeiro public acima o nome do esquema, enquanto o segundo public significa todos
os usurios. Na primeira ocorrncia um identificador, enquanto na segunda ocorrncia uma
palavra chave; por isso, na primeira vez est escrito em minsculas enquanto na segunda vez est
em maisculas; lembre-se da conveno da Seo 4.1.1.

5.8.5. O esquema do catlogo do sistema

Alm do esquema public e dos esquemas criados pelos usurios, cada banco de dados contm o
esquema pg_catalog, contendo as tabelas do sistema e todos os tipos de dado, funes e

Evolutiontech Treinamento e Desenvolvimento P g i n a | 63


POSTGRESQL Banco de dados SQL

operadores nativos. O pg_catalog sempre parte efetiva do caminho de procura. Se no for


colocado explicitamente no caminho de procura, ento implicitamente procurado antes dos
esquemas do caminho de procura. Isto garante que os nomes nativos sempre podem ser
encontrados. Entretanto, possvel colocar explicitamente o pg_catalog no final do caminho de
procura, se for desejado que os nomes definidos pelo usurio substituam os nomes nativos.
Nas verses do PostgreSQL anteriores a 7.3, os nomes de tabela comeando por pg_ eram
reservados. Isto no mais verdade: podem ser criadas tabelas com este nome, se for desejado,
em qualquer esquema que no seja o do sistema. Entretanto, melhor continuar evitando estes
nomes, para garantir que no haver conflito caso alguma verso futura defina uma tabela do
sistema com o mesmo nome da tabela criada (com o caminho de procura padro, uma referncia
no qualificada tabela criada ser resolvida com a tabela do sistema). As tabelas do sistema vo
continuar seguindo a conveno de possuir nomes comeando por pg_, no conflitando com os
nomes no qualificados das tabelas dos usurios, desde que os usurios evitem utilizar o prefixo
pg_.

Acompanhando as Dependncias
Ao se criar uma estrutura de banco de dados complexa, envolvendo muitas tabelas com restries
de chave estrangeira, vises, gatilhos, funes, etc., cria-se, implicitamente, uma rede de
dependncias entre os objetos. Por exemplo, uma tabela com uma restrio de chave estrangeira
depende da tabela referenciada.
Para garantir a integridade de toda a estrutura do banco de dados, o PostgreSQL no permite
remover um objeto quando h objetos que dependem do mesmo. Por exemplo, tentar remover a
tabela produtos, conforme declarada na Seo 5.3.5 onde a tabela pedidos depende dela,
produz uma mensagem de erro como esta:

DROP TABLE produtos;

NOTA: a restrio pedidos_cod_prod_fkey na tabela pedidos depende da tabela produtos


ERRO: no foi possvel remover a tabela produtos porque outros objetos dependem da mesma
DICA: Use DROP ... CASCADE para remover os objetos dependentes tambm.

A mensagem de erro mostra uma dica til: Se no tem importncia


remover todos os objetos dependentes, ento pode ser executado

DROP TABLE produtos CASCADE;

e todos os objetos dependentes sero removidos.


Neste caso no ser removida a tabela pedidos, ser removida apenas a restrio de chave
estrangeira (caso se deseje verificar o que DROP ... CASCADE far, deve ser executado o
comando DROP sem o CASCADE).
Todos os comandos de remoo do PostgreSQL permitem especificar CASCADE. Obviamente, a
natureza das dependncias possveis varia conforme o tipo do objeto. Pode ser escrito RESTRICT

Evolutiontech Treinamento e Desenvolvimento P g i n a | 64


POSTGRESQL Banco de dados SQL

em vez de CASCADE, para obter o comportamento padro que impedir a remoo do objeto
quando existem objetos que dependem do mesmo.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 65


POSTGRESQL Banco de dados SQL

Manipulao de dados
O captulo anterior mostrou como criar tabelas e outras estruturas para armazenar dados. Agora
est na hora de preencher as tabelas com dados. Este captulo mostra como inserir, atualizar e
excluir dados em tabelas. Tambm so apresentadas maneiras de efetuar mudanas automticas
nos dados quando ocorrem certos eventos: gatilhos (triggers) e regras de reescrita (rewrite rules).
Para completar, o prximo captulo explica como fazer consultas para extrair dados do banco de
dados.

Insero de dados (INSERT)


A tabela recm-criada no contm dados. A primeira ao a ser realizada para o banco de dados
ter utilidade inserir dados. Conceitualmente, os dados so inseridos uma linha de cada vez.
claro que possvel inserir mais de uma linha, mas no existe maneira de inserir menos de uma
linha por vez. Mesmo que se conhea apenas o valor de algumas colunas, deve ser criada uma
linha completa.
Para criar uma linha utilizado o comando INSERT. Este comando requer o nome da tabela, e um
valor para cada coluna da tabela.

Exemplo:

CREATE TABLE produtos (


cod_prod integer,
nome text,
preco numeric );

Um exemplo de comando para inserir uma linha :

INSERT INTO produtos VALUES (1, 'Queijo', 9.99);

Os valores dos dados so colocados na mesma ordem que as colunas se encontram na tabela,
separados por vrgula. Geralmente os valores dos dados so literais (constantes), mas tambm
so permitidas expresses escalares.
A sintaxe mostrada acima tem como desvantagem ser necessrio conhecer a ordem das colunas
da tabela. Para evitar isto, as colunas podem ser relacionadas explicitamente. Por exemplo, os
dois comandos mostrados abaixo possuem o mesmo efeito do comando mostrado acima:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 66


POSTGRESQL Banco de dados SQL

INSERT INTO produtos (cod_prod, nome, preco)


VALUES (1, 'Queijo', 9.99);

INSERT INTO produtos (nome, preco, cod_prod)


VALUES ('Queijo', 9.99, 1);

Muitos usurios consideram boa prtica escrever sempre os nomes das colunas.
Se no forem conhecidos os valores de todas as colunas, as colunas com valor desconhecido
podem ser omitidas. Neste caso, estas colunas so preenchidas com seu respectivo valor padro.
Por exemplo:

INSERT INTO produtos (cod_prod, nome) VALUES (1, 'Queijo');


INSERT INTO produtos VALUES (1, 'Queijo');

A segunda forma uma extenso do PostgreSQL, que preenche as colunas a partir da esquerda
com quantos valores forem fornecidos, e as demais com o valor padro.
Para ficar mais claro, pode ser requisitado explicitamente o valor padro da coluna
individualmente, ou para toda a linha:

INSERT INTO produtos (cod_prod, nome, preco)


VALUES (1, 'Queijo', DEFAULT);

Atualizao de dados (UPDATE)


A modificao dos dados armazenados no banco de dados referida como atualizao. Pode ser
atualizada uma linha, todas as linhas, ou um subconjunto das linhas da tabela. Uma coluna pode
ser atualizada separadamente; as outras colunas no so afetadas.

Para realizar uma atualizao so necessrias trs informaes:

nome da tabela e da coluna a ser atualizada;


novo valor para a coluna;
Quais linhas sero atualizadas.

Lembre-se que foi dito no Captulo 5 que o SQL, de uma maneira geral, no fornece um
identificador nico para as linhas. Portanto, no necessariamente possvel especificar
diretamente a linha a ser atualizada. Em vez disso, devem ser especificadas as condies que a
linha deve atender para ser atualizada. Somente havendo uma chave primria na tabela (no

Evolutiontech Treinamento e Desenvolvimento P g i n a | 67


POSTGRESQL Banco de dados SQL

importando se foi declarada ou no), possvel enderear uma linha especfica com confiana,
escolhendo uma condio correspondendo chave primria. Ferramentas grficas de acesso a
banco de dados dependem da chave primria para poderem atualizar as linhas individualmente.
Por exemplo, o comando mostrado abaixo atualiza todos os produtos com preo igual a 5,
mudando estes preos para 10:

UPDATE produtos SET preco = 10 WHERE preco = 5;

Este comando pode atualizar nenhuma, uma, ou muitas linhas. No errado tentar uma
atualizao que no corresponda a nenhuma linha.
Vejamos este comando em detalhe: Primeiro aparece a palavra chave UPDATE seguida pelo nome
da tabela. Como usual, o nome da tabela pode ser qualificado pelo esquema, seno procurado
no caminho. Depois aparece a palavra chave SET, seguida pelo nome da coluna, por um sinal de
igual, e pelo novo valor da coluna. O novo valor da coluna pode ser qualquer expresso escalar, e
no apenas uma constante. Por exemplo, se for desejado aumentar o preo de todos os produtos
em 10% pode ser utilizado:

UPDATE produtos SET preco = preco * 1.10;

Como pode ser visto, a expresso para obter o novo valor pode fazer referncia ao valor antigo.
Tambm foi deixada de fora a clusula WHERE. Quando esta clusula omitida, significa que todas
as linhas da tabela sero atualizadas e, quando est presente, somente as linhas que atendem
condio desta clusula sero atualizadas. Deve ser observado que o sinal de igual na clusula SET
uma atribuio, enquanto o sinal de igual na clusula WHERE uma comparao, mas isto no
cria uma ambigidade. Obviamente, a condio da clusula WHERE no necessariamente um
teste de igualdade, esto disponveis vrios outros operadores (consulte o Captulo 9), mas a
expresso deve produzir um resultado booleano.
Tambm pode ser atualizada mais de uma coluna pelo comando UPDATE, colocando mais de uma
atribuio na clusula SET. Por exemplo:

UPDATE minha_tabela SET a = 5, b = 3, c = 1 WHERE a > 0;

Excluso de dados (DELETE)


At aqui foi mostrado como adicionar dados a tabelas, e como modificar estes dados. Est
faltando mostrar como remover os dados que no so mais necessrios. Assim como s possvel
adicionar dados para toda uma linha, uma linha tambm s pode ser removida por inteiro da
tabela. Na seo anterior foi explicado que o SQL no fornece uma maneira para enderear
diretamente uma determinada linha. Portanto, a remoo das linhas s pode ser feita
especificando as condies que as linhas a serem removidas devem atender. Havendo uma chave
primria na tabela, ento possvel especificar exatamente a linha. Mas tambm pode ser

Evolutiontech Treinamento e Desenvolvimento P g i n a | 68


POSTGRESQL Banco de dados SQL

removido um grupo de linhas atendendo a uma determinada condio, ou podem ser removidas
todas as linhas da tabela de uma s vez.
utilizado o comando DELETE para remover linhas; a sintaxe deste comando muito semelhante
a do comando UPDATE. Por exemplo, para remover todas as linhas da tabela produtos possuindo
preo igual a 10:

DELETE FROM produtos WHERE preco = 10;

Se for escrito simplesmente

DELETE FROM produtos;

Todas as linhas da tabela sero excludas!

Evolutiontech Treinamento e Desenvolvimento P g i n a | 69


POSTGRESQL Banco de dados SQL

Consultas (SELECT)
Os captulos anteriores explicaram como criar tabelas, como preench-las com dados, e como
manipular estes dados. Agora, finalmente, mostrado como trazer estes dados para fora do
banco de dados.
O processo de trazer, ou o comando para trazer os dados armazenados no banco de dados,
chamado de consulta. No SQL, o comando SELECT utilizado para especificar consultas. A
sintaxe geral do comando SELECT :

SELECT lista_de_seleo
FROM expresso_de_tabela [especificao_da_ordenao]

As prximas sees descrevem em detalhes a lista de seleo, a expresso de tabela, e a


especificao da ordenao.
O tipo mais simples de consulta possui a forma:

SELECT * FROM tabela1;

Supondo existir uma tabela chamada tabela1, este comando traz todas as linhas e todas as
colunas da tabela1. A forma de trazer depende do aplicativo cliente. Por exemplo, o aplicativo
psql exibe uma tabela ASCII formatada na tela, enquanto as bibliotecas cliente disponibilizam
funes para extrair valores individuais do resultado da consulta. A especificao da lista de
seleo * significa todas as colunas que a expresso de tabela possa fornecer. A lista de seleo
tambm pode selecionar um subconjunto das colunas disponveis, ou efetuar clculos utilizando
as colunas. Por exemplo, se a tabela1 possui colunas chamadas a, b e c (e talvez outras), pode ser
feita a seguinte consulta:

SELECT a, b, c FROM tabela1;

FROM tabela1 um tipo particularmente simples de expresso de tabela: l apenas uma nica
tabela. De uma forma geral, as expresses de tabela podem ser construes complexas contendo
tabelas base, junes e subconsultas. Mas a expresso de tabela pode ser totalmente omitida,
quando se deseja utilizar o comando SELECT como uma calculadora:

SELECT 3 * 4;

mais til quando as expresses da lista de seleo retornam resultados variveis. Por exemplo,
uma funo pode ser chamada deste modo:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 70


POSTGRESQL Banco de dados SQL

SELECT random();

A clusula FROM

A Clusula FROM deriva uma tabela a partir de uma ou mais tabelas especificadas na lista,
separada por vrgulas, de referncias a tabela.
FROM referncia_a_tabela [, referncia_a_tabela [, ...]]

Uma referncia a tabela pode ser um nome de tabela (possivelmente qualificado pelo esquema)
ou uma tabela derivada, como uma subconsulta, uma juno de tabelas ou, ainda, uma
combinao complexa destas. Se for listada mais de uma referncia a tabela na clusula FROM,
feita uma juno cruzada (cross-join) (veja abaixo) para formar a tabela virtual intermediria
que poder, ento, estar sujeita s transformaes das clusulas WHERE, GROUP BY e HAVING,
gerando o resultado final de toda a expresso de tabela.

Quando uma referncia a tabela especifica uma tabela ancestral em uma hierarquia de herana
de tabelas, a referncia a tabela no produz linhas apenas desta tabela, mas inclui as linhas de
todas as tabelas descendentes, a no ser que a palavra chave ONLY preceda o nome da tabela.
Entretanto, esta referncia produz apenas as colunas existentes na tabela especificada so
ignoradas todas as colunas adicionadas s tabelas descendentes.

Juno de tabelas (JOIN)


Uma tabela juntada uma tabela derivada de outras duas tabelas (reais ou derivadas), de acordo
com as regras do tipo particular de juno. Esto disponveis as junes internas, externas e
cruzadas.

Tipos de juno

Juno cruzada
T1 CROSS JOIN T2

Para cada combinao de linhas de T1 e T2, a tabela derivada contm uma linha formada por
todas as colunas de T1 seguidas por todas as colunas de T2. Se as tabelas possurem N e M
linhas, respectivamente, a tabela juntada ter N * M linhas.
FROM T1 CROSS JOIN T2 equivale a FROM T1, T2. Tambm equivale a FROM T1 INNER JOIN
T2 ON TRUE
(veja abaixo).

Evolutiontech Treinamento e Desenvolvimento P g i n a | 71


POSTGRESQL Banco de dados SQL

Junes qualificadas
As palavras INNER e OUTER so opcionais em todas as formas. INNER o padro; LEFT, RIGHT
e FULL implicam em juno externa.
A condio de juno especificada na clusula ON ou USING, ou implicitamente pela palavra
NATURAL. A condio de juno determina quais linhas das duas tabelas de origem so
consideradas correspondentes, conforme explicado detalhadamente abaixo.
A clusula ON o tipo mais geral de condio de juno: recebe uma expresso de valor
booleana do mesmo tipo utilizado na clusula WHERE. Um par de linhas de T1 e T2 so
correspondentes se a expresso da clusula ON for avaliado como verdade para este par de
linhas.
USING uma notao abreviada: recebe uma lista de nomes de colunas, separados por
vrgula, que as tabelas juntadas devem possuir em comum, e forma a condio de juno
especificando a igualdade de cada par destas colunas. Alm disso, a sada de JOIN USING
possui apenas uma coluna para cada par da igualdade de colunas da entrada, seguidas por
todas as outras colunas de cada tabela. Portanto, USING (a, b, c) equivale a ON (t1.a =
t2.a AND t1.b = t2.b AND t1.c = t2.c), mas quando ON utilizado existem duas
colunas a, b e c no resultado, enquanto usando USING existe apenas uma de cada.
Finalizando, NATURAL uma forma abreviada de USING: gera uma lista USING formada pelas
colunas cujos nomes aparecem nas duas tabelas de entrada. Assim como no USING, estas
colunas aparecem somente uma vez na tabela de sada.
Os tipos possveis de juno qualificada so:

INNER JOIN
Para cada linha L1 de T1, a tabela juntada possui uma linha para cada linha de T2 que
satisfaz a condio de juno com L1.

LEFT OUTER JOIN


Primeiro, realizada uma juno interna. Depois, para cada linha de T1 que no satisfaz
a condio de juno com nenhuma linha de T2, adicionada uma linha juntada com
valores nulos nas colunas de T2. Portanto, a tabela juntada possui, incondicionalmente,
no mnimo uma linha para cada linha de T1.

RIGHT OUTER JOIN


Primeiro, realizada uma juno interna. Depois, para cada linha de T2 que no satisfaz
a condio de juno com nenhuma linha de T1, adicionada uma linha juntada com
valores nulos nas colunas de T1. o oposto da juno esquerda: a tabela resultante
possui, incondicionalmente, uma linha para cada linha de T2.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 72


POSTGRESQL Banco de dados SQL

FULL OUTER JOIN


Primeiro, realizada uma juno interna. Depois, para cada linha de T1 que no satisfaz
a condio de juno com nenhuma linha de T2, adicionada uma linha juntada com
valores nulos nas colunas de T2. Tambm, para cada linha de T2 que no satisfaz a
condio de juno com nenhuma linha de T1, adicionada uma linha juntada com
valores nulos nas colunas de T1.
As junes de todos os tipos podem ser encadeadas ou aninhadas: tanto T1 como T2, ou ambas,
podem ser tabelas juntadas. Podem colocados parnteses em torno das clusulas JOIN para
controlar a ordem de juno. Na ausncia de parnteses, as clusulas JOIN so aninhadas da
esquerda para a direita.

Para reunir tudo isto, vamos supor que temos as tabelas t1

num | nome
-----+------
1 | a
2 | b
3 | c

e t2

num | valor
-----+-------
1 | xxx
3 | yyy
5 | zzz

e mostrar os resultados para vrios tipos de juno:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 73


POSTGRESQL Banco de dados SQL

SELECT * FROM t1 CROSS JOIN t2;

num | nome | num | valor


-----+------+-----+-------
1 | a | 1 | xxx
1 | a | 3 | yyy
1 | a | 5 | zzz
2 | b | 1 | xxx
2 | b | 3 | yyy
2 | b | 5 | zzz
3 | c | 1 | xxx
3 | c | 3 | yyy
3 | c | 5 | zzz
(9 linhas)

SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;


num | nome | num | valor
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 3 | yyy
(2 linhas)

SELECT * FROM t1 INNER JOIN t2 USING (num);


num | nome | valor
-----+------+-------
1 | a | xxx
3 | c | yyy
(2 linhas)

SELECT * FROM t1 NATURAL INNER JOIN t2;


num | nome | valor
-----+------+-------
1 | a | xxx
3 | c | yyy
linhas)

A Tabela 7-1 mostra os tipos de juno suportados pelos gerenciadores de banco de dados
PostgreSQL, SQL Server, Oracle e DB2.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 74


POSTGRESQL Banco de dados SQL

Tabela 7-1. Tipos de juno no PostgreSQL, no SQL Server, no Oracle e no DB2

Tipo de juno PostgreSQL 8.0.0 SQL Server 2000 Oracle 10g DB2 8.1

INNER JOIN ON sim sim sim sim

LEFT OUTER JOIN sim sim sim sim


ON

RIGHT OUTER sim sim sim sim


JOIN ON

FULL OUTER JOIN sim sim sim sim


ON

INNER JOIN USING sim no sim no

CROSS JOIN sim sim sim no

NATURAL JOIN sim no sim no

Aliases de tabela e de coluna


Pode ser dado um nome temporrio s tabelas, e s referncias a tabela complexas, para ser
usado nas referncias tabela derivada no restante do comando. Isto chamado de alis de
tabela. 2 3
Para criar um alis de tabela, escreve-se FROM referncia_a_tabela AS alis

ou
FROM referncia_a_tabela alis

A palavra chave AS opcional. O alis pode ser qualquer identificador.


Uma utilizao tpica de alis de tabela para atribuir identificadores curtos a nomes de tabelas
longos, para manter a clusula de juno legvel. Por exemplo:

SELECT * FROM
um_nome_muito_comprido u
JOIN outro_nome_muito_comprido o
ON u.id = o.num;

Evolutiontech Treinamento e Desenvolvimento P g i n a | 75


POSTGRESQL Banco de dados SQL

O alis se torna o novo nome da referncia tabela na consulta corrente no mais possvel
fazer referncia tabela pelo seu nome original. Portanto,

SELECT * FROM minha_tabela AS m


WHERE minha_tabela.a > 5;

no uma sintaxe SQL vlida!

A clusula WHERE
A sintaxe da Clusula WHERE WHERE condio_de_pesquisa

onde a condio_de_pesquisa qualquer expresso de valor (consulte a Seo 4.2) que retorne
um valor do tipo boolean.
Aps o processamento da clusula FROM ter sido feito, cada linha da tabela virtual derivada
verificada com relao condio de pesquisa. Se o resultado da condio for verdade, a linha
mantida na tabela de sada, seno (ou seja, se o resultado for falso ou nulo) a linha desprezada.
Normalmente a condio de pesquisa faz referncia a pelo menos uma coluna da tabela gerada
pela clusula FROM; embora isto no seja requerido, se no for assim a clusula WHERE no ter
utilidade.
Nota: A condio de juno de uma juno interna pode ser escrita tanto na clusula WHERE quanto na

Abaixo esto mostrados alguns exemplos de clusulas WHERE:

SELECT ... FROM fdt WHERE c1 > 5


SELECT ... FROM fdt WHERE c1 IN (1, 2, 3)
SELECT ... FROM fdt WHERE c1 IN (SELECT c1 FROM t2)

SELECT ... FROM fdt WHERE c1


IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10)

SELECT ... FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 =


fdt.c1 + 10) AND 100

SELECT ... FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1)

sendo que fdt a tabela derivada da clusula FROM. As linhas que no aderem condio de
pesquisa da clusula WHERE so eliminadas de fdt. Deve ser observada a utilizao de
subconsultas escalares como expresses de valor. Assim como qualquer outra consulta, as
subconsultas podem utilizar expresses de tabela complexas. Deve ser observado, tambm, como

Evolutiontech Treinamento e Desenvolvimento P g i n a | 76


POSTGRESQL Banco de dados SQL

fdt referenciada nas subconsultas. A qualificao de c1 como fdt.c1 somente necessria se


c1 tambm for o nome de uma coluna na tabela de entrada derivada da subconsulta. Entretanto,
a qualificao do nome da coluna torna mais clara a consulta, mesmo quando no necessria.
Este exemplo mostra como o escopo do nome da coluna de uma consulta externa se estende s
suas consultas internas.

As clusulas GROUP BY e HAVING

Aps passar pelo filtro WHERE, a tabela de entrada derivada pode estar sujeita ao agrupamento,
utilizando a clusula GROUP BY, e eliminao de grupos de linhas, utilizando a clusula HAVING.
SELECT lista_de_seleo FROM ...
[WHERE ...]
GROUP BY referncia_a_coluna_de_agrupamento
[, referncia_a_coluna_de_agrupamento]...

A Clusula GROUP BY utilizada para agrupar linhas da tabela que compartilham os mesmos
valores em todas as colunas da lista. Em que ordem as colunas so listadas no faz diferena. O
efeito combinar cada conjunto de linhas que compartilham valores comuns em uma linha de
grupo que representa todas as linhas do grupo. Isto feito para eliminar redundncia na sada,
e/ou para calcular agregaes aplicveis a estes grupos. Por exemplo:
SELECT * FROM teste1;
x | y
--+---
a | 3
c | 2
b | 5
a | 1
(4 linhas)

SELECT x FROM teste1 GROUP BY x;


x
--
a
b
c
(3 linhas)

Na segunda consulta no poderia ser escrito SELECT * FROM teste1 GROUP BY x, porque no
existe um valor nico da coluna y que poderia ser associado com cada grupo. As colunas
agrupadas podem ser referenciadas na lista de seleo, desde que possuam um valor nico em
cada grupo.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 77


POSTGRESQL Banco de dados SQL

De modo geral, se uma tabela for agrupada as colunas que no so usadas nos agrupamentos no
podem ser referenciadas, exceto nas expresses de agregao. Um exemplo de expresso de
agregao :

SELECT x, sum(y)
FROM teste1 GROUP BY x;
x | sum
--+-----
a | 4
b | 5
c | 2
(3 linhas)

Aqui sum() a funo de agregao que calcula um valor nico para o grupo todo. Mais
informaes sobre as funes de agregao disponveis podem ser encontradas na Seo 9.15.

Abaixo est mostrado um outro exemplo: clculo do total das vendas de cada produto (e no o
total das vendas de todos os produtos).

SELECT cod_prod, p.nome,


(sum(v.unidades) * p.preco) AS vendas
FROM produtos p LEFT JOIN vendas v USING (cod_prod)
GROUP BY cod_prod, p.nome, p.preco;

Neste exemplo, as colunas cod_prod, p.nome e p.preco devem estar na clusula GROUP BY,
porque so referenciadas na lista de seleo da consulta (dependendo da forma exata como a
tabela produtos for definida, as colunas nome e preo podem ser totalmente dependentes da
coluna cod_prod, tornando os agrupamentos adicionais teoricamente desnecessrios, mas isto
ainda no est implementado). A coluna v.unidades no precisa estar na lista do GROUP BY,
porque usada apenas na expresso de agregao (sum(...)), que representa as vendas do
produto. Para cada produto, a consulta retorna uma linha sumarizando todas as vendas do
produto.
No SQL estrito, a clusula GROUP BY somente pode agrupar pelas colunas da tabela de origem,
mas o PostgreSQL estende esta funcionalidade para permitir o GROUP BY agrupar pelas colunas da
lista de seleo. O agrupamento por expresses de valor, em vez de nomes simples de colunas,
tambm permitido.
Se uma tabela for agrupada utilizando a clusula GROUP BY, mas houver interesse em alguns
grupos apenas, pode ser utilizada a clusula HAVING, de forma parecida com a clusula WHERE,
para eliminar grupos da tabela agrupada. A sintaxe :
SELECT lista_de_seleo FROM ... [WHERE ...] GROUP BY ... HAVING expresso_booleana

As expresses na clusula HAVING podem fazer referncia tanto a expresses agrupadas quanto a
no agrupadas (as quais necessariamente envolvem uma funo de agregao).

Evolutiontech Treinamento e Desenvolvimento P g i n a | 78


POSTGRESQL Banco de dados SQL

Exemplo:

SELECT x, sum(y) FROM teste1 GROUP BY x HAVING sum(y) > 3;

x | sum
--+-----
a | 4
b | 5
(2 linhas)

SELECT x, sum(y) FROM teste1 GROUP BY x HAVING x < 'c';

x | sum
--+-----
a | 4
b | 5
(2 linhas)

Evolutiontech Treinamento e Desenvolvimento P g i n a | 79


POSTGRESQL Banco de dados SQL

Agora vamos fazer um exemplo mais prximo da realidade:

SELECT cod_prod, p.nome,


(sum(v.unidades) * (p.preco - p.custo)) AS lucro
FROM produtos p LEFT JOIN vendas v USING (cod_prod)
WHERE v.data > CURRENT_DATE - INTERVAL '4 weeks'
GROUP BY cod_prod, p.nome, p.preco, p.custo
HAVING sum(p.preco * v.unidades) > 5000;

No exemplo acima, a clusula WHERE est selecionando linhas por uma coluna que no agrupada
(a expresso somente verdadeira para as vendas feitas nas quatro ltimas semanas, enquanto a
clusula HAVING restringe a sada aos grupos com um total de vendas brutas acima de 5000. Deve
ser observado que as expresses de agregao no precisam ser necessariamente as mesmas em
todas as partes da consulta.

Utilizao de HAVING sem GROUP BY no SELECT


O exemplo abaixo mostra a utilizao da clusula HAVING sem a clusula GROUP BY no comando
SELECT. criada a tabela produtos e so inseridas cinco linhas. Quando a clusula HAVING exige a
presena de mais de cinco linhas na tabela, a consulta no retorna nenhuma linha.

create table produtos(codigo int, valor float);

insert into produtos values (1, 102);


insert into produtos values (2, 104);
insert into produtos values (3, 202);
insert into produtos values (4, 203);
insert into produtos values (5, 204);

Evolutiontech Treinamento e Desenvolvimento P g i n a | 80


POSTGRESQL Banco de dados SQL

select avg(valor) from produtos;


avg
-----
163
(1 linha)

select avg(valor) from produtos having count(*) >= 5;


avg
---
163
(1 linha)

select avg(valor) from produtos having count(*)=5;


avg
---
163
(1 linha)

select avg(valor) from produtos having count(*)>5;


avg
---
(0 linhas)

Evolutiontech Treinamento e Desenvolvimento P g i n a | 81


POSTGRESQL Banco de dados SQL

Utilizao da expresso CASE para agrupar valores


A expresso CASE pode fazer parte da lista de agrupamento. Este exemplo usa a expresso CASE
para agrupar as notas dos alunos em conceitos, e calcular a nota mnima, mxima e mdia, alm
da quantidade de notas, correspondente a cada conceito. Abaixo est mostrado o script utilizado:

CREATE TABLE notas (


nota decimal(4,2) CONSTRAINT chknota
CHECK (nota BETWEEN 0.00 AND 10.00) );

INSERT INTO notas VALUES(10);


INSERT INTO notas VALUES(9.2);
INSERT INTO notas VALUES(9.0);
INSERT INTO notas VALUES(8.3);
INSERT INTO notas VALUES(7.7);
INSERT INTO notas VALUES(7.4);
INSERT INTO notas VALUES(6.4);
INSERT INTO notas VALUES(5.8);
INSERT INTO notas VALUES(5.1);
INSERT INTO notas VALUES(5.0);
INSERT INTO notas VALUES(0);

Evolutiontech Treinamento e Desenvolvimento P g i n a | 82


POSTGRESQL Banco de dados SQL

Chamamos a instruo a baixo de SELECT CASE

SELECT CASE
WHEN nota < 3 THEN 'E'
WHEN nota < 5 THEN 'D'
WHEN nota < 7 THEN 'C'
WHEN nota < 9 THEN 'B'
ELSE 'A'
END AS conceito,
COUNT(*) AS quantidade,
MIN(nota) AS menor,
MAX(nota) AS maior,
AVG(nota) AS media
FROM notas
GROUP BY CASE
WHEN nota < 3 THEN 'E'
WHEN nota < 5 THEN 'D'
WHEN nota < 7 THEN 'C'
WHEN nota < 9 THEN 'B'
ELSE 'A'
END
ORDER BY conceito;

A seguir esto mostrados os resultados obtidos:

conceito | quantidade | menor | maior | media


---------+------------+-------+-------+-----------------------
A | 3 | 9.00 | 10.00 | 9.4000000000000000
B | 3 | 7.40 | 8.30 | 7.8000000000000000
C | 4 | 5.00 | 6.40 | 5.5750000000000000
E | 1 | 0.00 | 0.00 | 0.00000000000000000000
(4 linhas)

Utilizao da expresso CASE com funo


A expresso CASE pode ser usada como argumento de chamada de funo. Este exemplo usa a
expresso CASE como argumento da funo COUNT, passando o valor 1 quando a nota
corresponde ao conceito, e nulo quando no corresponde. Desta forma, a funo COUNT conta a
quantidade de notas presentes em cada conceito, uma vez que os valores nulos no so contados.
Os dados so os mesmos do exemplo anterior. Abaixo est mostrada a consulta utilizada:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 83


POSTGRESQL Banco de dados SQL

SELECT
COUNT(CASE WHEN nota BETWEEN 9.00 AND 10.00 THEN 1 ELSE NULL END) AS A,
COUNT(CASE WHEN nota BETWEEN 7.00 AND 8.99 THEN 1 ELSE NULL END)
AS B,
COUNT(CASE WHEN nota BETWEEN 5.00 AND 6.99 THEN 1 ELSE NULL END) AS C,
COUNT(CASE WHEN nota BETWEEN 3.00 AND 4.99 THEN 1 ELSE NULL END) AS D,
COUNT(CASE WHEN nota BETWEEN 0.00 AND 2.99 THEN 1 ELSE NULL END) AS E
FROM notas;

A seguir esto mostrados os resultados obtidos:

a | b | c | d | e
---+---+---+---+---
3 | 3 | 4 | 0 | 1
(1 linha)

Desta forma, foi mostrado em uma linha o mesmo resultado da coluna quantidade do exemplo
anterior.

Combinao de informao agrupada e no agrupada


Os comandos SELECT que retornam apenas uma linha 10 podem ser utilizados para combinar
informaes agrupadas com informaes no agrupadas na mesma consulta. Neste exemplo cada
nota mostrada junto com a menor nota, a maior nota, e a mdia de todas as notas. Os dados
so os mesmos dos dois exemplos anteriores. Abaixo est mostrada a consulta utilizada:

SELECT nota,
(SELECT MIN(nota) FROM notas) AS menor,
(SELECT MAX(nota) FROM notas) AS maior,
(SELECT AVG(nota) FROM notas) AS media
FROM notas;

A seguir esto mostrados os resultados obtidos:

Evolutiontech Treinamento e Desenvolvimento P g i n a | 84


POSTGRESQL Banco de dados SQL

nota | menor | maior | media


------+-------+-------+--------------------
10.00 | 0.00 | 10.00 | 6.7181818181818182
9.20 | 0.00 | 10.00 | 6.7181818181818182
9.00 | 0.00 | 10.00 | 6.7181818181818182
8.30 | 0.00 | 10.00 | 6.7181818181818182
7.70 | 0.00 | 10.00 | 6.7181818181818182
7.40 | 0.00 | 10.00 | 6.7181818181818182
6.40 | 0.00 | 10.00 | 6.7181818181818182
5.80 | 0.00 | 10.00 | 6.7181818181818182
5.10 | 0.00 | 10.00 | 6.7181818181818182
5.00 | 0.00 | 10.00 | 6.7181818181818182
0.00 | 0.00 | 10.00 | 6.7181818181818182
(11 linhas)

Select DISTINCT
Aps a lista de seleo ser processada, a tabela resultante pode opcionalmente estar sujeita
remoo das linhas duplicadas. A palavra chave DISTINCT deve ser escrita logo aps o SELECT
para especificar esta funcionalidade:

SELECT DISTINCT lista_de_seleo ...


Como bvio, duas linhas so consideradas distintas quando tm pelo menos uma coluna
diferente. Os valores nulos so considerados iguais nesta comparao.
Como alternativa, uma expresso arbitrria pode determinar quais linhas devem ser consideradas
distintas:

Combinao de consultas
Pode-se combinar os resultados de duas consultas utilizando as operaes de conjunto unio,
interseo e diferena
. A sintaxe

Evolutiontech Treinamento e Desenvolvimento P g i n a | 85


POSTGRESQL Banco de dados SQL

consulta1
UNION [ALL]
consulta2

consulta1
INTERSECT [ALL]
consulta2

consulta1
EXCEPT [ALL]
consulta2

onde consulta1 e consulta2 so consultas que podem utilizar qualquer uma das funcionalidades
mostradas at aqui.

As operaes de conjuntos tambm podem ser aninhadas ou encadeadas. Por exemplo:

consulta1
UNION
consulta2
UNION
consulta3

UNION
Efetivamente, UNION anexa o resultado da consulta2 ao resultado da consulta1 (embora no
haja garantia que esta seja a ordem que as linhas realmente retornam). Alm disso, so
eliminadas do resultado as linhas duplicadas, do mesmo modo que no DISTINCT, a no ser que
seja utilizado UNION ALL.

INTERSECT
INTERSECT retorna todas as linhas presentes tanto no resultado da consulta1 quanto no
resultado da consulta2. As linhas duplicadas so eliminadas, a no ser que seja utilizado
INTERSECT ALL.

EXCEPT
EXCEPT retorna todas as linhas presentes no resultado da consulta1, mas que no esto
presentes no resultado da consulta2 (s vezes isto chamado de diferena entre duas consultas).
Novamente, as linhas duplicadas so eliminadas a no ser que seja utilizado EXCEPT ALL.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 86


POSTGRESQL Banco de dados SQL

Linhas diferentes em duas tabelas com definies idnticas

Este exemplo mostra a utilizao de EXCEPT e UNION para descobrir as linhas diferentes de duas
tabelas semelhantes.
CREATE TEMPORARY TABLE a (c1 text, c2 text, c3 text);
INSERT INTO a VALUES ('x', 'x', 'x');
INSERT INTO a VALUES ('x', 'x', 'y'); -- nas duas tabelas
INSERT INTO a VALUES ('x', 'y', 'x');

CREATE TEMPORARY TABLE b (c1 text, c2 text, c3 text);


INSERT INTO b VALUES ('x', 'x', 'y'); -- nas duas tabelas
INSERT INTO b VALUES ('x', 'x', 'y'); -- nas duas tabelas
INSERT INTO b VALUES ('x', 'y', 'y');
INSERT INTO b VALUES ('y', 'y', 'y');
INSERT INTO b VALUES ('y', 'y', 'y');

-- No comando abaixo s um par ('x', 'x', 'y') removido do resultado -- Este


comando executa no DB2 8.1 sem alteraes.

SELECT 'a-b' AS dif, a.* FROM a EXCEPT ALL SELECT 'a-b',


b.* FROM b
UNION ALL
SELECT 'b-a', b.* FROM b EXCEPT ALL SELECT 'b-a', a.* FROM
a;

dif | c1 | c2 | c3
-----+----+----+----
a-b | x | x | x
a-b | x | y | x
b-a | x | x | y
b-a | x | y | y
b-a | y | y | y
b-a | y | y | y
(6 linhas)

No comando abaixo so removidas todas as linhas ('x', 'x', 'y'), e s


mostrada uma linha ('y', 'y', 'y') no resultado.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 87


POSTGRESQL Banco de dados SQL

SELECT 'a-b' AS dif, a.* FROM a EXCEPT SELECT 'a-b', b.*


FROM b
UNION
SELECT 'b-a', b.* FROM b EXCEPT SELECT 'b-a', a.* FROM a;

dif | c1 | c2 | c3
----+----+----+----
a-b | x | x | x
a-b | x | y | x
b-a | x | y | y
b-a | y | y | y
(4 linhas)

Ordenao de linhas
Aps a consulta ter produzido a tabela de sada (aps a lista de seleo ter sido processada) esta
tabela pode, opcionalmente, ser ordenada. Se nenhuma ordenao for especificada, as linhas
retornam em uma ordem aleatria. Neste caso, a ordem real depende dos tipos de plano de
varredura e de juno e da ordem no disco, mas no se deve confiar nisto.
Uma ordem de sada especfica somente pode ser garantida se a etapa de ordenao for
especificada explicitamente.
A clusula ORDER BY especifica a ordem de classificao:
SELECT lista_de_seleo
FROM expresso_de_tabela
ORDER BY coluna1 [ASC | DESC] [, coluna2 [ASC | DESC] ...]

onde coluna1, etc., fazem referncia s colunas da lista de seleo. Pode ser tanto o nome de
sada da coluna quanto o nmero da coluna. Alguns exemplos:

SELECT a, b FROM tabela1 ORDER BY a;


SELECT a + b AS soma, c FROM tabela1 ORDER BY soma;
SELECT a, sum(b) FROM tabela1 GROUP BY a ORDER BY 1;

Como extenso ao padro SQL, o PostgreSQL tambm permite ordenar por


expresses arbitrrias:

SELECT a, b FROM tabela1 ORDER BY a + b;

Evolutiontech Treinamento e Desenvolvimento P g i n a | 88


POSTGRESQL Banco de dados SQL

Tambm permitido fazer referncia a nomes de colunas da clusula FROM que no esto
presentes na lista de seleo:

SELECT a FROM tabela1 ORDER BY b;

Mas estas extenses no funcionam nas consultas envolvendo UNION, INTERSECT ou EXCEPT, e
no so portveis para outros bancos de dados SQL.
Cada especificao de coluna pode ser seguida pela palavra opcional ASC ou DESC, para definir a
direo de ordenao como ascendente ou descendente. A ordem ASC o padro. A ordenao
ascendente coloca os valores menores na frente, sendo que menor definido nos termos do
operador <. De forma semelhante, a ordenao descendente determinada pelo operador >.

LIMIT e OFFSET
LIMIT (limite) e OFFSET (deslocamento) permitem que seja trazida apenas uma parte das linhas
geradas pelo restante da consulta:

Usando LIMIT
SELECT lista_de_seleo
FROM expresso_de_tabela
[LIMIT { nmero | ALL }]
[OFFSET nmero]

Usando OFFSET
SELECT lista_de_seleo
FROM expresso_de_tabela
[OFFSET nmero]

Se for especificado o limite, no ser retornada mais que esta quantidade de linhas (mas
possivelmente menos, se a consulta produzir menos linhas). LIMIT ALL o mesmo que omitir a
clusula LIMIT.
OFFSET diz para saltar esta quantidade de linhas antes de comear a retornar as linhas. OFFSET 0
o mesmo que omitir a clusula OFFSET. Se forem especificados tanto OFFSET quanto LIMIT,
ento so saltadas OFFSET linhas antes de comear a contar as LIMIT linhas que sero retornadas.
Quando se utiliza LIMIT importante utilizar a clusula ORDER BY para estabelecer uma ordem
nica para as linhas do resultado. Caso contrrio, ser retornado um subconjunto imprevisvel de
linhas da consulta; pode-se desejar obter da dcima a vigsima linha, mas da dcima a vigsima
de qual ordem? A ordem desconhecida a no ser que seja especificado ORDER BY.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 89


POSTGRESQL Banco de dados SQL

O otimizador de consultas leva LIMIT em considerao para gerar o plano da consulta, portanto
bastante provvel obter planos diferentes (resultando em uma ordem diferente das linhas)
dependendo do que for especificado para LIMIT e OFFSET. Portanto, utilizar valores diferentes de
LIMIT/OFFSET para selecionar subconjuntos diferentes do resultado da consulta produz resultados
inconsistentes, a no ser que seja imposta uma ordem previsvel do resultado por meio da clusula
ORDER BY. Isto no est errado; isto uma conseqncia inerente ao fato do SQL no prometer
retornar os resultados de uma consulta em qualquer ordem especfica, a no ser que ORDER BY
seja utilizado para impor esta ordem.
necessrio computar as linhas saltadas pelo OFFSET no servidor; portanto, um OFFSET grande
pode ser ineficiente.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 90


POSTGRESQL Banco de dados SQL

Tipos de dado
O PostgreSQL disponibiliza para os usurios um amplo conjunto de tipos de dado nativos. Os
usurios podem adicionar novos tipos ao PostgreSQL utilizando o comando CREATE TYPE.
A Tabela 8-1 mostra todos os tipos de dado nativos de propsito geral. A maioria dos nomes
alternativos listados na coluna Aliases o nome utilizado internamente pelo PostgreSQL por
motivos histricos. Alm desses, existem alguns tipos usados internamente ou em obsolescncia 4
que no so mostrados aqui.

Nome Aliases Descrio


bigint int8 inteiro de oito
bytes com sinal
bigserial serial8 inteiro de oito bytes com
auto-incremento
bit [ (n) ] cadeia de bits de
comprimento fixo
bit varying [ (n) ] varbit cadeia de bits de
comprimento varivel
boolean bool booleano lgico
(verdade/falso)
box caixa retangular
no plano
bytea dados binrios
(matriz de bytes)
character varying [ (n) ]varchar [ (n) ] cadeia de caracteres
de comprimento varivel
character [ (n) ] char [ (n) ] cadeia de caracteres de
comprimento fixo
cidr endereo de rede
IPv4 ou IPv6
circle crculo no plano
date data de calendrio
(ano, ms, dia)

Evolutiontech Treinamento e Desenvolvimento P g i n a | 91


POSTGRESQL Banco de dados SQL

double precision float8 nmero de ponto


flutuante de preciso dupla
inet endereo de hospedeiro
IPv4 ou IPv6
integer int, int4 inteiro de quatro
bytes com sinal
interval [ (p) ] espao de tempo
line linha infinita no plano
lseg segmento de linha no plano
macaddr endereo MAC
money quantia monetria
numeric [ (p, s) ] decimal [ (p, s) ] numrico exato com
preciso selecionvel
path caminho geomtrico
no plano
point ponto geomtrico no plano
polygon caminho geomtrico
fechado no plano
real float4 nmero de ponto
flutuante de preciso simples
smallint int2 inteiro de dois bytes com sinal
serial serial4 inteiro de quatro bytes com
autoincremento
text cadeia de caracteres
de comprimento varivel
time [ (p) ] [ without hora do dia
time zone ]

time [ (p) ] with time timetz hora do dia, incluindo a zona horria
zone

timestamp [ (p) ] [ data e hora


without time zone ]

timestamp [ (p) ] with timestamptz data e hora, incluindo a zona horria


time zone

Evolutiontech Treinamento e Desenvolvimento P g i n a | 92


POSTGRESQL Banco de dados SQL

Tipos numricos
Os tipos numricos consistem em inteiros de dois, quatro e oito bytes, nmeros de ponto
flutuante de quatro e oito bytes, e decimais de preciso selecionvel. A Tabela 8-2 lista os tipos
disponveis.

Nome Tamanho de Descrio Faixa de valores


armazenamento

smallint 2 bytes inteiro com faixa pequena -32768 a +32767

integer 4 bytes escolha usual para inteiro -2147483648 a +2147483647

bigint 8 bytes inteiro com faixa larga -9223372036854775808 a


9223372036854775807

decimal varivel preciso especificada pelo usurio, sem limite


exato

numeric varivel preciso especificada pelo usurio, sem limite


exato

real 4 bytes preciso varivel, inexato preciso de 6 dgitos decimais

double 8 bytes preciso varivel, inexato preciso de 15 dgitos decimais


precision

serial 4 bytes inteiro com auto-incremento 1 a 2147483647

bigserial 8 bytes inteiro grande com auto-incremento 1 a 9223372036854775807

A sintaxe das constantes para os tipos numricos descrita na Seo 4.1.2. Os tipos numricos
possuem um conjunto completo de operadores aritmticos e funes correspondentes. Consulte
o Captulo 9 para obter informaes adicionais. As prximas sees descrevem os tipos em
detalhe.

Tipos inteiros
Os tipos smallint, integer e bigint armazenam nmeros inteiros, ou seja, nmeros sem a parte
fracionria, com faixas diferentes. A tentativa de armazenar um valor fora da faixa permitida
resulta em erro.
O tipo integer a escolha usual, porque oferece o melhor equilbrio entre faixa de valores,
tamanho de armazenamento e desempenho. Geralmente o tipo smallint s utilizado quando o
espao em disco est muito escasso. O tipo bigint somente deve ser usado quando a faixa de
valores de integer no for suficiente, porque este ltimo bem mais rpido.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 93


POSTGRESQL Banco de dados SQL

O tipo bigint pode no funcionar de modo correto em todas as plataformas, porque depende de
suporte no compilador para inteiros de oito bytes. Nas mquinas sem este suporte, o bigint age
do mesmo modo que o integer (mas ainda ocupa oito bytes de armazenamento). Entretanto,
no de nosso conhecimento nenhuma plataforma razovel onde este caso se aplique.
O padro SQL somente especifica os tipos inteiros integer (ou int) e smallint. O tipo bigint, e
os nomes de tipo int2, int4 e int8 so extenses, tambm compartilhadas por vrios outros
sistemas de banco de dados SQL.

Nmeros com preciso arbitrria


O tipo numeric pode armazenar nmeros com preciso de at 1.000 dgitos e realizar clculos
exatos. recomendado, especialmente, para armazenar quantias monetrias e outras
quantidades onde se requeira exatido. Entretanto, a aritmtica em valores do tipo numeric
muito lenta se comparada com os tipos inteiros, ou com os tipos de ponto flutuante descritos na
prxima seo.
So utilizados os seguintes termos: A escala do tipo NUMERIC o nmero de dgitos decimais da
parte fracionria, direita do ponto decimal.
A preciso do tipo NUMERIC o nmero total de dgitos significativos de todo o nmero, ou seja,
o nmero de dgitos nos dois lados do ponto decimal.
Portanto, o nmero 23.5141 possui preciso igual a 6 e escala igual a 4. Os inteiros podem ser
considerados como tendo escala igual a zero.
Como forma alternativa, NUMERIC(preciso) define a escala como sendo igual a 0.
Especificando-se NUMERIC sem qualquer preciso ou escala criada uma coluna onde
podem ser armazenados valores numricos com qualquer preciso ou escala, at a preciso
limite da implementao. Uma coluna deste tipo no converte os valores de entrada para
nenhuma escala em particular, enquanto as colunas do tipo numeric com escala declarada
convertem os valores da entrada para esta escala (O padro SQL requer a escala padro igual a
0, ou seja, uma converso para a preciso inteira. Isto foi considerado sem utilidade. Havendo
preocupao com a portabilidade, a preciso e a escala devem ser sempre especificadas
explicitamente).
Se a escala do valor a ser armazenado for maior que a escala declarada para a coluna, o sistema
arredonda o valor para o nmero de dgitos fracionrios especificado. Depois, se o nmero de
dgitos esquerda do ponto decimal exceder a preciso declarada menos a escala declarada,
gerado um erro.

Arredondamento em tipo numeric

Abaixo esto mostrados exemplos de insero de dados em um campo do tipo numeric. No


terceiro exemplo o arredondamento faz com que a preciso do campo seja excedida.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 94


POSTGRESQL Banco de dados SQL

CREATE TABLE t ( c NUMERIC(6,3));


INSERT INTO t VALUES (998.9991);
INSERT INTO t VALUES (998.9999);

SELECT * FROM t;

c
-------
998.999
999.000
(2 linhas)

INSERT INTO t VALUES (1999.9999);

ERRO: estouro de campo numrico


DETALHE: O valor absoluto maior ou igual a 10^3 para campo com preciso 6,
escala 3.

Os valores numricos so armazenados fisicamente sem zeros adicionais no incio ou no final.


Portanto, a preciso e a escala declaradas para uma coluna so as alocaes mximas, e no fixas
(Sob este aspecto o tipo numeric mais semelhante ao tipo varchar(n) do que ao tipo char(n)).
Alm dos valores numricos ordinrios o tipo numeric aceita o valor especial NaN, que significa
no--um-nmero (not-a-number). Toda operao envolvendo NaN produz outro NaN. Para
escrever este valor como uma constante em um comando SQL deve-se coloc-lo entre apstrofos
como, por exemplo, UPDATE tabela SET x = 'NaN'. Na entrada, a cadeia de caracteres NaN
reconhecida sem que haja distino entre letras maisculas e minsculas.
Os tipos decimal e numeric so equivalentes. Os dois tipos fazem parte do padro SQL.

Tipos seriais (Numerao automtica)

Os tipos de dado serial e bigserial no so tipos verdadeiros, mas meramente uma notao
conveniente para definir colunas identificadoras nicas (semelhante propriedade
AUTO_INCREMENTO existente em alguns outros bancos de dados). Na implementao corrente
especificar

CREATE TABLE nome_da_tabela (nome_da_coluna SERIAL );

Evolutiontech Treinamento e Desenvolvimento P g i n a | 95


POSTGRESQL Banco de dados SQL

Equivale a especificar:

CREATE SEQUENCE seq_product;


CREATE TABLE product (id_product; DEFAULT nextval('seq_product') NOT
NULL );

Conforme visto, foi criada uma coluna do tipo inteiro e feito o valor padro ser atribudo a partir
de um gerador de seqncia. A restrio NOT NULL aplicada para garantir que no pode ser
inserido o valor nulo explicitamente. Na maior parte das vezes, deve ser colocada uma restrio
UNIQUE ou PRIMARY KEY para no permitir a insero de valores duplicados por acidente, mas isto
no automtico.

Para inserir o prximo valor da seqncia em uma coluna do tipo serial deve ser especificada a
atribuio do valor padro coluna serial, o que pode ser feito omitindo a coluna na lista de
colunas no comando INSERT, ou atravs da utilizao da palavra chave DEFAULT.
Os nomes de tipo serial e serial4 so equivalentes: ambos criam colunas do tipo integer. Os
nomes de tipo bigserial e serial8 funcionam da mesma maneira, exceto por criarem uma
coluna bigint. Deve ser utilizado bigserial se forem esperados mais de 231 identificadores
durante a existncia da tabela.
A seqncia criada para a coluna do tipo serial removida automaticamente quando a coluna
que a definiu removida, e no pode ser removida de outra forma (Isto no era verdade nas
verses do PostgreSQL anteriores a 7.3. Deve ser observado que este vnculo de remoo
automtica no ocorre em uma seqncia criada pela restaurao da cpia de segurana de um
banco de dados pr-7.3; a cpia de segurana no contm as informaes necessrias para
estabelecer o vnculo de dependncia). Alm disso, a dependncia entre a seqncia e a coluna
feita apenas para a prpria coluna serial; se qualquer outra coluna fizer referncia seqncia
(talvez chamando manualmente a funo nextval()), haver rompimento se a seqncia for
removida. Esta forma de utilizar as seqncias das colunas serial considerada um estilo ruim.
Se for desejado suprir vrias colunas a partir do mesmo gerador de seqncia, a seqncia deve
ser criada como um objeto independente.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 96


POSTGRESQL Banco de dados SQL

Alterao da seqncia da coluna serial


A seqncia criada para a coluna do tipo serial pode ter seus parmetros alterados atravs do
comando ALTER SEQUENCE, da mesma forma que qualquer outra seqncia criada atravs do
comando CREATE SEQUENCE. Este exemplo mostra como proceder para fazer com que o valor
inicial da coluna do tipo serial seja igual a 1000.

CREATE TABLE t ( c1 SERIAL, c2 TEXT);

=> \ds

Esquema | Nome | Tipo | Dono


--------+----------+-----------+---------
public | t_c1_seq | seqncia | postgres
(1 linha)

ALTER SEQUENCE t_c1_seq RESTART WITH 1000;

INSERT INTO t VALUES (DEFAULT, 'Primeira linha');

SELECT * FROM t;

c1 | c2
-----+----------------
1000 | Primeira linha
(1 linha)

Tipos monetrios
O tipo money armazena a quantia monetria com uma preciso fracionria fixa; consulte a Tabela
8-3. A entrada aceita em vrios formatos, incluindo literais inteiros e de ponto flutuante, e
tambm o formato monetrio tpico, como '$1,000.00'. A sada geralmente neste ltimo
formato, mas depende do idioma).

Tipos monetrios

Nome Tamanho de ArmazenamentoDescrio Faixa

money 4 bytes quantia monetria-21474836.48 a +21474836.47

Evolutiontech Treinamento e Desenvolvimento P g i n a | 97


POSTGRESQL Banco de dados SQL

Tipos para cadeias de caracteres


A Tabela 8-4 mostra os tipos de propsito geral para cadeias de caracteres disponveis no
PostgreSQL.

Tipos para cadeias de caracteres

Nome Descrio

character varying(n), comprimento varivel com limite


varchar(n)

character(n), char(n) comprimento fixo, completado com brancos

text comprimento varivel no limitado

O SQL define dois tipos primrios para caracteres: character varying(n) e character(n), onde
n um nmero inteiro positivo. Estes dois tipos podem armazenar cadeias de caracteres com
comprimento de at n caracteres. A tentativa de armazenar uma cadeia de caracteres mais longa
em uma coluna de um destes tipos resulta em erro, a no ser que os caracteres excedentes sejam
todos espaos; neste caso a cadeia de caracteres ser truncada em seu comprimento mximo
(Esta exceo um tanto bizarra requerida pelo padro SQL). Se a cadeia de caracteres a ser
armazenada for mais curta que o comprimento declarado, os valores do tipo character so
completados com espaos; os valores do tipo character varying simplesmente armazenam uma
cadeia de caracteres mais curta.
Se um valor for convertido explicitamente (cast) para character varying(n), ou para
character(n), o excesso de comprimento ser truncado para n caracteres sem gerar erro (isto
tambm requerido pelo padro SQL).

As notaes varchar(n) e char(n) so sinnimos para character varying(n) e character(n),


respectivamente. O uso de character sem especificao de comprimento equivale a
character(1); se for utilizado character varying sem especificador de comprimento, este tipo
aceita cadeias de caracteres de qualquer tamanho. Este ltimo uma extenso do PostgreSQL.
Alm desses o PostgreSQL disponibiliza o tipo text, que armazena cadeias de caracteres de
qualquer comprimento. Embora o tipo text no esteja no padro SQL, vrios outros sistemas
gerenciadores de banco de dados SQL tambm o possuem.
Os valores do tipo character so preenchidos fisicamente com espaos at o comprimento n
especificado, sendo armazenados e mostrados desta forma. Entretanto, os espaos de
preenchimento so tratados como no sendo significativos semanticamente. Os espaos de
preenchimento so desconsiderados ao se comparar dois valores do tipo character, e so
removidos ao converter um valor do tipo character para um dos outros tipos para cadeia de
caracteres. Deve ser observado que os espaos no final so significativos semanticamente nos
valores dos tipos character varying e text.
So necessrios para armazenar dados destes tipos 4 bytes mais a prpria cadeia de caracteres e,
no caso do tipo character, mais os espaos para completar o tamanho. As cadeias de caracteres
longas so comprimidas automaticamente pelo sistema e, portanto, o espao fsico necessrio em
disco pode ser menor. Os valores longos tambm so armazenados em tabelas secundrias, para
no interferirem com o acesso rpido aos valores mais curtos da coluna. De qualquer forma, a

Evolutiontech Treinamento e Desenvolvimento P g i n a | 98


POSTGRESQL Banco de dados SQL

cadeia de caracteres mais longa que pode ser armazenada em torno de 1 GB (O valor mximo
permitido para n na declarao do tipo de dado menor que isto. No seria muito til mudar,
porque de todo jeito nas codificaes de caractere multibyte o nmero de caracteres e de bytes
podem ser bem diferentes. Se for desejado armazenar cadeias de caracteres longas, sem um
limite superior especificado, deve ser utilizado text ou character varying sem a especificao
de comprimento, em vez de especificar um limite de comprimento arbitrrio).

Existem dois outros tipos para cadeias de caracteres de comprimento fixo no PostgreSQL,
mostrados na Tabela 8-5. O tipo name existe apenas para armazenamento de identificadores nos
catlogos internos do sistema, no tendo por finalidade ser usado pelos usurios comuns. Seu
comprimento definido atualmente como 64 bytes (63 caracteres utilizveis mais o terminador)
mas deve ser referenciado utilizando a constante NAMEDATALEN. O comprimento definido
quando feita a compilao (sendo, portanto, ajustvel para usos especiais); o padro para
comprimento mximo poder mudar em uma verso futura. O tipo "char" (observe as aspas)
diferente de char(1), porque utiliza apenas um byte para armazenamento. utilizado
internamente nos catlogos do sistema como o tipo de enumerao do homem pobre ( poorman's
enumeration type).

Tipos especiais para caracteres

Nome Tamanho de Armazenamento Descrio

"char" 1 byte tipo interno de um nico caractere

name 64 bytes tipo interno para nomes de objeto

Utilizao dos tipos para cadeias de caracteres


CREATE TABLE teste1 (a character(4));
INSERT INTO teste1 VALUES ('ok');
SELECT a, char_length(a) FROM teste1;

a | char_length
------+------------
ok | 4

CREATE TABLE teste2 (b VARCHAR(5));


INSERT INTO teste2 VALUES ('ok');
INSERT INTO teste2 VALUES ('bom');
INSERT INTO teste2 VALUES ('muito longo');

ERRO: valor muito longo para o tipo character varying(5)

Evolutiontech Treinamento e Desenvolvimento P g i n a | 99


POSTGRESQL Banco de dados SQL

Tipos para data e hora


O PostgreSQL suporta o conjunto completo de tipos para data e hora do SQL, mostrados na
Tabela 8-9. As operaes disponveis para estes tipos de dado esto descritas na Seo 9.9.

Tipos para data e hora

Nome Tamanho de Descrio


Armazenamento

timestamp [ (p) ] 8 bytes tanto data quanto hora


[ without time zone ]

timestamp [ (p) ] 8 bytes tanto data quanto hora,


with time zone
com zona horria

interval [ (p) ] 12 bytes intervalo de tempo

date 4 bytes somente data

time [ (p) ] 8 bytes somente a hora do dia


[ without time zone ]

time [ (p) ] 12 bytes somente a hora do dia,


with time zone
com zona horria

Os tipos time, timestamp, e interval aceitam um valor opcional de preciso p, que especifica o
nmero de dgitos fracionrios mantidos no campo de segundos. Por padro no existe limite
explcito para a preciso. O intervalo permitido para p de 0 a 6 para os tipos timestamp e
interval.

Para os tipos time o intervalo permitido para p de 0 a 6 quando armazenados em inteiros de


oito bytes, e de 0 a 10 quando armazenados em ponto flutuante.
O tipo time with time zone definido pelo padro SQL, mas a definio contm propriedades
que levam a uma utilidade duvidosa. Na maioria dos casos, a combinao de date, time,
timestamp without time zone e timestamp with time zone deve fornecer uma faixa
completa de funcionalidades para data e hora requeridas por qualquer aplicativo.
Os tipos abstime e reltime so tipos de menor preciso usados internamente. desestimulada a
utilizao destes tipos em novos aplicativos, alm de ser incentivada a migrao dos aplicativos
antigos quando apropriado. Qualquer um destes tipos internos pode desaparecer em uma verso
futura, ou mesmo todos.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 100


POSTGRESQL Banco de dados SQL

Entrada de data e hora


A entrada da data e da hora aceita em praticamente todos os formatos razoveis, incluindo o
ISO 8601, o SQLcompatvel, o POSTGRES tradicional, alm de outros. Para alguns formatos a
ordem do dia, ms e ano na entrada da data ambguo e, por isso, existe suporte para especificar
a ordem esperada destes campos. Deve ser definido o parmetro DateStyle como MDY para
selecionar a interpretao ms-dia-ano, DMY para selecionar a interpretao dia-ms-ano, ou YMD
para selecionar a interpretao ano-ms-dia.
O PostgreSQL mais flexvel no tratamento da entrada de data e hora do que o requerido pelo
padro SQL. Consulte o Apndice B para conhecer as regras exatas de anlise da entrada de data
e hora e os campos texto reconhecidos, incluindo meses, dias da semana e zonas horrias.
Lembre-se que qualquer entrada literal de data ou hora necessita estar entre apstrofos, como os
textos das cadeias de caracteres. Consulte a Seo 4.1.2.5 para obter informaes adicionais. O
SQL requer a seguinte sintaxe
tipo [ (p) ] 'valor'

onde p, na especificao opcional da preciso, um nmero inteiro correspondendo ao nmero


de dgitos fracionrios do campo de segundos. A preciso pode ser especificada para os tipos
time, timestamp e interval. Os valores permitidos esto mencionados acima. Se no for
especificada nenhuma preciso na especificao da constante, a preciso do valor literal torna-se
o padro.

Datas
A Tabela 8-10 mostra algumas entradas possveis para o tipo date.

Entrada de data

Exemplo Descrio

January 8, 1999 no-ambguo em qualquer modo de entrada em datestyle

1999-01-08 ISO 8601; 8 de janeiro em qualquer modo (formato recomendado)

1/8/1999 8 de janeiro no modo MDY; 1 de agosto no modo DMY

1/18/1999 18 de janeiro no modo MDY; rejeitado nos demais modos

01/02/03 2 de janeiro de 2003 no modo MDY; 1 de fevereiro de 2003 no modo


DMY; 3 de fevereiro de

2001 no modo YMD

1999-Jan-08 8 de janeiro e qualquer modo

Jan-08-1999 January 8 em qualquer modo

08-Jan-1999 8 de janeiro em qualquer modo

Evolutiontech Treinamento e Desenvolvimento P g i n a | 101


POSTGRESQL Banco de dados SQL

99-Jan-08 8 de janeiro no modo YMD, caso contrrio errado

08-Jan-99 8 de janeiro, porm errado no modo YMD

Jan-08-99 8 de janeiro, porm errado no modo YMD

19990108 ISO 8601; 8 de janeiro de 1999 em qualquer modo

990108 ISO 8601; 8 de janeiro de 1999 em qualquer modo

1999.008 ano e dia do ano

J2451187 dia juliano

January 8, 99 BC ano 99 antes da era comum a

Horas
Os tipos hora-do-dia so time [ (p) ] without time zone e time [ (p) ] with time zone.
Escrever apenas time equivale a escrever time without time zone.

Entrada de hora

Exemplo Descrio

04:05:06.789 ISO 8601

04:05:06 ISO 8601

04:05 ISO 8601

040506 ISO 8601

04:05 AM o mesmo que 04:05; AM no afeta o valor

04:05 PM o mesmo que 16:05; a hora entrada deve ser <=


12

04:05:06.789-8 ISO 8601

04:05:06-08:00 ISO 8601

04:05-08:00 ISO 8601

040506-08 ISO 8601

Evolutiontech Treinamento e Desenvolvimento P g i n a | 102


POSTGRESQL Banco de dados SQL

04:05:06 PST zona horria especificada pelo nome

Entrada de zona horria

Exemplo Descrio

PST Hora Padro do Pacfico (Pacific Standard


Time)

-8:00 deslocamento ISO-8601 para PST

-800 deslocamento ISO-8601 para PST

-8 deslocamento ISO-8601 para PST

zulu Abreviatura militar para UTC

z Forma abreviada de zulu

Carimbos do tempo (TIMESTAMP)


As entradas vlidas para os tipos carimbo do tempo so formadas pela concatenao da data com
a hora seguida, opcionalmente, pela zona horria, e seguida opcionalmente por AD ou BC (Como
alternativa, AD ou BC pode aparecer antes da zona horria, mas esta no a ordem preferida).
Portanto,

1999-01-08 04:05:06

e
1999-01-08 04:05:06 -8:00

Evolutiontech Treinamento e Desenvolvimento P g i n a | 103


POSTGRESQL Banco de dados SQL

So valores vlidos, que seguem o padro ISO 8601. Alm desses, suportado o formato muito
utilizado

January 8 04:05:06 1999 PST

O padro SQL diferencia os literais timestamp without time zone de timestamp with time
zone pela existncia de +; ou -.

Portanto, de acordo com o padro,


TIMESTAMP '2004-10-19 10:23:54'

um timestamp without time zone, enquanto


TIMESTAMP '2004-10-19 10:23:54+02'

um timestamp with time zone.

O PostgreSQL difere do padro requerendo que os literais timestamp with time zone sejam
digitados explicitamente:
TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'

Se o literal no for informado explicitamente como sendo timestamp with time zone, o
PostgreSQL ignora em silncio qualquer indicao de zona horria no literal. Ou seja, o valor
resultante de data e hora derivado dos campos data e hora do valor da entrada, no sendo
ajustado conforme a zona horria.
Para timestamp with time zone, o valor armazenado internamente est sempre em UTC
(Tempo Universal Coordenado, tradicionalmente conhecido por Hora Mdia de Greenwich, GMT
12 ). Um valor de entrada possuindo a zona horria especificada explicitamente convertido em

UTC utilizando o deslocamento apropriado para esta zona horria. Se no for especificada
nenhuma zona horria na cadeia de caracteres da entrada, pressupe-se que est na mesma zona
horria indicada pelo parmetro do sistema timezone, sendo convertida em UTC utilizando o
deslocamento da zona em timezone.
Quando um valor de timestamp with time zone enviado para a sada, sempre convertido de
UTC para a zona horria corrente de timezone, e mostrado como hora local desta zona. Para ver a
hora em outra zona horria, ou se muda timezone ou se usa a construo AT TIME ZONE
(consulte a Seo 9.9.3).
As converses entre timestamp without time zone e timestamp with time zone
normalmente assumem que os valores de timestamp without time zone devem ser recebidos
ou fornecidos como hora local da timezone. A referncia para uma zona horria diferente pode
ser especificada para a converso utilizando AT TIME ZONE.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 104


POSTGRESQL Banco de dados SQL

Valores especiais
Por ser conveniente, o PostgreSQL tambm suporta vrios valores especiais para entrada de data
e hora, conforme mostrado na Tabela 8-13. Os valores infinity e -infinity possuem
representao especial dentro do sistema, sendo mostrados da mesma maneira; porm, os
demais so simplesmente notaes abreviadas convertidas para valores comuns de data e hora
ao serem lidos (Em particular, now e as cadeias de caracteres relacionadas so convertidas para
um valor especfico de data e hora to logo so lidas). Todos estes valores devem ser escritos
entre apstrofos quando usados como constantes nos comandos SQL.

Entradas especiais de data e hora

Cadeia de Tipos vlidos Descrio


caracteres
entrada

epoch date, timestamp 1970-01-01 00:00:00+00 (hora zero do


sistema Unix)

infinity timestamp mais tarde que todos os outros carimbos


do tempo

-infinity timestamp mais cedo que todos os outros carimbos


do tempo

now date, time, timestamp hora de incio da transao corrente

today date, timestamp meia-noite de hoje

tomorrow date, timestamp meia-noite de amanh

yesterday date, timestamp meia-noite de ontem

allballs time 00:00:00.00 UTC

Tambm podem ser utilizadas as seguintes funes, compatveis com o padro SQL, para obter o
valor corrente de data e hora para o tipo de dado correspondente: CURRENT_DATE, CURRENT_TIME,
CURRENT_TIMESTAMP, LOCALTIME e LOCALTIMESTAMP.

Utilizao das entradas especiais de data e hora


Neste exemplo so mostradas utilizaes das entradas especiais de data e hora para o tipo
timestamp with time zone.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 105


POSTGRESQL Banco de dados SQL

=> CREATE TABLE t ( c1 TEXT, c2 TIMESTAMP WITH TIME ZONE );


=> BEGIN;
=> INSERT INTO t VALUES ('epoch', 'epoch');
=> INSERT INTO t VALUES ('infinity', 'infinity');
=> INSERT INTO t VALUES ('-infinity', '-infinity');
=> INSERT INTO t VALUES ('now', 'now');
=> INSERT INTO t VALUES ('today', 'today');
=> INSERT INTO t VALUES ('tomorrow', 'tomorrow');
=> INSERT INTO t VALUES ('yesterday', 'yesterday');
=> INSERT INTO t VALUES ('CURRENT_TIMESTAMP', CURRENT_TIMESTAMP); =>
END;
=> SELECT * FROM t;

c1 | c2
------------------+-------------------------------
epoch | 1969-12-31 21:00:00-03
infinity | infinity
-infinity | -infinity
now | 2005-04-19 18:20:35.164293-03
today | 2005-04-19 00:00:00-03
tomorrow | 2005-04-20 00:00:00-03
yesterday | 2005-04-18 00:00:00-03
CURRENT_TIMESTAMP | 2005-04-19 18:20:35.164293-03
(8 linhas)

Sadas de data e hora

Utilizando o comando SET datestyle o formato de sada para os tipos de data e hora pode ser
definido como um dos quatro estilos ISO 8601, SQL (Ingres), POSTGRES tradicional e German. O
padro o formato ISO (o padro SQL requer a utilizao do formato ISO 8601; o nome do
formato de sada SQL um acidente histrico). A Tabela 8-14 mostra exemplo de cada um dos
estilos de sada. A sada dos tipos date e time obviamente utilizam apenas a parte da data ou da
hora de acordo com os exemplos fornecidos.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 106


POSTGRESQL Banco de dados SQL

Estilos de sada de data e hora

Especificao de estilo Descrio Exemplo

ISO ISO 8601/padro 2005-04-21 18:39:28.283566-03


SQL

SQL estilo tradicional 04/21/2005 18:39:28.283566 BRT

POSTGRES estilo original Thu Apr 21 18:39:28.283566 2005


BRT

German estilo regional 21.04.2005 18:39:28.283566 BRT

Nos estilos SQL e POSTGRES, o dia vem antes do ms se a ordem de campo DMY tiver sido
especificada, seno o ms vem antes do dia (veja na Seo 8.5.1 como esta especificao tambm
afeta a interpretao dos valores de entrada). A Tabela 8-15 mostra um exemplo.

Convenes de ordem na data

Definio de datestyle Ordem de Exemplo de sada


entrada

SQL, DMY dia/ms/ano 21/04/2005 18:39:28.283566 BRT

SQL, MDY ms/dia/ano 04/21/2005 18:39:28.283566 BRT

Postgres, DMY dia/ms/ano Thu 21 Apr 18:39:28.283566 2005 BRT

A sada do tipo interval se parece com o formato da entrada, exceto que as unidades como
century e week so convertidas em anos e dias, e que ago convertido no sinal apropriado. No
modo ISO a sada se parece com
[ quantidade unidade [ ... ] ] [ dias ] [ horas:minutos:segundos ]

Os estilos de data e hora podem ser selecionados pelo usurio utilizando o comando SET
datestyle, o parmetro DateStyle no arquivo de configurao postgresql.conf, ou a varivel de
ambiente PGDATESTYLE no servidor ou no cliente. A funo de formatao to_char (consulte a
Seo 9.8) tambm pode ser utilizada como uma forma mais flexvel de formatar a sada de data e
hora.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 107


POSTGRESQL Banco de dados SQL

Tipo booleano
O PostgreSQL disponibiliza o tipo SQL padro boolean. O tipo boolean pode possuir apenas um
dos dois estados: verdade ou falso. O terceiro estado, desconhecido, representado pelo
valor nulo do SQL.
Os valores literais vlidos para o estado verdade so:
TRUE
't'
'true'
'y'
'yes'
'1'

Para o estado falso podem ser utilizados os seguintes valores:


FALSE
'f'
'false'
'n'
'no' '0'

A utilizao das palavras chave TRUE e FALSE preferida (e em conformidade com o padro SQL).

Utilizao do tipo boolean


CREATE TABLE teste1 (a boolean, b text);
INSERT INTO teste1 VALUES (TRUE, 'sic est');
INSERT INTO teste1 VALUES (FALSE, 'non est');
SELECT * FROM teste1;

a | b
--+---------
t | sic est
f | non est

Tipos para endereo de rede


O PostgreSQL disponibiliza tipos de dado para armazenar endereos IPv4, IPv6 e MAC, conforme
mostrado na Tabela 817. prefervel utilizar estes tipos em vez dos tipos de texto puro, porque
estes tipos possuem verificao de erro na entrada, alm de vrios operadores e funes
especializadas (consulte Seo 9.11).

Tipos para endereo de rede

Nome Tamanho de ArmazenamentoDescrio

Evolutiontech Treinamento e Desenvolvimento P g i n a | 108


POSTGRESQL Banco de dados SQL

cidr 12 ou 24 bytes redes IPv4 e IPv6

inet 12 ou 24 bytes hospedeiros e redes IPv4 e IPv6

macaddr 6 bytes endereo MAC

Ao ordenar os tipos de dado inet e cidr, os endereos IPv4 vm sempre na frente dos endereos
IPv6, inclusive os endereos IPv4 encapsulados ou mapeados em endereos IPv6, tais como
::10.2.3.4 ou ::ffff::10.4.3.2.

inet
O tipo de dado inet armazena um endereo de hospedeiro IPv4 ou IPv6 e, opcionalmente, a
identificao da sub-rede onde se encontra, tudo em um nico campo. A identificao da sub-
rede representada declarando quantos bits do endereo do hospedeiro representam o
endereo de rede (a mscara de rede). Se a mscara de rede for 32 e o endereo for IPv4, ento
o valor no indica uma sub-rede, e sim um nico hospedeiro. No IPv6 o comprimento do
endereo de 128 bits e, portanto, 128 bits especificam o endereo de um nico hospedeiro.
Deve ser observado que se for desejado aceitar apenas endereos de rede, deve ser utilizado o
tipo cidr em vez do tipo inet.
O formato de entrada para este tipo endereo/y, onde endereo um endereo IPv4 ou IPv6, e
y o nmero de bits da mscara de rede. Se a parte /y for deixada de fora, ento a mscara de
rede ser 32 para IPv4 e 128 para IPv6, e o valor representa um nico hospedeiro apenas. Ao ser
mostrado, a poro /y suprimida se a mscara de rede especificar apenas um nico hospedeiro.

cidr
O tipo cidr armazena uma especificao de rede IPv4 ou IPv6. Os formatos de entrada e de sada
seguem as convenes do Classless Internet Domain Routing 19 O formato para especificar
redes endereo/y, onde endereo a rede representada por um endereo IPv4 ou IPv6, e y o
nmero de bits da mscara de rede. Se y for omitido, ser calculado utilizando as premissas do
sistema de numerao com classes antigo, exceto que ser pelo menos suficientemente grande
para incluir todos os octetos escritos na entrada. errado especificar endereo de rede contendo
bits definidos direita da mscara de rede especificada.
A Tabela 8-18 mostra alguns exemplos.

Exemplos de entrada para o tipo cidr

Entrada cidr Sada cidr abbrev(cidr)

192.168.100.128/25 192.168.100.128/25 192.168.100.128/25

192.168/24 192.168.0.0/24 192.168.0/24

Evolutiontech Treinamento e Desenvolvimento P g i n a | 109


POSTGRESQL Banco de dados SQL

192.168/25 192.168.0.0/25 192.168.0.0/25

192.168.1 192.168.1.0/24 192.168.1/24

192.168 192.168.0.0/24 192.168.0/24

128.1 128.1.0.0/16 128.1/16

128 128.0.0.0/16 128.0/16

128.1.2 128.1.2.0/24 128.1.2/24

10.1.2 10.1.2.0/24 10.1.2/24

10.1 10.1.0.0/16 10.1/16

10 10.0.0.0/8 10/8

10.1.2.3/32 10.1.2.3/32 10.1.2.3/32

2001:4f8:3:ba::/64 2001:4f8:3:ba::/64 2001:4f8:3:ba::/64

::ffff:1.2.3.0/120 ::ffff:1.2.3.0/120 ::ffff:1.2.3/120

::ffff:1.2.3.0/128 ::ffff:1.2.3.0/128 ::ffff:1.2.3.0/128

8.11. Tipos compostos


O tipo composto descreve a estrutura de uma linha ou registro; essencialmente, apenas uma
lista de nomes de campos com seus tipos de dado. O PostgreSQL permite que os valores de tipo
composto sejam utilizados de muitas maneiras idnticas s que os tipos simples podem ser ser
utilizados. Por exemplo, uma coluna de uma tabela pode ser declarada como sendo de um tipo
composto.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 110


POSTGRESQL Banco de dados SQL

Funes e Operadores
O PostgreSQL fornece um grande nmero de funes e operadores para os tipos de dado nativos.
Os usurios tambm podem definir suas prprias funes e operadores, conforme descrito na
Parte V. Os comandos \df e \do do psql podem ser utilizados para mostrar a lista de todas as
funes e operadores disponveis, respectivamente.
Havendo preocupao quanto portabilidade, deve-se ter em mente que a maioria das funes e
operadores descritos neste captulo, com exceo dos operadores mais triviais de aritmtica e de
comparao, alm de algumas funes indicadas explicitamente, no so especificadas pelo
padro SQL. Algumas das funcionalidades estendidas esto presentes em outros sistemas
gerenciadores de banco de dados SQL e, em muitos casos, estas funcionalidades so compatveis
e consistentes entre as vrias implementaes.

Operadores lgicos
Esto disponveis os operadores lgicos habituais:
AND OR
NOT

O SQL utiliza a lgica booleana de trs valores, onde o valor nulo representa o desconhecido.
Devem ser observadas as seguintes tabelas verdade:

a b a AND b a OR b

TRUE TRUE TRUE TRUE

TRUE FALSE FALSE TRUE

TRUE NULL NULL TRUE

FALSE FALSE FALSE FALSE

FALSE NULL FALSE NULL

NULL NULL NULL NULL

a NOT a

TRUE FALSE

FALSE TRUE

NULL NULL

Evolutiontech Treinamento e Desenvolvimento P g i n a | 111


POSTGRESQL Banco de dados SQL

Os operadores AND e OR so comutativos, ou seja, pode-se trocar a ordem dos operandos


esquerdo e direito sem afetar o resultado. Consulte a Seo 4.2.12 para obter informaes
adicionais sobre a ordem de avaliao das subexpresses.

Operadores de comparao
Esto disponveis os operadores de comparao habituais, conforme mostrado na Tabela 9-1.

Operadores de comparao

Operador Descrio

< menor

> maior

<= menor ou igual

>= maior ou igual

= igual

<> ou != diferente

Os operadores de comparao esto disponveis para todos os tipos de dado onde fazem sentido.
Todos os operadores de comparao so operadores binrios, que retornam valores do tipo
boolean; expresses como 1 < 2 < 3 no so vlidas (porque no existe o operador < para
comparar um valor booleano com 3).

Alm dos operadores de comparao, est disponvel a construo


especial BETWEEN.
a BETWEEN x AND y

equivale a
a >= x AND a <= y

Evolutiontech Treinamento e Desenvolvimento P g i n a | 112


POSTGRESQL Banco de dados SQL

a NOT BETWEEN x AND y

equivale a
a < x OR a > y

No existe diferena entre as duas formas, alm dos ciclos de CPU necessrios para reescrever a
primeira forma na segunda internamente.

Para verificar se um valor nulo ou no, so usadas as construes

expresso IS NULL expresso IS NOT NULL

ou s construes equivalentes, mas fora do padro,


expresso ISNULL expresso NOTNULL

No deve ser escrito expresso = NULL, porque NULL no igual a NULL (O valor nulo
representa um valor desconhecido, e no se pode saber se dois valores desconhecidos so iguais).
Este comportamento est de acordo com o padro SQL.

Funes e operadores matemticos


So fornecidos operadores matemticos para muitos tipos de dado do PostgreSQL. Para os tipos
sem as convenes matemticas habituais para todas as permutaes possveis (por exemplo, os
tipos de data e hora), o comportamento real descrito nas prximas sees.

Operadores matemticos

Operador Descrio Exemplo Resultado

+ adio 2 + 3 5

- subtrao 2 - 3 -1

* multiplicao 2 * 3 6

/ diviso (diviso inteira trunca o 4 / 2 2


resultado)

% mdulo (resto) 5 % 4 1

Evolutiontech Treinamento e Desenvolvimento P g i n a | 113


POSTGRESQL Banco de dados SQL

^ exponenciao 2.0 ^ 3.0 8

|/ raiz quadrada |/ 25.0 5

||/ raiz cbica ||/ 27.0 3

! fatorial 5 ! 120

!! fatorial (operador de prefixo) !! 5 120

@ valor absoluto @ -5.0 5

& AND bit a bit 91 & 15 11

| OR bit a bit 32 | 3 35

# XOR bit a bit 17 # 5 20

~ NOT bit a bit ~1 -2

<< deslocamento esquerda bit a bit 1 << 4 16

>> deslocamento direita bit a bit 8 >> 2 2

Os operadores bit a bit 1 trabalham somente em tipos de dado inteiros, enquanto os demais esto
disponveis para todos os tipos de dado numricos. Os operadores bit a bit tambm esto
disponveis para os tipos cadeia de bits bit e bit varying.

Funes matemticas
Funo Descrio Exemplo Resultado
abs(x) valor absoluto abs(-17.4) 17.4

cbrt(dp) raiz cbica cbrt(27.0) 3

ceil(dp ou numeric) o menor inteiro no ceil(-42.8) -42


menor que o
argumento
ceiling(dp ou o menor inteiro no ceiling(-95.3) -95
numeric)
menor que o
argumento (o
mesmo que ceil)
degrees(dp) radianos para graus degrees(0.5) 28.64788

exp(dp ou numeric) exponenciao exp(1.0) 2.71828182845905

Evolutiontech Treinamento e Desenvolvimento P g i n a | 114


POSTGRESQL Banco de dados SQL

floor(dp ou numeric) o maior inteiro no floor(-42.8) -43


maior que o
argumento
ln(dp ou numeric) logaritmo natural ln(2.0) 0.693147180559945

log(dp ou numeric) logaritmo na base log(100.0) 2


10
log(b numeric, x logaritmo na base b log(2.0, 64.0) 6.0000000000
numeric)

mod(y, x) resto de y/x mod(9,4) 1

pi() constante pi() 3.14159265358979

power(a dp, b dp) a elevado a b power(9.0, 3.0) 729

power(a numeric, b a elevado a b power(9.0, 3.0) 729


numeric)

radians(dp) graus para radianos radians(45.0) 0.785398163397448

random() valor randmico random()


entre
0.0 e 1.0
round(dp ou numeric) arredondar para o round(42.4) 42
inteiro mais
prximo
round(v numeric, s arredondar para s round(42.4382, 2) 42.44
integer)
casas decimais
setseed(dp) define a semente setseed(0.54823) 1177314959
para as prximas
chamadas a
random()
sign(dp ou numeric) sinal do argumento sign(-8.4) -1
(-
1, 0, +1)
sqrt(dp ou numeric) raiz quadrada sqrt(2.0) 1.4142135623731

trunc(dp ou numeric) trunca em direo trunc(42.8) 42


ao zero
trunc(v numeric, s trunca com s casas trunc(42.4382, 2) 42.43
integer)
decimais

Evolutiontech Treinamento e Desenvolvimento P g i n a | 115


POSTGRESQL Banco de dados SQL

Funes trigonomtricas
Funo Descrio

acos(x) arco cosseno

asin(x) arco seno

atan(x) arco tangente

atan2(x, y) arco tangente de x/y

cos(x) cosseno

cot(x) cotangente

sin(x) seno

tan(x) tangente

Funes e operadores para cadeias de caracteres


Esta seo descreve as funes e operadores disponveis para examinar e manipular valores
cadeia de caracteres. Neste contexto, cadeia de caracteres inclui todos os valores dos tipos
character, character varying e text. A menos que seja dito o contrrio, todas as funes
relacionadas abaixo trabalham com todos estes tipos, mas se deve tomar cuidado com os efeitos
em potencial do preenchimento automtico quando for utilizado o tipo character. De modo
geral, as funes descritas nesta seo tambm trabalham com dados de tipos que no so
cadeias de caracteres, convertendo estes dados primeiro na representao de cadeia de
caracteres. Algumas funes tambm existem em forma nativa para os tipos cadeia de bits.
O SQL define algumas funes para cadeias de caracteres com uma sintaxe especial, onde certas
palavras chave, em vez de vrgulas, so utilizadas para separar os argumentos. Os detalhes esto
na Tabela 9-6. Estas funes tambm so implementadas utilizando a sintaxe regular de chamada
de funo (Consulte a Tabela 9-7).

Funo Descrio Exemplo Resultado

cadeia_de_caracteres Concatenao de cadeias de 'Post' || PostgreSQL


|| 'greSQL'
caracteres
cadeia_de_caracteres

Evolutiontech Treinamento e Desenvolvimento P g i n a | 116


POSTGRESQL Banco de dados SQL

bit_length( cadeia_de_ Nmero de bits na cadeia de bit_length( 32


caracteres) 'Jos')
caracteres

Funo Descrio Exemplo Resultado

char_length( cadeia_de_ Nmero de caracteres na char_length( 4


caracteres) ou 'Jos')
cadeia de caracteres
character_length(
cadeia_de_ caracteres)

convert( cadeia_de_ Muda a codificao utilizando convert( 'PostgreSQL'


caracteres using 'PostgreSQL'
nome_da_converso)
o nome de converso using na codificao
especificado. As converses
iso_8859_1_to Unicode (UTF-
podem ser definidas pelo
comando CREATE _utf_8)
8)
CONVERSION. Alm disso,
existem alguns nomes de
converso pr-definidos. Veja
na Tabela 9-8 os nomes de
converso disponveis.
lower( cadeia_de_ Converte as letras da cadeia lower( 'SO') so
caracteres)
de caracteres em minsculas
octet_length( cadeia_de_ Nmero de bytes na cadeia de octet_length( 4
caracteres) 'Jos')
caracteres
overlay( cadeia_de_ Substituir parte da cadeia de overlay( Thomas
caracteres placing 'Txxxxas'
cadeia_de_ caracteres caracteres (sobreposio) placing 'hom'
from integer [for from 2 for 4)
integer])

position( substring in Posio da subcadeia de position( 'om' 3


cadeia_de_ caracteres) in 'Thomas')
caracteres
substring( cadeia_de_ Extrai parte da cadeia de substring( hom
caracteres [from
integer] [for integer])
caracteres 'Thomas' from
2 for 3)

substring( cadeia_de_ Extrai a parte da cadeia de substring( mas


caracteres from padro)
caracteres correspondente 'Thomas' from
expresso regular POSIX '...$')
(http:// unixhelp.ed.ac.uk/
CGI/man-cgi?regex+7) a

Evolutiontech Treinamento e Desenvolvimento P g i n a | 117


POSTGRESQL Banco de dados SQL

substring( cadeia_de_ Extrai a parte da cadeia de substring( oma


caracteres from padro 'Thomas' from
for escape) caracteres correspondente '%#"o_a#"_' for
expresso regular SQL '#')

trim( [leading | Remove a cadeia de trim( both 'x' Tom


trailing | both] from 'xTomxx')
[caracteres] from caracteres mais longa
cadeia_de_ caracteres) contendo apenas os
caracteres (espao por
padro) da extremidade
inicial/final/ambas da
cadeia_de_caracteres.

upper( cadeia_de_ Converte as letras da cadeia upper('so') SO


caracteres)
de caracteres em maisculas

Funo Descrio Exemplo Resultado

Esto disponveis funes adicionais para manipulao de cadeias de caracteres, algumas delas
so utilizadas internamente para implementar funes de cadeia de caracteres do padro SQL.

Outras funes para cadeia de caracteres


Funo Descrio Exemplo Resultado

ascii(text) cdigo ASCII do primeiro ascii('x') 120


caractere do argumento

btrim( cadeia_de_ Remove a maior cadeia btrim( trim


caracteres text [,
caracteres text])
de caracteres contendo 'xyxtrimyyx',
apenas os caracteres 'xy')
presentes em
caracteres (espao por
padro), do incio e do
fim
da cadeia_de_
caracteres

chr(integer) Caractere com o cdigo chr(65) A

ASCII fornecido

Evolutiontech Treinamento e Desenvolvimento P g i n a | 118


POSTGRESQL Banco de dados SQL

convert( cadeia_de_ Converte a cadeia de convert( Representao na


caracteres text, 'texto_em_
[codificao_de_ caracteres na unicode', codificao ISO
origem name,] codificao_de_ 'UNICODE',
codificao_de_
8859-1 do texto_em
destino name) 'LATIN1') _unicode
destino. A codificao
de origem especificada
por
codificao_de_
origem. Se a
codificao_de_

origem for omitida, ser


assumida a codificao
do banco de dados.

decode( cadeia_de_ Decodifica os dados decode( 123\000\001


caracteres text, 'MTIzAAE=',
tipo text)
binrios da cadeia_de_
caracteres previamente 'base64')
codificada com
encode().

O tipo do parmetro o
mesmo que em
encode().

encode( dados bytea, Codifica dados binrios encode( MTIzAAE=


tipo text)
na representao '123\\000\\001',
somente ASCII. Os tipos 'base64')
suportados so: base64,
hex e escape.

initcap(text) Converte a primeira letra deinitcap( 'hi Hi Thomas


THOMAS')
cada palavra em maiscula e
as demais em minsculas. As
palavras so seqncias de
caracteres alfanumricos
separadas por caracteres
no alfanumricos.

length( cadeia_de_ Nmero de caracteres length( 'Jos') 4


caracteres text)
presentes na cadeia_de_
caracteres.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 119


POSTGRESQL Banco de dados SQL

lpad( cadeia_de_ Preenche a cadeia_de_ lpad( 'hi', 5, 'xy')xyxhi


caracteres text,
comprimento integer [,
caracteres at o
preenchimento text]) comprimento adicionando os
caracteres de
preenchimento (espao por
padro) esquerda. Se
a cadeia_de_ caracteres
for mais longa que o
comprimento ento
truncada ( direita).

ltrim( cadeia_de_ Remove a cadeia de ltrim( trim


caracteres text [, 'zzzytrim',
caracteres text])
caracteres mais longa
'xyz')
contendo apenas caracteres
presentes em caracteres
(espao por padro) do incio
da cadeia_de_ caracteres.

md5( cadeia_de_ Calcula o MD5 da md5( 'abc') 900150983cd24fb0


caracteres text) d6963f7d28e17f72
cadeia_de_caracteres,
retornando o resultado em
hexadecimal.

pg_client_encoding() Nome da codificao atual pg_client_ LATIN1


encoding()
do cliente

quote_ident( cadeia_de_Retorna a cadeia de quote_ident( 'Foo "Foo bar"


caracteres text) bar')
caracteres fornecida
apropriadamente entre
aspas, para ser utilizada
como identificador na cadeia
de caracteres de um
comando SQL. As aspas so
adicionadas somente
quando h necessidade (ou
seja, se a cadeia de
caracteres contiver
caracteres
noidentificadores, ou se
contiver letras maisculas e
minsculas). As aspas

internas so devidamente
duplicadas.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 120


POSTGRESQL Banco de dados SQL

quote_literal( Retorna a cadeia de quote_literal( 'O''Reilly'


cadeia_de_ caracteres 'O\'Reilly')
text) caracteres fornecida
apropriadamente entre
apstrofos, para ser utilizada
como literal cadeia de
caracteres na cadeia de
caracteres de um comando
SQL. Os
apstrofos e contrabarras
embutidos so devidamente
duplicados.

repeat( cadeia_de_ Repete a repeat( 'Pg', 4) PgPgPgPg


caracteres text, nmero
integer)
cadeia_de_caracteres pelo
nmero de vezes especificado

replace( cadeia_de_ Substitui todas as replace( abXXefabXXef


caracteres text, origem 'abcdefabcdef',
text, destino text)
ocorrncias na
'cd', 'XX')
cadeia_de_
caracteres, da cadeia de
caracteres de origem pela
cadeia de caracteres de
destino.

rpad( cadeia_de_ Preenche a cadeia_de_ rpad( 'hi', 5, 'xy')hixyx


caracteres text,
caracteres at o
comprimento integer [,
preenchimento text]) comprimento anexando os
caracteres de
preenchimento (espao por
padro) direita. Se a
cadeia_de_ caracteres for
mais longa que o
comprimento, ento
truncada.

rtrim( cadeia_de_ Remove do final da rtrim( trim


caracteres text [, 'trimxxxx', 'x')
cadeia_de_caracteres, a
caracteres text])
cadeia de caracteres mais
longa contendo apenas os
caracteres presentes em
caracteres (espao por
padro).

Evolutiontech Treinamento e Desenvolvimento P g i n a | 121


POSTGRESQL Banco de dados SQL

split_part( cadeia_de_ Divide a split_part( def


caracteres text, cadeia_de_caracteres 'abc~@~def~@~ghi'
delimitador text, campo
utilizando o , '~@~', 2)
integer)

delimitador, retornando o
campo especificado
(contado a partir de 1).

strpos( cadeia_de_ Posio dos caracteres strpos( 'high', 2


caracteres, caracteres) 'ig')
especificados; o mesmo que
position( caracteres in
cadeia_de_ caracteres),
mas deve ser observada a
ordem invertida dos
argumentos

substr( cadeia_de_ Extrai a subcadeia de substr( ph


caracteres, origem 'alphabet', 3, 2)
caracteres caracteres; o
[, contador])
mesmo que substring(
cadeia_de_ caracteres from
origem for contador)

to_ascii( text [, Converte texto em outras to_ascii( Consequencia


codificao]) 'Conseqncia')
codificaes em ASCII a

to_hex( nmero integer Converte o nmero em sua to_hex( 7fffffff


ou bigint)
representao hexadecimal2147483647)
equivalente

translate( cadeia_de_ Todo caractere da translate( a23x5


caracteres text, origemcadeia_de_ caracteres '12345', '14',
text, destino text) 'ax')
que corresponde a um
caractere do conjunto
origem, substitudo pelo
caractere correspondente
do conjunto destino.

Tamanho de uma cadeia de caracteres com espao


direita
Abaixo so mostradas consultas que retornam como resultado o tamanho de uma cadeia de
caracteres com espao direita. Note que apenas a funo len do SQL Server 2000 no conta o
espao direita.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 122


POSTGRESQL Banco de dados SQL

=> SELECT length('1234567890 ');


length
--------
11
(1 linha)

Concatenao de cadeias de caracteres


Abaixo so mostradas consultas que retornam como resultado a concatenao de cadeias de
caracteres. Deve ser observado que o SQL Server 2000 usa o operador +, enquanto os demais
usam o operador || para concatenar cadeias de caracteres. Alm disso, o Oracle e o DB2 possuem
a funo concat, nativa, para concatenar duas cadeias de caracteres. Embora o PostgreSQL e o
SQL Server no possuam a funo concat nativa, esta pode ser facilmente definida neste dois
produtos.

=> SELECT 'ae' || 'io' || 'u' AS vogais;

vogais
--------
aeiou
(1 linha)

Evolutiontech Treinamento e Desenvolvimento P g i n a | 123


POSTGRESQL Banco de dados SQL

Converso de tipo
Os comandos SQL podem, intencionalmente ou no, usar tipos de dado diferentes na mesma
expresso. O PostgreSQL possui muitas funcionalidades para processar expresses com mistura
de tipos.
Em muitos casos no h necessidade do usurio compreender os detalhes do mecanismo de
converso de tipo. Entretanto, as converses implcitas feitas pelo PostgreSQL podem afetar o
resultado do comando. Quando for necessrio, os resultados podem ser personalizados utilizando
uma converso de tipo explcita.
Este captulo apresenta os mecanismos e as convenes de converso de tipo de dado do
PostgreSQL. Consulte as sees relevantes no Captulo 8 e no Captulo 9 para obter informaes
adicionais sobre tipos de dado especficos, e funes e operadores permitidos, respectivamente.

Viso geral sobre converso


A linguagem SQL uma linguagem fortemente tipada, ou seja, todo item de dado possui um tipo
de dado associado que determina seu comportamento e a utilizao permitida. O PostgreSQL
possui um sistema de tipo de dado extensvel, muito mais geral e flexvel do que o de outras
implementaes do SQL. Por isso, a maior parte do comportamento de converso de tipo de dado
do PostgreSQL governado por regras gerais, em vez de heursticas 1 ad hoc 2 , permitindo, assim,
expresses com tipos diferentes terem significado mesmo com tipos definidos pelo usurio.

Funes
A funo especfica a ser utilizada em uma chamada de funo determinada de acordo com os
seguintes passos.
Resoluo do tipo em funo

1. Selecionar no catlogo do sistema pg_proc as funes a serem consideradas. Se for


utilizado um nome de funo no qualificado, as funes consideradas so aquelas com nome
e nmero de argumentos corretos, visveis no caminho de procura corrente (consulte a Seo
5.8.3). Se for fornecido um nome de funo qualificado, somente so consideradas as funes
no esquema especificado.
a. Se forem encontradas no caminho de procura vrias funes com argumentos do
mesmo tipo, somente considerada quela que aparece primeiro no caminho. Mas as
funes com argumentos de tipos diferentes so consideradas em p de igualdade,
no importando a posio no caminho de procura.
2. Verificar se alguma funo aceita exatamente os mesmos tipos de dado dos argumentos de
entrada. Caso exista (s pode haver uma correspondncia exata no conjunto de funes
consideradas), esta usada. Os casos envolvendo o tipo unknown nunca encontram
correspondncia nesta etapa.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 124


POSTGRESQL Banco de dados SQL

3. Se no for encontrada nenhuma correspondncia exata, verificar se a chamada de funo


parece ser uma solicitao trivial de converso de tipo. Isto acontece quando a chamada de
funo possui apenas um argumento, e o nome da funo o mesmo nome (interno) de algum
tipo de dado. Alm disso, o argumento da funo deve ser um literal de tipo desconhecido, ou
um tipo binariamente compatvel com o tipo de dado do nome da funo. Quando estas
condies so satisfeitas, o argumento da funo convertido no tipo de dado do nome da
funo sem uma chamada real de funo.
4. Procurar pela melhor correspondncia.

a. Desprezar as funes candidatas para as quais os tipos da entrada no


correspondem, e nem podem ser convertidos (utilizando uma converso implcita)
para corresponder. Para esta finalidade assumido que os literais do tipo unknown
podem ser convertidos em qualquer tipo. Se permanecer apenas uma funo
candidata, ento esta usada; seno continuar na prxima etapa.
b. Examinar todas as funes candidatas, e manter aquelas com mais
correspondncias exatas com os tipos da entrada (Para esta finalidade os domnios so
considerados idnticos aos seus tipos base). Manter todas as funes candidatas se
nenhuma possuir alguma correspondncia exata. Se permanecer apenas uma funo
candidata, ento esta usada; seno continuar na prxima etapa.
c. Examinar todas as funes candidatas, e manter aquelas que aceitam os tipos
preferidos (da categoria de tipo do tipo de dado de entrada) em mais posies onde a
converso de tipo ser necessria. Manter todas as candidatas se nenhuma aceitar o
tipo preferido. Se permanecer apenas uma funo candidata, esta usada; seno
continuar na prxima etapa.
d. Se algum dos argumentos de entrada for do tipo unknown, verificar as categorias
de tipo aceitas nesta posio do argumento pelas funes candidatas remanescentes.
Em cada posio, selecionar a categoria string se qualquer uma das candidatas
aceitar esta categoria (este favorecimento em relao cadeia de caracteres
apropriado, porque um literal de tipo desconhecido se parece com uma cadeia de
caracteres). Seno, se todas as candidatas remanescentes aceitam a mesma categoria
de tipo, selecionar esta categoria; seno falhar, porque a escolha correta no pode ser
deduzida sem informaes adicionais. Rejeitar agora as funes candidatas que no
aceitam a categoria de tipo selecionada; alm disso, se alguma funo candidata
aceitar o tipo preferido em uma dada posio do argumento, rejeitar as candidatas
que aceitam tipos no preferidos para este argumento.
e. Se permanecer apenas uma funo candidata, este usada; Se no permanecer
nenhuma funo candidata, ou se permanecer mais de uma candidata, ento falhar.

Deve ser observado que as regras da melhor correspondncia so idnticas para a resoluo do
tipo em operador e funo. Seguem alguns exemplos.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 125


POSTGRESQL Banco de dados SQL

Resoluo do tipo do argumento em funo de arredondamento

Existe apenas uma funo round com dois argumentos (O primeiro numeric e o segundo
integer). Portanto, a consulta abaixo converte automaticamente o primeiro argumento do tipo
integer para numeric:

=> SELECT round(4, 4);


round
--------
4.0000
(1 linha)

Na verdade esta consulta convertida pelo analisador em

=> SELECT round(CAST (4 AS numeric), 4);

Uma vez que inicialmente atribudo o tipo numeric s constantes numricas com ponto decimal,
a consulta abaixo no necessita de converso de tipo podendo, portanto, ser ligeiramente mais
eficiente:
=> SELECT round(4.0, 4);

Resoluo do tipo em funo de subcadeia de caracteres


Existem diversas funes substr, uma das quais aceita os tipos text e integer. Se esta funo
for chamada com uma constante cadeia de caracteres de tipo no especificado, o sistema escolhe
a funo candidata que aceita o argumento da categoria preferida para string (que o tipo
text).

=> SELECT substr('1234', 3);


substr
--------
34
(1 linha)

Evolutiontech Treinamento e Desenvolvimento P g i n a | 126


POSTGRESQL Banco de dados SQL

ndices
Os ndices so um modo comum de melhorar o desempenho do banco de dados. O ndice permite
ao servidor de banco de dados encontrar e trazer linhas especficas muito mais rpido do que
faria sem o ndice. Entretanto, os ndices tambm produzem trabalho adicional para o sistema de
banco de dados como um todo devendo, portanto, serem utilizados com sensatez.

Suponha a existncia de uma tabela como:


CREATE TABLE teste1 (
id integer,
conteudo varchar
);

e um aplicativo requerendo muitas consultas da forma:

SELECT conteudo FROM teste1 WHERE id = constante;

Sem preparo prvio, o sistema teria que varrer toda a tabela teste1, linha por linha, para
encontrar todas as entradas correspondentes. Havendo muitas linhas em teste1, e somente
poucas linhas (talvez somente uma ou nenhuma) retornadas pela consulta, ento este mtodo
claramente ineficiente. Porm, se o sistema fosse instrudo para manter um ndice para a coluna
id, ento poderia ser utilizado um mtodo mais eficiente para localizar as linhas correspondentes.
Por exemplo, s necessitaria percorrer uns poucos nveis dentro da rvore de procura.
Uma abordagem semelhante utilizada pela maioria dos livros, fora os de fico: os termos e os
conceitos procurados freqentemente pelos leitores so reunidos em um ndice alfabtico
colocado no final do livro. O leitor interessado pode percorrer o ndice rapidamente e ir direto
para a pgina desejada, em vez de ter que ler o livro por inteiro em busca do que est
procurando. Assim como tarefa do autor prever os itens que os leitores mais provavelmente vo
procurar, tarefa do programador de banco de dados prever quais ndices traro benefcios.
Pode ser utilizado o seguinte comando para criar um ndice na coluna id:

CREATE INDEX idx_teste1_id ON teste1 (id);

O nome idx_teste1_id pode ser escolhido livremente, mas deve ser usado algo que permita
lembrar mais tarde para que serve o ndice.
Para remover um ndice utilizado o comando DROP INDEX. Os ndices podem ser adicionados ou
removidos das tabelas a qualquer instante.
Aps o ndice ser criado, no necessria mais nenhuma interveno adicional: o sistema atualiza
o ndice quando a tabela modificada, e utiliza o ndice nas consultas quando julgar mais eficiente
que a varredura seqencial da tabela. Porm, talvez seja necessrio executar regularmente o

Evolutiontech Treinamento e Desenvolvimento P g i n a | 127


POSTGRESQL Banco de dados SQL

comando ANALYZE para atualizar as estatsticas, para permitir que o planejador de comandos
tome as decises corretas. Consulte o Captulo 13 para obter informaes sobre como descobrir
se o ndice est sendo utilizado; e quando e porque o planejador pode decidir no utilizar um
ndice.
Os ndices tambm podem beneficiar os comandos de atualizao (UPDATE) e de excluso
(DELETE) com condio de procura. Alm disso, os ndices tambm podem ser utilizados em
consultas com juno. Portanto, um ndice definido em uma coluna que faa parte da condio de
juno pode acelerar, significativamente, a consulta.
Quando um ndice criado, o sistema precisa mant-lo sincronizado com a tabela. Isto adiciona
um trabalho extra para as operaes de manipulao de dados. Portanto, os ndices no
essenciais ou no utilizados devem ser removidos. Deve ser observado que uma consulta ou um
comando de manipulao de dados pode utilizar, no mximo, um ndice por tabela.

ndices com vrias colunas


Pode ser definido um ndice contendo mais de uma coluna. Por exemplo, se existir uma tabela
como:
CREATE TABLE teste2 (
principal int,
secundario int,
nome varchar );

(Digamos que seja armazenado no banco de dados o diretrio /dev...) e


freqentemente sejam feitas consultas como

SELECT nome
FROM teste2
WHERE principal = constante AND secundario = constante;

ento apropriado definir um ndice contendo as colunas principal e


secundario como, por exemplo,

CREATE INDEX idx_teste2_princ_sec ON teste2 (principal, secundario);


Atualmente, somente as implementaes de B-tree e GiST suportam ndices com vrias colunas.
Podem ser especificadas at 32 colunas (Este limite pode ser alterado durante a gerao do
PostgreSQL; consulte o arquivo pg_config_manual.h).
O planejador de comandos pode utilizar um ndice com vrias colunas, para comandos
envolvendo a coluna mais esquerda na definio do ndice mais qualquer nmero de colunas

Evolutiontech Treinamento e Desenvolvimento P g i n a | 128


POSTGRESQL Banco de dados SQL

listadas sua direita, sem omisses. Por exemplo, um ndice contendo (a, b, c) pode ser
utilizado em comandos envolvendo todas as colunas a, b e c, ou em comandos envolvendo a e b,
ou em comandos envolvendo apenas a, mas no em outras combinaes (Em um comando
envolvendo a e c, o planejador pode decidir utilizar o ndice apenas para a, tratando c como uma
coluna comum no indexada). Obviamente, cada coluna deve ser usada com os operadores
apropriados para o tipo do ndice; as clusulas envolvendo outros operadores no so
consideradas.
Os ndices com vrias colunas s podem ser utilizados se as clusulas envolvendo as colunas
indexadas forem ligadas por AND. Por exemplo,
SELECT nome
FROM teste2
WHERE principal = constante OR secundario = constante;
no pode utilizar o ndice idx_teste2_princ_sec definido acima para procurar pelas duas
colunas (Entretanto, pode ser utilizado para procurar apenas a coluna principal).
Os ndices com vrias colunas devem ser usados com moderao. Na maioria das vezes, um ndice
contendo apenas uma coluna suficiente, economizando espao e tempo. Um ndice com mais
de trs colunas quase certo no ser til, a menos que a utilizao da tabela seja muito peculiar.

ndices nicos
Os ndices tambm podem ser utilizados para impor a unicidade do valor de uma coluna, ou a
unicidade dos valores combinados de mais de uma coluna.

CREATE UNIQUE INDEX nome ON tabela (coluna [, ...]);

Quando o ndice declarado como nico, no pode existir na tabela mais de uma linha com
valores indexados iguais. Os valores nulos no so considerados iguais. Um ndice nico com
vrias colunas rejeita apenas os casos onde todas as colunas indexadas so iguais em duas linhas.
O PostgreSQL cria, automaticamente, um ndice nico quando definida na tabela uma restrio
de unicidade ou uma chave primria. O ndice abrange as colunas que compem a chave primria
ou as colunas nicas (um ndice com vrias colunas, se for apropriado), sendo este o mecanismo
que impe a restrio.

Examinar a utilizao do ndice


Embora no PostgreSQL os ndices no necessitem de manuteno e ajuste, ainda assim
importante verificar quais ndices so utilizados realmente pelos comandos executados no
ambiente de produo. O exame da utilizao de um ndice por um determinado comando feito
por meio do comando EXPLAIN; sua aplicao para esta finalidade est ilustrada na Seo 13.1.
Tambm possvel coletar estatsticas gerais sobre a utilizao dos ndices por um servidor em
operao da maneira descrita na Seo 23.2.
difcil formular um procedimento genrico para determinar quais ndices devem ser definidos.
Existem vrios casos tpicos que foram mostrados nos exemplos das sees anteriores. Muita

Evolutiontech Treinamento e Desenvolvimento P g i n a | 129


POSTGRESQL Banco de dados SQL

verificao experimental necessria na maioria dos casos. O restante desta seo d algumas
dicas.
O comando ANALYZE sempre deve ser executado primeiro. Este comando coleta
estatsticas sobre a distribuio dos valores na tabela. Esta informao necessria para estimar
o nmero de linhas retornadas pela consulta, que uma necessidade do planejador para atribuir
custos dentro da realidade para cada plano de comando possvel. Na ausncia de estatsticas
reais, so assumidos alguns valores padro, quase sempre imprecisos. O exame da utilizao do
ndice pelo aplicativo sem a execuo prvia do comando ANALYZE , portanto, uma causa
perdida.
Devem ser usados dados reais para a verificao experimental. O uso de dados de teste
para definir ndices diz quais ndices so necessrios para os dados de teste, e nada alm disso.
especialmente fatal utilizar conjuntos de dados de teste muito pequenos. Enquanto
selecionar 1.000 de cada 100.000 linhas pode ser um candidato para um ndice, selecionar 1 de
cada 100 linhas dificilmente ser, porque as 100 linhas provavelmente cabem dentro de uma
nica pgina do disco, e no existe nenhum plano melhor que uma busca seqencial em uma
pgina do disco.
Tambm deve ser tomado cuidado ao produzir os dados de teste, geralmente no disponveis
quando o aplicativo ainda no se encontra em produo. Valores muito semelhantes,
completamente aleatrios, ou inseridos ordenadamente, distorcem as estatsticas em relao
distribuio que os dados reais devem ter.
Quando os ndices no so usados, pode ser til como teste forar sua utilizao. Existem
parmetros em tempo de execuo que podem desativar vrios tipos de planos (descritos no
Seo 16.4). Por exemplo, desativar varreduras seqenciais (enable_seqscan) e junes de lao-
aninhado (enable_nestloop), que so os planos mais bsicos, foram o sistema a utilizar um
plano diferente. Se o sistema ainda assim escolher a varredura seqencial ou a juno de lao-
aninhado ento existe, provavelmente, algum problema mais fundamental devido ao qual o
ndice no est sendo utilizado como, por exemplo, a condio da consulta no corresponde ao
ndice (Qual tipo de consulta pode utilizar qual tipo de ndice explicado nas sees anteriores).
Se forar a utilizao do ndice no faz o ndice ser usado, ento existem duas
possibilidades: ou o sistema est correto e realmente a utilizao do ndice no apropriada, ou
a estimativa de custo dos planos de comando no esto refletindo a realidade. Portanto, deve
ser medido o tempo da consulta com e sem ndices. O comando EXPLAIN ANALYZE pode ser til
neste caso.
Se for descoberto que as estimativas de custo esto erradas existem, novamente, duas
possibilidades. O custo total calculado a partir do custo por linha de cada n do plano vezes a
seletividade estimada do n do plano. Os custos dos ns do plano podem ser ajustados usando
parmetros em tempo de execuo (descritos no Seo 16.4). A estimativa imprecisa da
seletividade devida a estatsticas insuficientes. possvel melhorar esta situao ajustando os
parmetros de captura de estatsticas (consulte o comando ALTER TABLE).
Se no for obtido sucesso no ajuste dos custos para ficarem mais apropriados, ento pode ser
necessrio o recurso de forar a utilizao do ndice explicitamente. Pode-se, tambm, desejar
fazer contato com os desenvolvedores do PostgreSQL para examinar este problema.

Evolutiontech Treinamento e Desenvolvimento P g i n a | 130