Home Map Index Search News Archives Links About LF
[Top Bar]
[Bottom Bar]
[Foto do Autor]
Manuel Soriano
Sobre o Autor: [escreva um pouco de sua biografia aqui]

Conte�do:
Introdu��o
Cria��o de uma Tabela
Sintaxe
Nota
Modifica��o de Uma Tabela
Inser��o de dados em uma Tabela
Sele��o de dados
Detalhes do where
Comando update
Comando delete
Referencias
Outros artigos do autor

SQL Tutorial
Part II

[Ilustration]

Abstrato: [A segunda parte do tutorial revisa v�rios aspectos b�sicos da linguagem SQL...]




Introdu��o

Esta � a segunda parte do curso de SQL, nesta parte vamos nos centrar nos civersos comandos SQL, desde a cria��o da tabela, sua modifica��o e/ou dele��o.

Nos centraremos, sobretudo, no comando SELECT, que �, a meu modo de ver, o mais importante de todos.

Espero que esta segunda parte seja amena e instrutiva.

Cria��o de uma tabela

Como vimos na primeira parte, para criar uma tabela, usamos o comando CREATE com o qualificativo TABLE, com efeito, o comando CREATE serve para criar:

- usuario : CREATE USER
- tabelas : CREATE TABLE
- indices : CREATE INDEX
- visualizar : CREATE VIEW

O comando create indica ao gerenciador que temos alguma coisa a criar, logo mostraremos aqui e como.

O que nos interessa no momento � a cria��o de uma tabela:

Syntaxe

CREATE TABLE nome ( coluna tipo [DEFAULT valor] [NOT NULL], ...
      [INHERITS (herda, ...)]
      [CONSTRAINT nom_cons CHECK (prova), CHECK (prova)] );
Onde :
Nome � o nome que se d� � tabela e como ser� referenciada por qualquer comando.
Coluna � o nome como vamos conhecer esta coluna.
Tipo � o tipo de dado (varchar, char, int, date, time, timestamp), postgres temos outros tipos de dados, mas n�o s�o compat�veis com SQL Ansi.
Valor O valor que ter� por default.
Herda Este � o pr�prio Postgres, define uma heran�a de outra tabela, isto �, criar� uma entidade que cont�m as colunas da tabela que estamos criando e as heran�as.
Nom_cons Isto define uma regra de integridade a respeitar cada vez que modificamos uma tabela.
Prova Condi��o a comprovar.
Exemplo :

CREATE TABLE paises (
         cod_pais integer NOT NULL,
         nome varchar(30))
   CONSTRAINT cod_raro CHECK (cod_pais > 0 AND cod_pais < 154);

Com este exemplo criamos uma tabela de pa�ses, cada vez que inserimos um novo dado, cumpriremos estas condi��es :

- o c�digo do pa�s n�o ser� NULO, se tentarmos por um c�digo NULO, o gerenciador nos retornar� uma mensagem de erro :

ExecAppend: Fail to add null value in not null attribute cod_pais

- o c�digo do pais ser� superior a 0 ou inferior a 154, se tentarmos inserir um c�digo do pais diferente, o gerenciador nos retornar� com uma mensagem de erro :

ExecAppend: rejected due to CHECK constraint cod_raro

Nota

O que quer dizer NULO? Em SQL existe dois estados, dados ou N�O dados, com efeito podemos nos interessar por um campo que n�o tenha dados, tanto o zero (0), como o espa�o s�o dados. SQL introduz o conceito de NULO e trabalha com NIL, um exemplo pr�tico :

Tenho uma tabela com registro de faturas, com os seguintes campos:

cliente, importe, data_emision, data_pago

Quando crio a tabela, inserirei os dados:

cliente, importe, data_emision

Deixarei a data_pago em branco, desta forma poderei conhecer todas as faturas n�o pagas com o seguinte comando :

SELECT * FROM facturas WHERE data_pago IS NULL;

Algu�m pode alegar que um zero (0) no campo data_pago, faria o mesmo papel, � verdade, salvo que zero (0), n�o � uma data e me impede de criar data_pago do tipo data e poder aplicar-lhe as fun��es pr�prias de datas.

Exemplos de cria��o com NULOS :

insert into paises values (15, NULL);

ou :

insert into paises (cod_pais) values (27);

a ausencia do campo (nome) implica que este receber� o valor NULO.

Modifica��o de uma tabela

No PostgreSQL a modifica��o s� sera completa com o acrescimo de nova(s) coluna(s).

ALTER TABLE tabela ADD nome tipo;

Onde :

Tabela Nome da tabela a modificar
Nome Nome da coluna a acrescentar
Tipo Tipo de dados (ver CREATE TABLE)

Inser��o de dados numa tabela

Agora vamos inserir dados na nossa tabela :

SINTAXE :

INSERT INTO tabela [(coluna, coluna, ...)] VALUES (valor-1, valor-2, ...)

ou :

INSERT INTO tabela [(coluna, coluna, ...)] SELECT ....

Como vimos existe duas maneiras de inserirmos dados numa tabela, seja linha a linha ou o resultado de uma sub-sele��o que pode devolver uma ou v�rias tabelas.

Quando inserimos linhas em uma tabela, SEMPRE poremos dados em todas as colunas inclusive nas que mencionamos, estas foram criadas com valores NULOS.

Se no comando n�o especificamos que colunas vamos preencher, entendemos que vamos por dados em todas, exemplo :

INSERT INTO paises VALUES (34, 'Espaqa');

Isto estaria errado :

INSERT INTO paises VALUES (34);
Mas, isto sim, estaria correto:

INSERT INTO paises (cod_pais) VALUES (34);

eu recomendo que em comandos embutidos em programas em C ou em fun��es do banco de dados SEMPRE especifiquemos as colunas que vamos trabalhar, e se acrescentamos uma nova coluna na tabela (ALTER TABLE), o pr�ximo INSERT, acusar� um erro, Exemplo :


INSERT INTO paises VALUES (34, 'Espaqa');

INSERT 18301 1

ALTER TABLE paises add poblacion integer

INSERT INTO paises VALUES (34, 'Espaqa');

Isto daria um erro, j� que falta o dado para popula��o.

Nota

PostgreSQL, n�o gera erro, cria a linha com o campo (popula��o) NULO, e isto � s� uma particularidade do PostgreSQL, qualquer outro gerenciador SQL acusar� um erro.

Logo, nos sobra o outro tipo de INSERT, o que utiliza uma sub-sele��o.

Este tipo de insert realiza, muito frequentemente, para criar tabelas temporais ou tabelas para realizar uma tarefa muito concreta de calculos especulativos.

A parte substituida � a que toca os dados, eles vem dados por uma instru��o SELECT que se realizava previamente com a inser��o dos dados. A instru��o SELECT pode devolver uma ou v�rias tabelas, esta instru��o SELECT tem as mesmas restri��es que a pr�pria SELECT.

Sele��o de dados

Era aqui que eu queria chegar! :-))

Temos topado com a fortaleza dos comandos SQL, a linguagem SQL sem SELECT seria como as lentilhas sem chori�o (olha que pus dificuldades para os tradutores :-)

O comando SELECT nos permite acessar aos dados, mas com a ressalva que pode realizar buscas, uni�o de tabelas, fun��es sobre os dados ou sobre as regras de busca (predicado)

Um exemplo :

select * from paises;

Outro exemplo :

SELECT a.nombre, SUM(popula��o)
    FROM paises a, provincias b, municipios c
    WHERE b.cod_pais = a.cod_pais
        AND (c.cod_pais = b.cod_pais
        AND c.cod_provincia = b.cod_provincia)
        AND popula��o IS NOT NULL
        GROUP BY a.nombre
        ORDER BY sum ASC;

Eu explico, ped� a popula��o de todos os pa�ses em ordem por popula��o em modo ascendente, simples.! N�O ! 8-O

Bem, para isso, acrescentei uma nova coluna (popula��o) a tabela municipios.

Isto fica assim :
create table municipios (cod_pais int, 
			cod_provincia int, 
			cod_municipio int,
			nombre_municipio varchar(60),
			popula��o int);
insert into municipios values (1, 1, 1, 'Pais 1, Provincia 1, Municipio 1', 5435);
insert into municipios values (2, 1, 1, 'Pais 2, Provincia 1, Municipio 1', 7832);
insert into municipios values (3, 1, 1, 'Pais 3, Provincia 1, Municipio 1', 4129);
insert into municipios values (1, 2, 1, 'Pais 1, Provincia 2, Municipio 1', 76529);
insert into municipios values (2, 2, 1, 'Pais 2, Provincia 2, Municipio 1', 9782);
insert into municipios values (3, 2, 1, 'Pais 3, Provincia 2, Municipio 1', 852);
insert into municipios values (1, 3, 1, 'Pais 1, Provincia 3, Municipio 1', 3433);
insert into municipios values (2, 3, 1, 'Pais 2, Provincia 3, Municipio 1', 7622);
insert into municipios values (3, 3, 1, 'Pais 3, Provincia 3, Municipio 1', 2798);
insert into municipios values (1, 1, 2, 'Pais 1, Provincia 1, Municipio 2', 7789);
insert into municipios values (2, 1, 2, 'Pais 2, Provincia 1, Municipio 2', 76511);
insert into municipios values (3, 1, 2, 'Pais 3, Provincia 1, Municipio 2', 98);
insert into municipios values (1, 2, 2, 'Pais 1, Provincia 2, Municipio 2', 123865);
insert into municipios values (2, 2, 2, 'Pais 2, Provincia 2, Municipio 2', 886633);
insert into municipios values (3, 2, 2, 'Pais 3, Provincia 2, Municipio 2', 982345);
insert into municipios values (1, 3, 2, 'Pais 1, Provincia 3, Municipio 2', 22344);
insert into municipios values (2, 3, 2, 'Pais 2, Provincia 3, Municipio 2', 179);
insert into municipios values (3, 3, 2, 'Pais 3, Provincia 3, Municipio 2', 196813);
insert into municipios values (1, 1, 3, 'Pais 1, Provincia 1, Municipio 3', 491301);
insert into municipios values (2, 1, 3, 'Pais 2, Provincia 1, Municipio 3', 166540);
insert into municipios values (3, 1, 3, 'Pais 3, Provincia 1, Municipio 3', 165132);
insert into municipios values (1, 2, 3, 'Pais 1, Provincia 2, Municipio 3', 0640);
insert into municipios values (2, 2, 3, 'Pais 2, Provincia 2, Municipio 3', 65120);
insert into municipios values (3, 2, 3, 'Pais 3, Provincia 2, Municipio 3', 1651462);
insert into municipios values (1, 3, 3, 'Pais 1, Provincia 3, Municipio 3', 60650);
insert into municipios values (2, 3, 3, 'Pais 2, Provincia 3, Municipio 3', 651986);
insert into municipios values (3, 3, 3, 'Pais 3, Provincia 3, Municipio 3', NULL);
commit work;

Eu sei que poder�amos fazer por ALTER TABLE, mas deveria usar o UPDATE e ainda n�o os expliquei, assim se quiserem usem "cut & paste" e felicidades :-))

Agora vamos executar a pesquisa (QUERY), e o resultado deveria ser :

nome|    sum
------+-------
pais 1| 705559
pais 2|1212418
pais 3|2804018
(3 rows)
Agora verificamos :

select sum(popula��o) from municipios where cod_pais = 1;

Resultado :
   sum
------
791986
(1 row)

!!!!!! UMA DIFEREN�A !!!!!!!!!!

Olhemos a tabela das provincias, falta a provincia 3, fa�amos :

INSERT INTO PROVINCIAS VALUES (3, 1, 'Provincia 3, Pais 1');
INSERT INTO PROVINCIAS VALUES (3, 2, 'Provincia 3, Pais 2');
INSERT INTO PROVINCIAS VALUES (3, 3, 'Provincia 3, Pais 3');

E repetimos o comando, resultado :
nome|    sum
------+-------
pais 1| 791986
pais 2|1872205
pais 3|3003629 

Nos faltava a provincia 3 de cada pais.

Agora para os que tenham se perdido, lembremo-nos que as conjun��es entre tabelas eram EXATAS, quer dizer, somente extrai dados se a condi��o dentro do predicado � exato.

Olhemos a primeira parte do WHERE : b.cod_pais = a.cod_pais

Isto quer dizer que junto da tabela paises at� provincia sempre que o c�digo do pa�s seja igual, agora recordemos os dados dos pa�ses que inserimos :

N�o o execute, � s� ilustra��o.

create table paises (cod_pais integer, nome varchar(30));
insert into paises values (1, 'pais 1');
insert into paises values (2, 'pais 2');
insert into paises values (3, 'pais 3');
commit work;
Agora os dados das provinvias :
create table provincias (cod_provincia int, 
			cod_pais int, 
			nom_provincia varchar(30));
insert into provincias values (1, 1, 'Provincia 1, Pais 1');
insert into provincias values (2, 1, 'Provincia 2, Pais 1');
insert into provincias values (1, 2, 'Provincia 1, Pais 2');
insert into provincias values (2, 2, 'Provincia 2, Pais 2');
insert into provincias values (1, 3, 'Provincia 1, Pais 3');
insert into provincias values (2, 3, 'Provincia 2, Pais 3');
commit work;
Faltam todas as provincias 3 de cada pa�s, mas na tabela de munic�pio est�o todos os dados das provinvias com c�digo 3, assim que � normal que n�o some-se os dados dos munic�pios das prov�ncias com c�digo 3, pode ser descartada a segunda parte do where :
        AND (c.cod_pais = b.cod_pais
        AND c.cod_provincia = b.cod_provincia)

A provincia existia na tabela dos municipios mas N�O na tabela das provincias.

Para os que n�o entenderam, tome uma aspirina, ou v� passear com o cachorro (se n�o tem cachorro v� passear sem cachorro), respirar um pouco de ar puro e volte a come�ar desde a primeira parte.

� muito importante comprender como realizamos as conjun��es de dados, sem ele, os desenvolvimentos que fizemos podem ter resultados imprevisiveis.

Fechemos os parenteses e comecemos com a sintaxe do comando SELECT.

SELECT [DISTINCT] expresion1 [AS nom-atributo] {, expresion-i [as nom-atributo-i]} 
       [INTO TABLE classname] 
       [FROM from-list] 
       [WHERE where-clause] 
       [GROUP BY attr_name1 {, attr_name-i....}] 
       [ORDER BY attr_name1 [ASC | DESC ] [USING op1 ] {, nom-atributo-i...}] 
       [UNION {ALL} SELECT ...] 
Passo a passo :
DISTINCT : isto � para eliminar tabelas duplicadas na sa�da.
expresion1 : queremos na sa�da, normalmente uma coluna de uma tabela da lista FROM.
AS nom-atributo : um alias para o nome da coluna, exemplo:
manu=> select cod_pais from paises;
cod_pais
--------
       1
       2
       3
(3 rows)          
Agora con o alias :
manu=> select cod_pais as pasi from paises;
pasi
----
   1
   2
   3
(3 rows)
INTO TABLE : permite inserir as tabelas resultantes diretamente em outra tabela . (ver INSERT ... SELECT...)
FROM : lista das tabelas na entrada
WHERE : predicado da sele��o (crit�rios de uni�o e sele��o).
GROUP BY : Crit�rio de agrupamento, certas fun��es que usamos na (expresion) podemos precisar de um agrupamento, quer dizer, um crit�rio de discrimina��o e resultado.
ORDER BY : Criterio de ordena��o das tabelas de sa�das. ASC ordem ascendente, DESC ordem descendente, USING define se a ordem da coluna n�o est� na lista (express�o...)
UNION ALL SELECT : Isto define se acrescento al resultado do primeiro SELECT ao segundo SELECT que pode ser de tabelas distintas, mas devolvendo o mesmo n�mero de colunas.

Vimos que os comandos SELECT n�o s� devolvem os dados do BD, sim que tamb�m pode modific�-los :


SELECT SUM(saldo * 1.1) - SUM(saldo) AS incremento FROM empregados;

Nos mostra o incremento de 10% a pagar no saldo.

Vamos ver quais as fun��es que temos a nossa disposi��o :

COUNT() : mostra a quantidade de tabelas n�o NULAS
SUM() : mostra a soma total de uma coluna num�rica.
AVG() : mostra o pre�o medio de uma coluna num�rica.
MIN() : mostra o valor m�nimo de uma coluna
MAX() : mostra o valor m�ximo de uma coluna
FLOAT(int) : mostra um FLOAT8, FLOAT(12345)
FLOAT4(int) : mostra um FLOAT4, FLOAT4(12345)
INT(float) : mostra um INT de um FLOAT/4, INT(123.456)
LOWER(texto) : mostra um texto em min�sculas.
UPPER(texto) : mostra texto em mai�sculas.
LPAD(texto, long, char) : preenche a esquerda com "char" no comprimeiro "long" da coluna "texto"
RPAD(texto, long, char) : preenche a direita com "char" no comprimento "long" da coluna "texto"
LTRIM(texto, char) : apaga a esquerda de "texto" todo caractere "char"
RTRIM(texto, char) : apaga a direita de "texto" todo caractere "char"
POSITION(cadeia IN texto) : extrai do "texto" a posi��o da "cadeia", mas N�O FUNCIONA
SUBSTR(texto,desde[,at�]) : extrai a sub-cadeia de "texto", da primeira posi�ao "de sde" at� a posi��o "at�" o final da cadeia
DATETIME(data, hora) : converte o formato datetime em data (AAAA-MM-DD) em hora (HH:MM)

Estas s�o algumas fun��es em SQL, s�o as que est�o definidas em SQL ANSI e est�o presentes no Postgres95.

Detalhes do where

At� agora vimos que na sess�o WHERE do SELECT coloc�vamos coisas como :

AND coluna = valor

Isto � uma pequena mostra do que podemos por ou combinar :

AND, OR, NOT, IN, IN ALL, =, !=, >, <, (SELECT....), LIKE lembrando que os parenteses tem relevancia, exemplos :

WHERE 
   coluna IN (SELECT DISTINCT coluna FROM tabela WHERE ....)
   coluna IN ('valor1','valor2','valor3',...)
   (coluna = 'valor' and coluna = 'outro_valor' OR coluna != 'valor')
!= � igual que dizer NOT EQUAL

LIKE permite procurar uma cadeia dentro de uma coluna com comodines :

WHERE coluna LIKE '%Pepito%'

El % � um comodim, no exemplo, ser� verdadeiro se "Pepito" est� na string.

WHERE coluna LIKE 'Pepito%'


WHERE coluna LIKE '%Pepito'

ser� verdeiro se "Pepito" est� no final da string.

Por aqui todas as op��es poss�veis do WHERE sai de minhas poss�bilidades e tempo, s� cabe aqui dizer que o limite est� na m�quina do programador e os limites do pr�prio tradutor do gerenciador.

Agora podemos deixar o comando SELECT e centrarmos nos dois �ltimos.

Comando update

O comando update permite modificar uma ou v�rias tabelas, dependendo da condi��o no WHERE.

SINTAXE
UPDATE tabela SET coluna-1 = expres�o-1 
                 [, coluna-i = expres�o-i] 
       [WHERE condi��o] 
Onde : tabela : � a tabela para modificar, s� poderemos modificar uma tabela por vez coluna : � a coluna a ser modificada expres�o : � o valor que vai receber a coluna, este valor pode ser est�tico ou o resultado de uma fun��o condi��o : � a condi��o que define o ambito do trabalho da modifica��o, aqui s�o aplicadas todas as regras definidas para o comando SELECT

Comando delete

O comando DELETE permite modificar uma ou v�rias colunas de uma tabela.

SINTAXE

DELETE FROM tabela
       [WHERE condi��o] 
Onde :
tabela : � a tabela onde vamos apagar, s� podemos apagar uma tabela por vez
condi��o : � a condi��o que define o ambito de trabalho de exclus�o, aqui s�o aplic�veis todas as regras definidas para o SELECT

NOTA : se n�o existir WHERE, DELETE eliminar� todas as colunas da tabela.

Referencias

Outros artigos do autor


Esta p�gina web � mantida por Miguel Angel Sepulveda
© Author 1998
LinuxFocus 1998