Escolar Documentos
Profissional Documentos
Cultura Documentos
Tutorial de SQL
O que é SQL
As aplicações em rede são cada dia mais numerosas e versáteis. Em muitos casos, o esquema
básico de operação é uma série de scripts que dirigem o comportamento de uma base de
dados.
É justamente disso que se trata o Structured Query Language que não é mais do que uma
linguagem padrão de comunicação com base de dados. Falamos portanto, de uma linguagem
normalizada que nos permite trabalhar com qualquer tipo de linguagem (ASP ou PHP) em
combinação com qualquer tipo de base de dados (MS Access, SQL Server, MySQL...).
O fato de ser padrão não quer dizer que seja idêntico para cada base de dados. Na prática,
determinadas bases de dados implementam funções específicas que não têm necessariamente
que funcionar em outras.
À parte desta universalidade, o SQL possui outras duas características muito apreciadas. Por
uma parte, apresenta potência e versatilidade notáveis que contrasta, por outra, com sua
acessibilidade de aprendizagem.
Tipos de campos
Como sabemos, um banco de dados é composto por tabelas onde armazenamos registros
catalogados em função de diferentes campos (características).
Um aspecto prévio a considerar é a natureza dos valores que introduzimos nesses campos.
Visto que um banco de dados trabalha com todo o tipo de informações, é importante especificar
que tipo de valor estamos introduzindo de maneira a, por um lado, facilitar a busca
posteriormente e por outro, otimizar os recursos de memória.
Cada banco de dados introduz tipos de valores de campo que não necessariamente estão
presentes em outros. Entretanto, existe um conjunto de tipos que estão representados na
totalidade destes bancos. Estes tipos comuns são os seguintes:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 2 of 90
Um exemplo simples a partir da nossa tabela modelo é a introdução de um novo cliente que
seria feito com uma instrução deste tipo:
Insert Into clientes (nome, sobrenomes, endereço, cidade, código postal, e-mail, pedidos)
Values ('Pedro', 'Palotes', 'Percebe n°13', 'Londrina', '123456', 'pedro@criarweb.com', 33)
Como se pode ver, os campos não numéricos ou booleanos vão delimitados por apóstrofes: '.
Também é interessante ver que o código postal foi salvo como um campo não numérico. Isto é
devido a que em determinados países (Inglaterra,por exemplo) os códigos postais contém
também letras.
Nota: Se desejarmos praticar com um banco de dados que está vazio, primeiro devemos criar as tabelas
que vamos preencher. As tabelas também se criam com sentenças SQL e aprendemos a fazer isso no
último capítulo.
Embora, de qualquer forma, pode ser que seja mais cômodo utilizar um programa com interface gráfica,
como Access, que pode nos servir para criar as tabelas em banco de dados do próprio Access ou por ODBC
a outros bancos de dados como SQL Server ou MySQL, por dar dois exemplos.
Outra possibilidade em um banco de dados como MySQL, seria criar as tabelas utilizando um software
como PhpMyAdmin.
Obviamente, não é imprescindível preencher todos os campos do registro. Porém, poder ser
que determinados campos sejam necessários. Estes campos necessários podem ser definidos
quando construirmos nossa tabela mediante o banco de dados.
Nota: Se não inserirmos um dos campos no banco de dados se iniciará com o valor padrão que tivermos
definido na hora de criar a tabela. Se não houver um valor padrão, provavelmente se inicie como NULL
(vazio), no caso de que este campo permita valores nulos. Se esse campo não permitir valores nulos (isso
se define também ao criar a tabela) o mais seguro é que a execução da sentença SQL nos dê um erro.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 3 of 90
número exclusivo do cliente que será muito útil quando consultarmos várias tabelas
simultaneamente.
Apagar um registro
Para apagar um registro nos servimos da instrução Delete. Neste caso devemos especificar qual
ou quais são os registros que queremos apagar. Por isso, é necessário estabelecer uma seleção
que se realize mediante a cláusula Where.
Nota: Se desejarmos praticar com um banco de dados que estiver vazio, primeiro devemos criar as
tabelas que vamos preencher. As tabelas também se criam com sentenças SQL que aprendemos a fazer no
último capítulo.
Se quisermos, por exemplo, apagar todos os registros dos clientes que se chamarem Pedro,
faríamos da seguinte forma:
Temos que ter cuidado com esta instrução, pois se não especificarmos uma condição com
Where, o que estamos fazendo é apagar toda a tabela:
Atualizar um registro
Update é a instrução que nos serve para modificar nossos registros. Como para o caso de
Delete, necessitamos especificar por meio de Where quais são os registros que queremos fazer
efetivas nossas modificações. Ademais, obviamente, teremos que especificar quais são os novos
valores dos campos que desejamos atualizar. A sintaxe é deste tipo:
Um exemplo aplicado:
Mediante esta sentença mudamos o nome Pedro por José em todos os registros cujo nome seja
Pedro.
Aqui também há que ser cuidadoso de não esquecer de usar Where, do contrário,
modificaríamos todos os registros de nossa tabela.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 4 of 90
Seleção de tabelas I
A seleção total ou parcial de uma tabela se realiza mediante a instrução Select. Em tal seleção
há que especificar:
Em nossa tabela modelo de clientes poderíamos fazer, por exemplo, uma seleção do nome e
endereço dos clientes com uma instrução deste tipo:
Também é muito útil filtrar os registros mediante condições que vêem expressas depois da
cláusula Where. Se quiséssemos mostrar os clientes de uma determinada cidade usaríamos
uma expressão como esta:
Select * From clientes Where cidade Like 'Rio de janeiro' Order By nome
Tendo em conta que pode haver mais de um cliente com o esmo nome, poderíamos dar um
segundo critério que poderia ser o sobrenome:
Select * From clientes Where cidade Like 'Rio de Janeiro' Order By nome, sobrenome
Se invertêssemos a ordem " nome,sobrenome " por " sobrenome, nome ", o resultado seria
diferente. Teríamos os clientes ordenados por sobrenome e aqueles que tivessem sobrenomes
idênticos se sub-classificariam pelo nome.
É possível também classificar por ordem inversa. Se por exemplo quiséssemos ver nossos
clientes por ordem de pedidos realizados tendo aos maiores em primeiro lugar escreveríamos
algo assim:
Assim evitaríamos ver repetido Rio de Janeiro tantas vezes quantos clientes tivermos nessa
cidade.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 5 of 90
Mail: ruben@desarrolloweb.com
Seleção de tabelas II
Quisemos compilar na forma de tabela certos operadores que podem ser úteis em determinados
casos. Estes operadores serão utilizados depois da cláusula Where e podem ser combinados
habilmente mediante parênteses para otimizar nossa seleção a níveis bastante altos.
Operadores matemáticos:
> Maior que
< Menor que
>= Maior ou igual que
<= Menor ou igual que
<> Diferente
= Igual
Operadores lógicos
And
Or
Not
Outros operadores
Seleciona os registros cujo valor de campo se assemelhe, não tendo em
Like
conta maiúsculas e minúsculas.
Dá um conjunto de valores para um campo para os quais a condição de
In e Not In
seleção é (ou não) válida
Is Null e Is Not
Seleciona aqueles registros onde o campo especificado está (ou não) vazio.
Null
Between...And Seleciona os registros compreendidos em um intervalo
Distinct Seleciona os registros não coincidentes
Desc Classifica os registros por ordem inversa
Curingas
* Substitui a todos os campos
% Substitui a qualquer coisa ou nada dentro de uma cadeia
_ Substitui só um caractere dentro de uma cadeia
Nesta sentença selecionamos todos os clientes de Salvador cujo nome não seja Jose. Como se
pode ver, empregamos Like ao invés de = simplesmente para evitar inconvenientes devido ao
emprego ou não de maiúsculas.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 6 of 90
Select * From clientes Where cidade Like 'salvador' And Not nome Like 'Jose'
Se quiséssemos recolher em uma seleção aos clientes de nossa tabela cujo sobrenome
começa por A e cujo número de pedidos esteja compreendido entre 20 e 40:
Select * From clientes Where sobrenomes like 'A%' And pedidos Between 20 And 40
O operador In, será visto mais adiante, é muito prático para consultas em várias tabelas. Para
casos em uma única tabela é empregada da seguinte forma:
Desta forma selecionamos aqueles clientes que vivem nessas três cidades.
Fazendo referência ao nosso clássico exemplo de um banco de dados para uma aplicação de e-
comercio, a tabela clientes que estivemos falando pode estar perfeitamente coordenada com
uma tabela onde armazenamos os pedidos realizados por cada cliente. Esta tabela de pedidos
pode por sua vez, estar conectada com uma tabela onde armazenamos os dados
correspondentes a cada artigo do inventário.
Deste modo poderíamos facilmente obter informações contidas nessas três tabelas como pode
ser a designação do artigo mais popular em uma determinada região onde a designação do
artigo seria obtida na tabela de artigos, a popularidade (quantidade de vezes que esse artigo foi
vendido) viria da tabela de pedidos e a região estaria compreendida obviamente na tabela
clientes.
Este tipo de organização baseada em múltiplas tabelas conectadas nos permite trabalhar com
tabelas muito mais manejáveis e ao mesmo tempo, nos evita copiar o mesmo campo em vários
lugares já que podemos acessa-lo a partir de uma simples chamada à tabela que o contém.
Neste capítulo veremos como, usando o que foi aprendido até agora, podemos realizar
facilmente seleções sobre várias tabelas. Definiremos antes de nada as diferentes tabelas e
campos que vamos utilizar em nossos exemplos:
Tabela de clientes
Nome campo Tipo campo
id_cliente Numérico inteiro
nome Texto
sobrenomes Texto
endereço Texto
cidade Texto
cep Texto
telefone Numérico inteiro
email Texto
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 7 of 90
Tabela de pedidos
Nome campo Tipo campo
id_pedido Numérico inteiro
id_cliente Numérico inteiro
id_artigo Numérico inteiro
data Data
quantidade Numérico inteiro
Tabela de artigos
Nome campo Tipo campo
id_artigo Numérico inteiro
titulo Alfanumérico
autor Alfanumérico
editorial Alfanumérico
preço Numérico real
Estas tabelas podem ser utilizadas simultaneamente para extrair informações de todo tipo.
Suponhamos que queremos enviar um mailing a todos aqueles que tiverem realizado um pedido
nesse mesmo dia. Poderíamos escrever algo assim:
Como pode ser visto desta vez, depois da cláusula From, introduzimos o nome das duas tabelas
de onde tiramos as informações. Ademais, o nome de cada campo vai precedido da tabela de
proveniência separado ambos por um ponto. Nos campos que possuem um nome que só
aparece em uma das tabelas, não é necessário especificar sua origem embora na hora de ler
sua sentença possa ser mais claro tendo esta informação mais precisa. Neste caso, o campo
data poderia ter sido designado como "data" ao invés de "pedidos.data".
Vejamos outro exemplo mais para consolidar estes novos conceitos. Desta vez queremos ver o
título do livro correspondente a cada um dos pedidos realizados:
Na verdade a filosofia continua sendo a mesma que para a consulta de uma única tabela.
Seleção de tabelas IV
Além dos critérios até agora explicados para realizar as consultas em tabelas, SQL permite
também aplicar um conjunto de funções pré-definidas. Estas funções, embora sejam básicas,
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 8 of 90
podem nos ajudar em alguns momentos a expressar nossa seleção de uma maneira mais
simples sem ter que recorrer a operações adicionais por parte do script que estivermos
executando.
Função Descrição
Soma(campo) Calcula a soma dos registros do campo especificado
Avg(Campo) Calcula a média dos registros do campo especificado
Count(*) Proporciona o valor do número de registros que foram selecionados
Max(Campo) Indica qual é o valor máximo do campo
Min(Campo) Indica qual é o valor mínimo do campo
Dado que o campo da função não existe no banco de dados, pois o estamos gerando
virtualmente, isto pode criar inconvenientes quando estivermos trabalhando com nossos scripts
na hora de tratar seu valor e seu nome de campo. É por isso que o valor da função tem que
ser recuperada a partir de um apelido que nós especificaremos na sentença SQL a partir da
instrução AS. A coisa poderia ficar assim:
A partir desta sentença calculamos a soma dos valores de todos os pedidos realizados e
armazenamos esse valor em um campo virtual chamado soma_pedidos que poderá ser utilizado
como qualquer outro campo por nossas páginas dinâmicas.
Obviamente, tudo que foi visto até agora pode ser aplicado neste tipo de funções de modo que,
por exemplo, podemos estabelecer condições com a cláusula Where construindo sentenças
como esta:
Outra propriedade interessante destas funções é que permitem realizar operações com
vários campos dentro de um mesmo parênteses:
Esta sentença dá como resultado o preço médio que estão sendo vendidos os livros. Este
resultado não tem porquê coincidir com o do preço médio dos livros presentes no
inventário, já que, pode ser que as pessoas tenham tendência a comprar os livros caros ou os
baratos:
Uma cláusula interessante no uso das funções é Group By. Esta cláusula nos permite agrupar
registros aos quais vamos aplicar a função. Podemos por exemplo calcular o dinheiro gastado
por cada cliente:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 9 of 90
As possibilidades como vemos são numerosas e pode ser práticas. Agora tudo fica à disposição
de nossas ocorrências e imaginação.
Mas o banco de dados por sí não opera milagres. É necessária a presença de um profissional
conhecedor de suas ferramentas e entranhas para tirar dele tudo aquilo que é possível. Este
profissional normalmente conhecido por DBA (Database Administrator) é a peça fundamental
neste processo.
Por outro lado, os desenvolvedores de software mesmo não sendo especialistas em bancos de
dados como os DBA's, podem (e devem) aproveitar um pouco do que é oferecido por estas
ferramentas para criar aplicações mais rápidas, mais enxutas e mais “limpas”, aproveitando
funções existentes mas que na maioria das vezes são esquecidas no momento do
desenvolvimento. Sobre isso que vamos falar hoje: aproveitamento de funções de bancos de
dados.
Obs: neste artigo usarei exemplos com o banco de dados MySQL e a linguagem PHP. Entretanto
com toda a certeza eles podem ser usados também com outras bases e linguagens de forma
semelheante.
Com uma frequência impressionante, precisamos somar valores vindos de uma base de dados.
Para fazer isso dentro do código do programa, podemos ter:
O “segredo” está na função SUM usada na segunda instrução. Ela simplesmente soma os
valores do campo e reduz um laço dentro do código. Com isso temos mais eficiência, velocidade
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 10 of 90
e código limpo.
Um outro exemplo interessante pode ser visto quando, por exemplo, precisamos concatenar
(unir) dois campos. Para criar uma tabela no código, faríamos assim:
Observe que não temos redução de linhas mas de caracteres que deixam o código mais limpo e
aproveitamos o processamento do banco ao invés do servidor web. A concatenação é feita pela
função CONCAT no segundo exemplo e depois somente precisamos imprimir uma variável, ao
invés de duas, evitando assim problemas de interpretação.
Muitas vezes o trabalho com datas é um pesadelo para o programador. Soma de dias, meses,
em que dia da semana caiu tal data e assim por diante.
Como para strings, bancos de dados também possuem um conjunto interessante de funções
para a manipulação de datas. Vamos ver algumas.
A data atual
Já vi muito programador criar função para a inserção de datas dentro de registros em bases de
dados. Acredito que isso seja por não conhecer uma pequena mas muito útil função chamada
now(). Com ela, a data e/ou hora atual são armazenadas em campos que necessitam este
valor.
Esta função simplesmente pega a informação de data e hora do servidor e insere no campo que
deseja (neste exemplo, em data). Mas cuidado; se o servidor está com a data/hora erradas, o
valor que será inserido também estará errado. Assim é interessante manter o servidor com
horário sempre sincronizado com time servers existentes na Internet.
Além disso, em alguns momentos precisamos saber em que semana estamos do ano ou ainda
quantas semanas faltam para o fim do ano. Ao invés de complexos códigos de linguagem,
podemos usar a base de dados para nos informar este resultado rapidamente. Por exemplo, em
que semana do mês estamos agora?
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 11 of 90
Aqui foi usada a função WEEK que retorna o número da semana de uma determinada data.
Neste caso, a data informada é “hoje” pois usamos como parâmetro de data a função now()
que, como já apresentado anteriormente, é a data atual do servidor.
Outra tarefa comum com datas é a soma de dias em uma data específica. Pode parecer simples
mas como o formato de data é diferente de formatos numéricos e strings, muitas vezes o
resultado está errado e não sabemos porquê.
A forma mais simples é novamente deixar o banco de dados trabalhar por você. Então para
acrescentar, por exemplo, dez dias à data atual, fazemos:
Com isso temos, em uma única linha, o valor que precisamos com a certeza que se trata de
uma data válida, inclusive contando meses que possuem somente 28,29 ou 30 dias
(experimente fazer a soma de 10 dias à data de 25/02/2006 e verá o resultado).
Conclusão
Pequenas e simples funções quando bem utilizadas facilitam a vida de qualquer desenvolvedor.
Assim, antes de “quebrar a cabeça” com dezenas de linhas de código para resolver um
problema ou demanda, procure saber se as ferramentas que está utilizando não dispõem de
formas mais simples para a solução deste problema. Muitas vezes a solução mais simples está
diante dos olhos e perdemos tempo tentando algo diferente.
Estes exemplos são pequenos e simples se comparados a enorme gama de opções existentes
nas bases de dados. Funções para data, strings, funções matemáticas e outras tantas estão
disponíveis na maioria das bases de dados relacionais existentes hoje em dia. Para o MySQL,
acesse http://dev.mysql.com/doc/refman/4.1/pt/functions.html. Já para o PostgreSQL, acesse
http://www.postgresql.org/docs/8.1/static/functions.html
Abraços!
Sintaxe:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 12 of 90
Tabelas temporárias são muito utilizadas quando precisamos reunir vários registros de várias
tabelas em uma única seleção e exibi-las em uma aplicação qualquer (p.ex.: Delphi, Visual
Studio, ASP.NET, etc.). .
É fundamental para aplicações cliente/servidor onde vários usuários estão acessando aquela
procedure ao mesmo tempo.
Aqui vai um exemplo prático da utilização de tabelas temporárias.É importante saber que a
tabela temporária só existe enquanto a procedure está sendo executada, após a execução da
mesma ela é automaticamente excluída. Aproveitei para colocar um exemplo utilizando o CASE
do Sql Server
as
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 13 of 90
Acredito que muitas pessoas já tiveram a necessidade de saber qual o nome do sistema
operacional de um usuário, o seu login do Windows, o diretório home etc. em suas aplicações.
Se você é um dos que se enquadram nessa situação, saiba que existe uma forma de adquirir
essas informações: através da função System.getProperty().
Segue um exemplo:
Veja a saída:
Usuário: GLAUCIO
Sistema Operacional: WINDOWS XP
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#getProperties()
Código da JSP:
Saída:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 14 of 90
Esse tipo de função permite que, por exemplo, quando um usuário acessar o sistema, seu login
seja obrigatoriamente o mesmo do Sistema Operacional. Isso oferece ao administrador do
sistema total controle de quem está usando a ferramenta, garantindo que o usuário possui uma
conta na Intranet.
Em páginas do tipo portal nas que nas laterais se encontram links que são impressos a partir de
bancos de dados (distintas seções, serviços,...) existe sempre um efeito lentalizador devido a
que se trata de páginas altamente visitadas que efetuam múltiplas chamadas a BD
sistematicamente em cada uma de suas páginas.
Uma forma de agilizar a visualização destas páginas é textualizando estes links a partir de
scripts internos. Colocamos o exemplo de Criarweb:
Como se pode ver, na lateral existem seções como "Suas Páginas", "Manuais" cujos links estão
armazenados no banco de dados. Entretanto, os links que se visualizam na página não foram
obtidos por chamadas a banco de dados e sim que, cada vez que um novo elemento da seção é
adicionado, isto se atualiza automaticamente, por meio de um script, um arquivo texto no qual
o novo link é incluído e o mais antigo é eliminado. De fato, este arquivo de texto é o que é
inserido no código fonte da página. Deste modo, evitamos meia dúzia de chamadas a bancos de
dados cada vez que uma página é vista, o qual permite otimizar recursos de servidor de uma
maneira significativa.
Em situações na qual nosso banco de dados tem que armazenar campos de texto
extremamente longos, e tais campos são requeridos para realizar seleções do tipo LIKE '%
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 15 of 90
Este campo adicional pode ser criado automaticamente por meio de scripts e nele incluiríamos o
texto original, do qual teremos eliminado palavras triviais como artigos, preposições ou
possessivos. Além disso, nos encarregaremos de eliminar as palavras que estiverem repetidas.
Desta forma poderemos diminuir sensivelmente o tamanho do campo que vai ser realmente
consultado.
Criação de tabelas
Em geral, a maioria dos bancos de dados possui potentes editores de bancos que permitem a
criação rápida e simples de qualquer tipo de tabela com qualquer tipo de formato.
Entretanto, uma vez que o banco de dados esteja hospedado no servidor, pode acontecer o
caso de que queiramos introduzir uma nova tabela já seja com caráter temporário (para
gerenciar um carrinho de compra, por exemplo) ou permanente, por necessidades concretas de
nossa aplicação.
Nestes casos, podemos, a partir de uma sentença SQL, criar a tabela com o formato que
desejarmos, o qual pode nos poupar mais que um quebra-cabeça.
Estes tipos de sentenças são especialmente úteis para bancos de dados como Mysql, os quais
trabalham diretamente com comandos SQL e não por meio de editores.
Para criar uma tabela devemos especificar diversos dados: O nome que queremos atribuir, os
nomes dos campos e suas características. Ademais, pode ser necessário especificar quais
destes campos vão ser índices e de que tipo serão.
A sintaxe de criação pode variar ligeiramente de um banco de dados para outro já que os tipos
de campos aceitos, não estarão completamente padronizados.
A seguir explicamos meramente a sintaxe desta sentença e lhes propomos uma série de
exemplos:
Sintaxe
Ponhamos agora como exemplo a criação da tabela pedidos que empregamos em capítulos
anteriores:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 16 of 90
Neste caso criamos os campos id os quais são considerados de tipo inteiro de uma longitude
especificada pelo número entre parênteses. Para id_pedido requeremos que tal campo se
incremente automaticamente (AUTO_INCREMENT) de uma unidade a cada introdução a um
novo registro para, desta forma, automatizar sua criação. Por outro lado, para evitar uma
mensagem de erro, é necessário requerer que os campos que vão ser definidos como índices
não possam ser nulos (NOT NULL).
O campo data é armazenado com formato de data (DATE) para permitir sua correta exploração
a partir das funções previstas a tal efeito.
Da mesma forma poderíamos criar a tabela de artigos com uma sentença como esta:
Neste caso pode-se ver que os campos alfanuméricos são introduzidos da mesma forma que os
numéricos. Voltemos a recordar que em tabelas que têm campos comuns é de vital importância
definir estes campos da mesma forma para o bom funcionamento da base.
Muitas são as opções que se oferecem ao gerar tabelas. Não vamos a trata-las detalhadamente,
pois sai do estritamente prático. Mostraremos somente alguns dos tipos de campos que podem
ser empregados na criação de tabelas com suas características:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 17 of 90
Minha experiência maior tem sido desenvolvida junto ao banco de dados Oracle, mas a
padronização do comando SQL e pelo fato de os conceitos de programação de um banco de
dados serem facilmente aplicados a qualquer outro banco de dados, faz com que possamos
tratar destes assuntos quase que universalmente.
SQL
A linguagem SQL (Structured Query Language) é a base para utilização de bancos de dados
relacionais. Com a utilização dos comandos básicos (INSERT, DELETE, UPDATE e SELECT) pode-
se resolver a maior parte dos problemas relacionados a manutenção e extração de dados no
banco de dados. Com o SQL é possível criar as estruturas básicas de armazenamento, como
tabelas e índices. Também há comandos específicos da linguagem para o controle e segurança
relacionado a um banco de dados. Em princípio, os comandos SQL são divididos em:
O SQL tem sido aprimorado ao longo do tempo. Duas entidades (ANSI – American National
Standards Institute e ISO – International Standards Organization) vêm, desde 1986, publicando
padrões de especificação da linguagem SQL.
Vamos discutir como abordar e tirar o máximo de proveito desta linguagem que é
extremamente importante para todos os profissionais de banco de dados. Os principais tópicos
que serão de interesse envolvem:
Naturalmente a idéia é ter uma visão prática, com exemplos e com a abertura de uma
discussão entre todos os leitores.
Os comandos da linguagem SQL são muito poderosos, mas normalmente consegue-se melhorar
o desempenho das aplicações através da programação do banco de dados. Ao desenvolver
módulos que sejam executados diretamente no servidor diminui-se o tráfego de informações na
rede, esconde-se boa parte das estruturas das tabelas e agiliza-se o processamento e retorno
das mensagens. Internamento o banco de dados possui mecanismos integrados que permitem
unir as estruturas tradicionais de programação com os comandos SQL.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 18 of 90
O banco de dados possui mecanismos próprios que podem ser utilizados em favor do
desenvolvedor. Cada banco de dados possui um conjunto específico de comandos que definem
a linguagem de programação do banco de dados. No caso do Oracle, a linguagem é o PL/SQL, o
SQL Server possui o Transact-SQL, o DB2 possui sua própria linguagem de programação, o
PostGreSQL possui diversas extensões que podem ser utilizadas como linguagem de
programação e o MySQL lançou sua mais recente versão com a possibilidade de programar o
servidor. Cada banco de dados é único sob este aspecto, mas todos trabalham sobre os
mesmos conceitos. É possível criar módulos programáveis, como funções, procedimentos,
objetos, pacotes, gatilhos, etc. Em todos os casos, há um engine responsável pela integração e
execução dos módulos no servidor de banco de dados.
Como se pode notar, os tópicos são quase os mesmos da linguagem SQL. Também teremos
artigos que poderão ser implementados, testados e melhorados por todos os leitores.
Tenho uma tabela com vários campos. Dois deles são datas, que correspondem com um
intervalo. Um deles é a data de início do intervalo (datadesde) e outro a de final do intervalo
(dataate)
Queria saber como se pode fazer uma consulta SQL em Access para obter os registros cujo
intervalo de datas contenha o dia de hoje.
Ou seja, que a data desde seja menor que hoje e data até seja maior que hoje.
Estivemos primeiro fazendo duas provas sem êxito, comparando as datas com operadores
aritméticos. Em alguns casos obtivemos a resposta esperada, porém nem sempre funcionavam
as sentenças e tínhamos problemas ao executa-las desde Access ou desde o servidor web,
porque não devolviam os mesmos resultados.
Função DateDiff()
Afinal, a resposta que propusemos passou por utilizar a função DateDiff, que serve para obter a
diferença entre duas datas. Por exemplo:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 19 of 90
Nós podemos utiliza-la como condição em um where de uma sentença SQL. Por exemplo, para
uma sentença como esta:
DateDiff("y",A,B)
Temos que comparar o dia de hoje com as datas desde e ate. Hoje tem que ser maior que
desde e menor que ate. Fica como resultado esta sentença:
Nota: Há que ter cuidado com o idioma das datas, pois em português se escrevem de maneira diferente
que em inglês. Access tenta interpretar a data corretamente, por exemplo, se introduzimos 02/26/04
pensará que está trabalhando em datas em inglês e se introduzimos 26/02/04 pensará que estamos
escrevendo as datas em português. O problema é com uma data como 02/02/04 que seu valor dependerá
de como esteja configurado o Access, em português ou em inglês.
Função DatePart
Serve para extrair parte de uma data. Recebe dois parâmetros, o primeiro indica mediante um
string a parte a obter. O outro parâmetro é a data com a que se deseja trabalhar.
DatePart("m",data)
Neste caso está sendo indicado que se deseja obter o mês do ano. Outro valor possível para o
primeiro parágrafo é, por exemplo "yyyy", que se utiliza para obter o ano com quatro dígitos.
Um exemplo de sentença SQL que utiliza esta função pode ser a seguinte:
Função DateAdd
Esta última função que vamos ver no presente artigo serve para acrescentar à data, algo como
dias, meses ou anos. Para isso a função recebe três parâmetros, o primeiro corresponde com
um string para indicar as unidades do que desejamos acrescentar, por exemplo, dias, meses ou
anos. O segundo parâmetro é o número de dias, meses ou anos a adicionar e o terceiro
parâmetro é a data a qual somar esses valores. Vemos um exemplo de sua sintaxe:
DateAdd("yyyy",10,validadedesde)
Neste exemplo a função DateAdd devolveria uma data dez anos posterior a validadedesde.
Outros valores para o string do primeiro parâmetro são "d", para acrescentar dias, ou "m", para
acrescentar meses.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 20 of 90
//Com esta variavel calculamos quantos dias "normais" existem na classe de datas
//esta variavel nos serve de contador para saber quando chegarmos ao ultimo dia da classe
/*esta variavel eh a que comparamos para saber se o dia que esta calculando eh sabado ou domingo*/
/*Estas duas variaveis servem para comparar as duas datas, se sao iguais, a funcao nos regressa um 0*/
SELECT @DaysBetween = 0
SELECT @BusinessDays = 0
SELECT @Cnt=0
/*Ordenamos o formato das datas para que não importando como se proporcionem se comparem igual*/
IF @ini <>@fin
BEGIN
/*Se a diferenca de datas for igual a dois, eh porque so foi transcorrido um dia, portanto somente se valida de que nao
vai marcar dias de mais*/
IF @DaysBetween = 2
BEGIN
SELECT @BusinessDays = 1
END
ELSE
BEGIN
WHILE @Cnt < @DaysBetween
BEGIN
/*Iguala-se a data que vamos calcular para saber se eh sabado ou domingo na variavel @EvalDate somando os dias
que marque o contador, o qual nao deve ser maior que o numero total de dias que existem na classe de datas*/
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 21 of 90
/*Utilizando a funcao datepart com o parametro dw que calcula que dia da semana corresponde uma data determinada,
determinados que nao seja sabado (7) ou domingo (1)*/
/*Se nao eh sabado ou domingo, entao se soma um ao total de dias que queremos desdobrar*/
SELECT @BusinessDays = 0
END
return (@BusinessDays)
END
Antes de começar, gostaria de dizer que este curso está baseado em Oracle, ou seja, os
exemplos expostos e o material foram atualizados sobre Oracle. Por outro lado dizer que acho
interessante saber algo de SQL antes de começar com MYSQL, já que, embora existam algumas
mudanças insignificantes, sabendo manejar SQL você saberá manejar MYSQL.
Algumas características:
Tipos de dados:
CHAR:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 22 of 90
VARCHAR:
NUMBER:
X=number (7,2)
X=155'862 à Erro já que só pode tomar 2 decimais
X= 155'86 à Bem
LONG:
DATE:
Seculo/Ano/Mes/Dia/Hora/Minutos/Segundos
RAW:
LONGRAW:
ROWID:
Select:
Select [ALL | Distinct] [expresao_coluna1, expresao_coluna2, …., | *]
From [nome1, nome_tabela1, …, nome_tabelan]
{[Where condicao]
[Order By expresao_coluna [Desc | Asc]…]};
Vamos explicar como ler a consulta anterior e assim seguir a pauta para todas as demais.
Quando compomos [] significa que a que vai dentro deve existir, e sim, além disso, colocamos |
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 23 of 90
significa que deveremos escolher um valor dos que colocamos e não mais de um. Em troca se
colocarmos {} significa que o que vai dentro das chaves pode ir ou não, ou seja, é opcional e se
colocará segundo a consulta.
Nota: Note que cada consulta de SQL que fazemos temos de termina-la com um ponto e vírgula";".
SELECT *
FROM JOGADORES
WHERE POSICAO = 'ATACANTE'
ORDER BY JOGADOR_NO;
Este exemplo mostra todos os campos da tabela jogadores onde (Where) a posição for igual
que 'Atacante' e o ordena por número de jogador. Ao não colocar nada se supõe que é
ascendentemente (Asc).
SELECT *
FROM JOGADORES
WHERE TIME_NAO = 'FLAMENGO' AND POSICAO = 'ATACANTE'
ORDER BY SOBRENOME DESC, JOGADOR_NAO ASC;
Neste exemplo seleciona todos os campos da tabela jogadores onde (Where) o nome do time
for igual a 'Flamengo' e a posição dos jogadores for igual a 'Atacante'. Por ultimo os ordena por
'Sobrenome' descendentemente e por número de jogador ascendentemente.
+ = Soma
- = Subtração
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 24 of 90
* = Multiplicação
/ = Divisião
!> = Diferente
>= = Maior ou igual que
<= = Menor ou igual que = = Igual que
Like = Utiliza para unir cadeias de caracteres. Propriedades:
% = representa qualquer cadeia de caracteres de 0 ou mais caracteres.
_= representa um único caractere qualquer.
Not = Negação
And = e
a and b
Certo se são certas a e b.
Or = o
a or b
Certo se a ou b são certas
Obtemos os dados dos jogadores cujos sobrenomes comecem com a letra "S":
SELECT SOBRENOMES
FROM JOGADORES
WHERE SOBRENOMES LIKE 'S%';
SELECT SOBRENOMES
FROM JOGADORES
WHERE SOBRENOMES LIKE '_R*';
Obtemos aqueles sobrenomes que começam por "A" e tem uma "o" em seu interior:
SELECT SOBRENOMES
FROM JOGADORES
WHERE SOBRENOMES LIKE 'A%O%';
Exemplo:
SELECT SOBRENOMES
FROM JOGADORES
WHERE JOGADOR_NUM IN (10, 20);
Seleciona os sobrenomes dos jogadores onde o número de jogador (Jogador_num) seja (In) ou
10 ou 20
SELECT SOBRENOMES
FROM JOGADORES
WHERE SALARIO NOT BETWEEN 15000000 AND 20000000;
Seleciona os sobrenomes dos jogadores onde o salário destes não esteja entre (Not Between)
15000000 e 20000000.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 25 of 90
Sub-consultas SQL
Sub-consultas:
Consulta que se faz sobre os dados que nos dá outra consulta. Seu formato é:
SELECT______
FROM________
WHERE CONDICAO OPERADOR (SELECT ______
FROM ___________
WHERE CONDICAO OPERADOR); Exemplo:
SELECT SOBRENOME
FORM EMPLE
WHERE POSICAO = (SELECT OFICIO
FROM EMPLE
WHERE SOBRENOME LIKE 'GIL');
Selecionamos em todos os campos da tabela Jogadores cuja sede está em Madrid ou Barcelona:
SELECT *
FROM JOGADORES
WHERE EQUIPE_NOM IN (SELECT EQUIPE_NOM
FROM SEDE
WHERE LOC IN ('MADRID', 'BARCELONA');
FROM SEDE
WHERE LOC IN ('MADRID', 'BARCELONA');
Funções SQL
Funções de valores simples:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 26 of 90
Funções de conversão:
Para saber qual é o salário médio de cada departamento da tabela Jogadores seria:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 27 of 90
GROUP BY DEPT_NO;
SELECT…
FROM…
GROUP BY COLUNA1, COLUNA2, COLUNAN…
HAVING CONDICAO
GROUP BY …
Os dados selecionados na sentença "Select" que leva o "Group By" devem ser:
Uma constante.
A cláusula Having se emprega para controlar qual dos conjuntos de filas se visualiza. Avalia-se
sobre a tabela que devolve o Group By. Não pode existir sem Group By.
Having é parecido ao Where, porém trabalha com grupos de filas; pergunta por uma
característica de grupo, ou seja, pergunta pelos resultados das funções de grupo, o qual Where
não pode fazer.
Permite-nos selecionar algumas filas de uma tabela embora estas não tenham correspondência
com as filas da outra tabela com a que se combina. Formato:
Isto seleciona todas as filas da tabela "tabela1" embora não tenham correspondência com as
filas da tabela "tabela2", se utiliza o símbolo +.
O resto de colunas da tabela "tabela2" se preenche com NULL.
Permite combinar os resultados de vários "Select" para obter um único resultado. Formato:
UNION= Combina os resultados de duas consultas. As filas duplicadas que aparecem se reduzem
a uma fila única.
UNION ALL= Como a anterior, porém aparecerão nomes duplicados.
INTERSEC= Devolve as filas que são iguais em ambas consultas. Todas as filas duplicadas serão
eliminadas.
MINUS= Devolve aquelas filas que estão na primeira "Select" e não estão na segunda "Select".
As filas duplicadas do primeiro conjunto se reduzirão a uma fila única antes que comece a
comparação com o outro conjunto.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 28 of 90
>
Insert:
Propriedades:
Com Select:
Update:
Atualiza os valores das colunas para uma ou várias filas de uma tabela:
UPDATE NOMETABELA
SET COLUNA1= VALOR1, …, COLUNAN= VALORN
WHERE CONDICAO;
Com Select:
Quando a subconsulta (orden select) forma parte de SET, deve selecionar o mesmo número de
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 29 of 90
colunas, (com tipos de dados adequados) que os que existem entre parênteses ao lado de SET.
UPDATE NOMETABELA
SET COLUNA= VALOR1, COLUNA2= VALOR2, …
WHERE COLUNA3= (SELECT…)
OU
UPDATE NOMETABELA
SET (COLUNA1, COLUNA2, …)= (SELECT …)
WHERE CONDICAO;
Delete:
Permite ir até o último COMMIT feito ou em seu padrão até o começo das ordens com o que
estas não se executam.
Commit:
Quando executamos ordens, estas não são criadas na tabela até que coloquemos esta ordem,
portanto as mudanças realizadas se perderão se ao sair do programa não realizarmos esta
ação. Pode se programar para que seja feito automaticamente.
QUIT
EXIT
CONNECT
DISCONNECT
CREATE TABLE
CREATE VIEW
GRANT
REVOQUE
DROP TABLE
DROP VIEW
ALTER
AUDIT
NO AUDIT
Seu primeiro caractere deve ser alfabético e o resto pode ser letras, números e o caractere
sublinhado.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 30 of 90
Características:
Integridade de dados:
A integridade faz referência ao fato de que os dados do banco de dados têm que se ajustar às
restrições antes de se armazenar nele. Uma restrição de integridade será:
Uma regra que restringe classe de valores para uma ou mais colunas na tabela.
Usamos a cláusula CONSTRAINT, que pode restringir uma só coluna ou um grupo de colunas de
uma mesma tabela.
Existem dois modos de especificar restrições:
Formato:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 31 of 90
É uma coluna ou um conjunto de colunas que identificam univocamente a cada fila. Deve ser
única, não nula e obrigatória. Como máximo, podemos definir uma chave primária por tabela.
Esta chave pode ser referenciada por uma coluna ou colunas. Quando se cria uma chave
primária, automaticamente se cria um índice que facilita o acesso à tabela.
Está formada por uma ou várias colunas que estão associadas a uma chave primária de outra
ou da mesma tabela. Pode-se definir tantas chaves alheias quantas se necessite, e podem estar
ou não na mesma tabela que a chave primária. O valor da coluna ou colunas que são chaves
alheias deve ser: NULL ou igual a um valor da chave referenciada (regra de integridade
referencial).
Notas:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 32 of 90
mãe, todas as filas da tabela detalhe cuja chave alheia seja referenciada se eliminarão
automaticamente. A restrição se declara na tabela detalhe. A mensagem "n filas
eliminadas" só indica as filas eliminadas da tabela mãe.
NOT NULL: Significa que a coluna não pode ter valores nulos.
DEFAULT: Proporcionamos a uma coluna um valor padrão quando o valor da coluna não se
especifica na cláusula INSERT. Na especificação DEFAULT é possível incluir várias expressões:
constantes, funções SQL e variáveis UID e SYSDATE.
Verificação de restrições: CHECK: Atua como uma cláusula where. Pode fazer referência a uma
ou mais colunas, porém não a valores de outras filas. Em uma cláusula CHECK não se podem
incluir sub-consultas nem as pseudo-consultas SYSDATE, UID e USER.
UNIQUE: Evita valores repetidos na mesma coluna. Pode conter uma ou várias colunas. É
similar à restrição PRIMARY KEY, salvo que são possíveis várias colunas UNIQUE definidas em
uma tabela. Admite valores NULL. Assim como em PRIMARY KEY, quando se define uma
restrição UNIQUE se cria um índice automaticamente.
CREATE TABLE: permite criar uma tabela a partir da consulta de outra tabela já existente. A
nova tabela conterá os dados obtidos na consulta. Realiza-se esta ação com a cláusula AS
colocada ao final da ordem CREATE TABLE.
Não é necessário especificar tipos nem tamanho das consultas, já que vêm determinadas pelos
tipos e os tamanhos das recuperadas na consulta.
A consulta pode ter uma sub-consulta, uma combinação de tabelas ou qualquer sentença select
válida.
As restrições COM NOME não se criam em uma tabela desde a outra, só se criam aquelas
restrições que carecem de nome.
DROP TABLE: suprime uma tabela do banco de dados. Cada usuário pode eliminar suas próprias
tabelas, porém só o administrador ou algum usuário com o privilégio "DROP ANY TABLE" pode
eliminar as tabelas de outro usuário. Ao suprimir uma tabela também se suprimem os índices e
os privilégios associados a ela. As vistas e os sinônimos criados a partir desta tabela deixam de
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 33 of 90
TRUNCATE: permite suprimir todas as filas de uma tabela e liberar o espaço ocupado para
outros usos sem que reapareça a definição da tabela do banco de dados. Uma ordem
TRUNCATE não se pode anular, assim como também não ativa os disparadores DELETE.
Modificação de tabelas:
Se a coluna não estiver definida como NOT NULL pode-se adicionar em qualquer
momento.
Se a coluna estiver definida como NOT NULL pode-se seguir estes passos:
1. Adiciona-se uma coluna sem especificar NOT NULL.
2. Dá-se valor à coluna para cada uma das filas.
3. Modifica-se a coluna NOT NULL.
Se a coluna for NULL em todas as filas da tabela, pode-se diminuir a longitude e modificar
o tipo de dado.
A opção MODIFY… NOT NULL só será possível quando a tabela não contiver nenhuma fila
com valor nulo na coluna que se modifica.
Adição de restrições:
Eliminação de restrições:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 34 of 90
A ordem ALTER TABLE com a cláusula DROP CONSTRAINT; com a que se eliminam as restrições
com nome e as atribuídas pelo sistema. Formato:
Não contém informação por si mesmas, e sim, estão baseadas nas que contém outras tabelas e
reflete os dados destas.
Se se suprime uma tabela a vista associada se invalida. Formato:
Nota: ao eliminar as tabelas, as vistas dessas tabelas não se eliminam e ficam inutilizadas.
Eliminação de vistas
Atualização. Se uma vista está baseada em uma só tabela, pode-se modificar as filas da
vista.
A modificação da vista muda a tabela sobre a qual está definida.
Eliminação de filas através de uma vista= Para eliminar filas de uma tabela através de
uma vista, esta se deve criar:
Com filas de uma só tabela.
Sem utilizar a cláusula GROUP BY nem DISTINCT.
Sem usar funções de grupo ou referências a pseudo-colunas.
Atualização de filas através de uma vista: Para atualizar filas em uma tabela através de
uma vista, esta tem que estar definida segundo as restrições anteriores e, ademais,
nenhuma das colunas que vai se atualizar terá definido como uma expressão.
Inserção de filas através de uma vista: Para inserir filas em uma tabela através de uma
vista, há que ter em conta todas as restrições anteriores e, ademais, todas as colunas
obrigatórias da tabela associada devem estar presentes na vista.
Manejo de expressões e de funções em vistas: Pode-se criar vistas usando funções,
expressões em colunas e consultas avançadas, porém unicamente se emparelham
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 35 of 90
consultar estas vistas. Também podemos modificar filas sempre e quando a coluna que
vai se modificar não for a coluna expressada em forma de cálculo ou com funções.
Nota: Não é possível inserir filas se as colunas da vista contém cálculos ou funções.
Mudanças de nome
RENAME muda o nome de uma tabela, vista ou sinônimo. O novo nome não pode ser uma
palavra reservada no nome de um objeto que o usuário tiver criado. As restrições de
integridade, os índices e as permissões dadas ao objeto se transferem automaticamente ao
novo objeto.
Com esta ordem não podemos re-nomear colunas de uma tabela, estas se re-nomeiam
mediante CREATE TABLE AS…
Usuários em Oracle
É um nome definido no banco de dados que se pode conecta-lo e acessar a determinados
objetos segundo certas condições que o administrador estabelece.
Os objetos do dicionário de dados aos que um usuário pode acessar, encontram-se na vista
DICTIONARY, que é propriedade do usuário SYS.
DESC DICTIONARY;
Com a ordem:
Criação de usuários:
Modificação de usuários:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 36 of 90
Eliminação de usuarios:
Permite-nos acessar e realizar mudanças nos dados de outros usuários. Exemplo: O privilégio
de consultar a tabela de outro usuário é um privilégio sobre objetos.
Privilégios de sistema
Dão direito a executar um tipo de comando SQL ou a realçar alguma ação sobre objetos de um
tipo especificado. Por exemplo, o privilégio para criar TABLESPACES é um privilégio de sistema.
Formato:
WITH ADMIN OPTION= Permite que o receptor do privilégio ou rol possa conceder esses
mesmos privilégios a outros usuários ou rols.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 37 of 90
Roles
Nota: Um rol pode decidir o acesso de um usuário a um objeto, mas não pode permitir a criação de
objetos.
Supressão de um rol
Perfis:
Eliminação de um perfil:
Gerenciamento de tablespaces
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 38 of 90
[ONLINE | OFFLINE];
Modificação de tablespaces
Eliminação de tablespaces
INCLUDING CONTENTS= Permite eliminar um tablespace que tenha dados. Sem esta opção só
se pode suprimir um tablespace vazio.
Recomenda-se colocar o talespace offline antes de elimina-lo para certificarmos de que não
haja sentenças SQL que estejam acessando dados do tablespace, em cujo caso não seria
possível elimina-lo.
Quando se elimina um tablespace os arquivos associados não se apagam do sistema
operacional, portanto teremos que elimina-los de forma manual.
Portanto, muitas vezes não basta com especificar uma sentença SQL correta, e sim que além
disso, há que indicar como tem que fazer se quisermos que o tempo de resposta seja o mínimo.
Nesta seção, veremos como melhorar o tempo de resposta de nosso intérprete ante umas
determinadas situações:
Design de tabelas
Normalize as tabelas, pelo menos até a terceira forma normal, para garantir que não haja
duplicidade de dados e aproveitar o máximo de armazenamento nas tabelas. Se tiver que
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 39 of 90
Os índices são campos escolhidos arbitrariamente pelo construtor do banco de dados que
permitem a busca a partir de tal campo a uma velocidade notavelmente superior. Entretanto,
esta vantagem se vê contra-arrestada pelo fato de ocupar muito mais memória (o dobro mais
ou menos) e de requerer para sua inserção e atualização um tempo de processo superior.
Evidentemente, não podemos indexar todos os campos de uma tabela extensa já que dobramos
o tamanho do banco de dados. Igualmente, tampouco serve muito indexar todos os campos em
uma tabela pequena já que as seleções podem se efetuar rapidamente de qualquer forma.
Um caso em que os índices podem ser muito úteis é quando realizamos petições simultâneas
sobre várias tabelas. Neste caso, o processo de seleção pode se acelerar sensivelmente se
indexamos os campos que servem de nexo entre as duas tabelas.
Os índices podem ser contraproducentes se os introduzimos sobre campos triviais a partir dos
quais não se realiza nenhum tipo de petição já que, além do problema de memória já
mencionado, estamos lentificando outras tarefas do banco de dados como são a edição,
inserção e eliminação. É por isso que vale a pena pensar duas vezes antes de indexar um
campo que não serve de critério para buscas ou que é usado com muita freqüência por razões
de manutenção.
Campos a Selecionar
Na medida do possível há que evitar que as sentenças SQL estejam embebidas dentro do
código da aplicação. É muito mais eficaz usar vistas ou procedimentos armazenados por
que o gerenciador os salva compilados. Se se trata de uma sentença embebida o
gerenciador deve compila-la antes de executa-la.
Selecionar exclusivamente aqueles que se necessitem
Não utilizar nunca SELECT * porque o gerenciador deve ler primeiro a estrutura da tabela
antes de executar a sentença
Se utilizar várias tabelas na consulta, especifique sempre a que tabela pertence cada
campo, isso economizará tempo ao gerenciador de localizar a que tabela pertence o
campo. Ao invés de SELECT Nome, Fatura FROM Clientes, Faturamento WHERE IdCliente
= IdClienteFaturado, use: SELECT Clientes.Nome, Faturamento.Fatura WHERE
Clientes.IdCliente = Faturamento.IdClienteFaturado.
Campos de Filtro
Procuraremos escolher na cláusula WHERE aqueles campos que fazem parte da chave do
arquivo pelo qual interrogamos. Ademais se especificarão na mesma ordem na qual
estiverem definidas na chave.
Interrogar sempre por campos que sejam chave.
Se desejarmos interrogar por campos pertencentes a índices compostos é melhor utilizar
todos os campos de todos os índices. Suponhamos que temos um índice formado pelo
campo NOME e o campo SOBRENOME e outro índice formado pelo campo IDADE. A
sentença WHERE NOME='Jose' AND SOBRENOME Like '%' AND IDADE = 20 seria melhor
que WHERE NOME = 'Jose' AND IDADE = 20 porque o gerenciador, neste segundo caso,
não pode usar o primeiro índice e ambas sentenças são equivalentes porque a condição
SOBRENOME Like '%' devolveria todos os registros.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 40 of 90
Quando se utilizam várias tabelas dentro da consulta há que ter cuidado com a ordem
empregada na cláusula FROM. Se desejarmos saber quantos alunos se matricularam no ano
1996 e escrevermos: FROM Alunos, Matriculas WHERE Aluno.IdAluno = Matriculas.IdAluno AND
Matriculas.Ano = 1996 o gerenciador percorrerá todos os alunos para buscar suas matrículas e
devolver as correspondentes. Se escrevermos FROM Matriculas, Alunos WHERE Matriculas.Ano
= 1996 AND Matriculas.IdAluno = Alunos.IdAlunos, o gerenciador filtra as matrículas e depois
seleciona os alunos, desta forma tem que percorrer menos registros.
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Consultas de seleção
Este conjunto de registros pode ser modificável.
Consultas básicas
SELECT
Campos
FROM
Tabela
Onde "campos" é a lista de campos que se deseja recuperar e "tabela" é a origem dos mesmos,
por exemplo:
SELECT
Nombre, Telefone
FROM
Clientes
Esta sentença devolve um conjunto de resultados com o campo nome e telefone da tabela
clientes.
Devolver Literais
Em determinadas ocasiões pode nos interessar incluir uma coluna com um texto fixo em uma
consulta de seleção, por exemplo, suponhamos que temos uma tabela de empregados e
desejamos recuperar as tarifas semanais dos eletricistas, poderíamos realizar a seguinte
consulta:
SELECT
Empregados.Nome, 'Tarifa semanal: ', Empregados.TarifaHora * 40
FROM
Empregados
WHERE
Empleados.Cargo = 'Eletricista'
SELECT
CodigoPostal, Nome, Telefone
FROM
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 41 of 90
Clientes
ORDER BY
Nome
Esta consulta devolve os campos CodigoPostal, Nome, Telefone da tabela Clientes ordenados
pelo campo Nome.
SELECT
CodigoPostal, Nome, Telefone
FROM
Clientes
ORDER BY
CodigoPostal, Nome
Inclusive pode-se especificar a ordem dos registros: ascendente mediante a cláusula (ASC -
toma-se este valor padrão) ou descendente (DESC)
SELECT
CodigoPostal, Nome, Telefone
FROM
Clientes
ORDER BY
CodigoPostal DESC , Nome ASC
Se desejarmos que a sentença SQL utilize um índice para mostrar os resultados se pode utilizar
a palavra reservada INDEX da seguinte forma:
Normalmente os motores dos bancos de dados decidem que índice se deve utilizar para a
consulta, para isso utilizam critérios de rendimento e sobretudo, os campos de busca
especificados na cláusula WHERE. Se se deseja forçar a não utilizar nenhum índice utilizaremos
a seguinte sintaxe:
Predicado Descrição
ALL Devolve todos os campos da tabela
TOP Devolve um determinado número de registros da tabela
DISTINCT Omite os registros cujos campos selecionados coincidam totalmente
Omite os registros duplicados baseando-se na totalidade do registro e não só nos
DISTINCTOW
campos selecionados.
ALL
Se não se inclui nenhum dos predicados se assume ALL. O Motor de banco de dados seleciona
todos os registros que cumprem as condições da instrução SQL e devolve todos e cada um de
seus campos. Não é conveniente abusar deste predicado já que obrigamos ao motor do banco
de dados a analisar a estrutura da tabela para averiguar os campos que contém, é muito mais
rápido indicar a lista de campos desejados.
SELECT ALL
FROM
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 42 of 90
Empregados
SELECT *
FROM
Empregados
TOP
Devolve um certo número de registros que entram entre ao princípio ou ao final de uma
categoria especificada por uma cláusula ORDER BY. Suponhamos que queremos recuperar os
nomes dos 25 primeiros estudantes do curso 1994:
SELECT TOP 25
Nome, Sobrenome
FROM
Estudantes
ORDER BY
Nota DESC
O valor que vai a seguir de TOP deve ser um inteiro sem signo. TOP não afeta à possível
atualização da consulta.
DISTINCT
Omite os registros que contém dados duplicados nos campos selecionados. Para que os valores
de cada campo listado na instrução SELECT se incluam na consulta devem ser únicos. Por
exemplo, vários empregados listados na tabela Empregados podem ter o mesmo sobrenome.
Se dois registros contém Lopez no campo Sobrenome, a seguinte instrução SQL devolve um
único registro:
SELECT DISTINCT
Sobrenome
FROM
Empregados
Com outras palavras o predicado DISTINCT devolve aqueles registros cujos campos indicados
na cláusula SELECT possuam um conteúdo diferente. O resultado de uma consulta que utiliza
DISTINCT não é atualizável e não reflete as mudanças subseqüentes realizadas por outros
usuários.
DISTINCTROW
Este predicado não é compatível com ANSI. Que eu saiba no dia de hoje só funciona com
ACCESS.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 43 of 90
SELECT DISTINCTROW
Sobrenome
FROM Empregados
Se a tabela empregados contém dois registros: Antonio Lopez e Marta Lopez o exemplo do
predicado DISTINCT devolve um único registro com o valor Lopez no campo Sobrenome já que
busca não duplicados em tal campo. Este último exemplo devolve dois registros com o valor
Lopez no sobrenome já que se buscam não duplicados no registro completo.
ALIAS
SELECT DISTINCTROW
Sobrenome AS Empregado
FROM Empregados
AS não é uma palavra reservada de ANSI, existem diferentes sistemas de atribuir os alias em
função do motor de banco de dados. Em ORACLE para atribuir um alias a um campo há que
fazer da seguinte forma:
SELECT
Sobrenome AS "Empregado"
FROM Empregados
Também podemos atribuir alias às tabelas dentro da consulta de seleção, neste caso há que ter
em conta que em todas as referências que desejarmos fazer a tal tabela há que utilizar o alias
ao invés do nome. Esta técnica será de grande utilidade mais adiante quando se estudarem as
vinculações entre tabelas. Por exemplo:
SELECT
Apellido AS Empregado
FROM
Empregados AS Trabalhadores
SELECT
Trabalhadores.Sobrenome (1) AS Empregado
FROM
Empregadore Trabalhadores
Para concluir este capítulo se deve fazer referência à recuperação de registros de banco de
dados externos. Em ocasiões é necessário a recuperação de informação que se encontra contida
em uma tabela que não se encontra no banco de dados que executará a consulta ou que nesse
momento não se encontra aberta, esta situação podemos salva-la com a palavra reservada IN
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 44 of 90
da seguinte forma:
SELECT
Sobrenome AS Empregado
FROM
Empleados IN'c: \databases\gerenciamento.mdb'
SELECT
Sobrenome
FROM
Servidor1.BancoDados1.dbo.Empregados
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Antes de começar o desenvolvimento deste artigo, há que ressaltar três detalhes de vital
importância. O primeiro deles é que cada vez que se deseja estabelecer uma condição referida
a um campo de texto a condição de busca deve ir fechada entre aspas simples; a segunda é
que não é possível estabelecer condições de busca nos campos memo e; a terceira e última faz
referência às datas. Ate hoje não fui capaz de encontrar uma sintaxe que funcione em todos os
sistemas, por isso se faz necessário particulariza-las segundo o banco de dados:
Data = #05-18-1969# ó
SQL-SERVER
Data = 19690518
ORACLE Data = to_date('YYYYDDMM', '19690518')
ACCESS Data = #05-18-1969#
Referente aos valores lógicos True ou False cabe destacar que não são reconhecidos em
ORACLE, nem nesse sistema de banco de dados, nem em SQL-SERVER existem os campos de
tipo "SIM/NAO" de ACCESS; nesses sistemas se utilizam os campos BIT que permitem
armazenar valores de 0 ou 1. Internamente, ACCESS, armazena neste campos valores de 0 ou
-1, por tanto tudo se complica bastante, porém, aproveitando a coincidência do 0 para os
valores FALSE, pode-se utilizar a sintaxe seguinte que funciona em todos os casos: se se deseja
saber se o campo é falso "... CAMPO = 0" e para saber os verdadeiros "CAMPO <> 0".
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 45 of 90
Operadores Lógicos
Os operadores lógicos suportados por SQL são: AND, OR, XOR, Eqv, Imp, Is e Not. Com
exceção dos dois últimos, todos possuem a seguinte sintaxe:
O último operador denominado Is se emprega para comparar duas variáveis de tipo objeto
<Objeto1> Is <Objeto2>. este operador devolve verdadeiro se os dois objetos forem iguais.
SELECT *
FROM
Empregados
WHERE
Idade > 25 AND Idade < 50
SELECT *
FROM
Empregados
WHERE
(Idade > 25 AND Idade < 50)
OR
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 46 of 90
Salario = 100
SELECT *
FROM
Empregados WHERE
NOT Estado = 'Solteiro'
SELECT *
FROM
Empregados
WHERE
(Salario >100 AND Salario < 500)
OR
(Cidade = 'Madri' AND Estado = 'Casado')
Intervalos de Valores
Para indicar que desejamos recuperar os registros segundo o intervalo de valores de um campo
empregaremos o operador Between cuja sintaxe é:
Neste caso a consulta devolveria os registros que contiverem em "campo" um valor incluído no
intervalo valor1, valor2 (ambos inclusive). Se ante-pusermos a condição Not devolverá aquelos
valores não incluídos no intervalo.
SELECT *
FROM
Pedidos
WHERE
CodPostal Between 28000 And 28999
(Devolve os pedidos realizados na cidade de Madrid)
O Operador Like
Utiliza-se para comparar uma expressão de cadeia com um modelo em uma expressão SQL.
Sua sintaxe é:
Onde expressão é uma cadeia modelo ou campo contra o que se compara expressão. Pode-se
utilizar o operador Like para encontrar valores nos campos que coincidam com o modelo
especificado. Por modelo pode especificar um valor completo (Ana Maria), ou se pode utilizar
uma cadeia de caracteres asterisco como os reconhecidos pelo sistema operacional para
encontrar uma classificação de valores (Like An*).
O operador Like pode ser utilizado em uma expressão para comparar um valor de um campo
com uma expressão de cadeia. Por exemplo, se introduzirmos Like C* em uma consulta SQL, a
consulta devolve todos os valores de campo que começarem pela letra C. Em uma consulta com
parâmetros, pode fazer com que o usuário escreva o modelo que será utilizado.
O exemplo seguinte devolve os dados que começam com a letra P seguido de qualquer letra
entre A e F e de três dígitos:
Like 'P[A-F]###'
Este exemplo devolve os campos cujo conteúdo comece com uma letra da A à D seguidas de
qualquer cadeia.
Like '[A-D]*'
Na tabela seguinte se mostra como utilizar o operador Like para comprovar expressões com
diferentes modelos.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 47 of 90
ACCESS
'
Tipo de coincidência Modelo Planejado Coincidee Nao coincide
Varios caracteres 'a*a' aa', 'aBa', 'aBBBa' 'aBC'
Caractere especial 'a[*]a' 'a*a' 'aaa'
Varios caracteres 'ab*' 'abcdefg', 'abc' 'cab', 'aab'
Um so caractere 'a?a' 'aaa', 'a3a', 'aBa' 'aBBBa'
Um so digito 'a#a' 'a0a', 'a1a', 'a2a' 'aaa', 'a10a'
Categoria de caracteres '[a-z]' 'f', 'p', 'j' '2', '&'
Fora de uma categoria '[!a-z]' '9', '&', '%' 'b', 'a'
Diferente de um digito '[!0-9]' 'A', 'a', '&', '~' '0', '1', '9'
Combinada 'a[!b-m]#' 'An9', 'az0', 'a99' 'abc', 'aj0'
SQL-SERVER
Exemplo Descrição
LIKE 'A%' Tudo que comecar por A
LIKE '_NG' Tudo que comece por qualquer caractere e logo siga NG
LIKE '[AF]%' Tudo que comecar por A ou F
LIKE '[A-F]%' Tudo que comece por qualquer letra compreendida entre a A e a F
LIKE '[A^B]%' Tudo que comecar por A e a segunda letra nao for uma B
Em determinado motores de banco de dados, esta cláusula, não reconhece o asterisco como
caractere e há que substitui-lo pelo caractere tanto por cento (%).
O Operador In
Este operador devolve aqueles registros cujo campo indicado coincide com algum dos em uma
lista. Sua sintaxe é:
SELECT *
FROM
Pedidos
WHERE
Cidade In ('Madri', 'Barcelona', 'Sevilha')
A cláusula WHERE
A cláusula WHERE pode ser usada para determinar que registros das tabelas enumeradas na
cláusula FROM aparecerão nos resultados da instrução SELECT. Depois de escrever esta
cláusula deve-se especificar as condições expostas nas seções anteriores. Se não se emprega
esta cláusula, a consulta devolverá todas as filas da tabela. WHERE é opcional, mas quando
aparece deve ir a seguir de FROM.
SELECT
Sobrenome, Salario
FROM
Empregados
WHERE
Salario = 21000
SELECT
IdProduto, Existencias
FROM
Produtos
WHERE
Existencias <= NovoPedido
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 48 of 90
SELECT *
FROM
Pedidos
WHERE
DataEnvio = #05-30-1994#
SELECT
Sobrenomes, Nome
FROM
Empregados
WHERE
Sobrenomes = 'King'
SELECT
Sobrenomes, Nome
FROM
Empregados
WHERE
Sobrenomes Like 'S*'
SELECT
Sobrenomes, Salario
FROM
Empregados
WHERE
Salario Between 200 And 300
SELECT
Sobrenomes, Salario
FROM
Empregados
WHERE
Sobrenomes Between 'Lon' And 'Tol'
SELECT
IdPedido, DataPedido
FROM
Pedidos
WHERE
DataPedido Between #01-01-1994# And #12-31-1994#
SELECT
Sobrenomes, Nome, Cidade
FROM
Empregados
WHERE
Cidade In ('Sevilha', 'Los Angeles', 'Barcelona')
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Neste artigo, veremos como retornar registros com uma stored procedure com duas instruções
SQL. Inicialmente, declaramos a string de conexão com o banco de dados
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 49 of 90
string sSql = " SELECT Count(*) AS Total FROM Products; SELECT ProductName, UnitPrice FROM Products";
Com a instrução using criamos uma nova instância da classe SqlConnection e passamos a string
de conexão:
SqlDataReader r = null;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandType = CommandType.Text;
Dentro dos blocos try, catch, finally, respectivamente, abrimos e exibimos os dados,
manipulamos as exceções que podem ocorrer e fechamos a conexão com o banco de dados.
try
{
conn.Open();
r = cmd.ExecuteReader(CommandBehavior.CloseConnection);
int t = r.GetOrdinal("total");
r.Read();
Response.Write(r.GetInt32(t) + "<br/>");
r.NextResult();
if (r.HasRows)
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 50 of 90
if (r.GetInt32(t) > 0)
while (r.Read())
string.Format(ci,"{0:c}", r.GetDecimal(valor))
e define a cultura como pt-BR - Português Brasil. Desta forma, a saída será sempre em reais,
independente do idioma usado pelo computador do usuário.
Response.Write("</table>");
catch (SqlException)
{
Response.Write("Erro SQL.");
}
finally
{
if (!r.IsClosed) r.Close();
}
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 51 of 90
using System.Globalization;
try
{
conn.Open();
r = cmd.ExecuteReader(CommandBehavior.CloseConnection);
int t = r.GetOrdinal("total");
Response.Write("<b><span style=\"text-decoration: underline\">Total de registros:</span></b> ");
r.Read();
Response.Write(r.GetInt32(t) + "<br/>");
r.NextResult();
if (r.HasRows)
{
int produto = r.GetOrdinal("ProductName");
int valor = r.GetOrdinal("UnitPrice");
Response.Write("<table><tr><td style=\"width: 150px\"><b>Produto</b></td><td style=\"width:
100px\"><b>Valor unitário</b></td></tr>");
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 52 of 90
Sobre o autor: Alfredo Lotar é consultor, programador, escritor. Desenvolve aplicações com ASP.NET,
JavaScript, XML, C#, Visual Basic e SQL Server. É autor do livro XML para Programadores ASP, da editora
Axcel Books, e dos livros ASP.NET com C# ? Curso Prático, e Como programar com ASP.NET e C#, ambos
publicados pela Novatec Editora. Atualmente, passa a maior parte do tempo desenvolvendo aplicações,
escrevendo livros ou artigos, testando códigos e analisando falhas de segurança em web sites de clientes.
O autor pode ser contactado pelo e-mail: alfredo.programador@bol.com.br.
GROUP BY é opcional. Os valores de resumo se omitem se não existe uma função SQL agregada
na instrução SELECT. Os valores Null nos campos GROUP BY se agrupam e não se omitem. Não
obstante, os valores Null não se avaliam em nenhuma das funções SQL agregadas.
Utiliza-se a cláusula WHERE para excluir aquelas filas que não deseja agrupar, e a cláusula
HAVING para filtrar os registros uma vez agrupados.
Ao menos que contenha um dado Memo ou Objeto OLE, um campo da lista de campos GROUP
BY pode se referir a qualquer campo das tabelas que aparecem na cláusula FROM, inclusive se o
campo não estiver incluído na instrução SELECT, sempre e quando a instrução SELECT incluir
pelo menos uma função SQL agregada.
Todos os campos da lista de campos de SELECT devem ou se incluir na cláusula GROUP BY, ou
como argumentos de uma função SQL agregada.
SELECT
IdFamilia, Sum(Stock) AS StockAtual
FROM
Produtos
GROUP BY
IdFamilia
Uma vez que GROUP BY combinou os registros, HAVING mostra qualquer registro agrupado
pela cláusula GROUP BY que satisfaça as condições da cláusula HAVING.
HAVING é similar a WHERE, determina que registros se selecionam. Uma vez que os registros
se agruparam utilizando GROUP BY, HAVING determina quais deles serão mostrados.
SELECT
IdFamilia, Sum(Stock) AS StockAtual
FROM
Produtos
GROUP BY
IdFamilia
HAVING
StockAtual > 100
AND
NomeProduto Like BOS*
AVG
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 53 of 90
Avg(expr)
Onde expr representa o campo que contém os dados numéricos para os que se deseja calcular
a média ou uma expressão que realiza um cálculo utilizando os dados de tal campo. A média
calculada por Avg é a média aritmética (a soma dos valores dividido pelo número de valores). A
função Avg não inclui nenhum campo Null no cálculo.
SELECT
Avg(Gastos) AS Promedio
FROM
Pedidos
WHERE
Gastos > 100
Count
Calcula o número de registros devolvidos por uma consulta. Sua sintaxe é a seguinte
Count(expr)
Onde expr contém o nome do campo que se deseja contar. Os operandos de expr podem incluir
o nome de um campo de uma tabela, uma constante ou uma função (a qual pode ser intrínseca
ou definida pelo usuário, mas não outras das funções agregadas de SQL). Pode contar com
qualquer tipo de dados inclusive texto.
Embora expr possa realizar um cálculo sobre um campo, Count simplesmente conta o número
de registros sem ter em conta que valores se armazenam nos registros. A função Count não
conta os registros que têm campos null a não ser que expr seja o caractere asterisco (*). Se
utilizar um asterisco, Count calcula o número total de registros, incluindo aqueles que contém
campos null. Count(*) é consideravelmente mais rápida que Count(Campo). Não se deve
colocar o asterisco entre aspas duplas ('*').
SELECT
Count(*) AS Total
FROM
Pedidos
SELECT
Count(DataEnvio & Transporte) AS Total
FROM
Pedidos
Podemos fazer com que o gestor conte os dados diferentes de um determinado campo
SELECT
Count(DISTINCT Localidade) AS Total
FROM
Pedidos
Max, Min
Min(expr)
Max(expr)
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 54 of 90
Onde expr é o campo sobre o qual se deseja realizar o cálculo. Expr pode incluir o nome de um
campo de uma tabela, uma constante ou uma função (a qual pode ser intrínseca ou definida
pelo usuário, porém não outras das funções agregadas de SQL).
SELECT
Min(Gastos) AS ElMin
FROM
Pedidos
WHERE
Pais = 'Espanha'
SELECT
Max(Gastos) AS ElMax
FROM
Pedidos
WHERE
Pais = 'Espanha'
StDev, StDevP
Devolve estimações do desvio padrão para a povoação (o total dos registros da tabela) ou uma
mostra da povoação representada (mostra aleatória). Sua sintaxe é:
StDev(expr)
StDevP(expr)
Onde expr representa o nome do campo que contém os dados que desejam avaliar ou uma
expressão que realiza um cálculo utilizando os dados de tais campos. Os operandos de expr
podem incluir o nome de um campo de uma tabela, uma constante ou uma função (a qual pode
ser intrínseca ou definida pelo usuário, porém não outras das funções agregadas de SQL).
StDevP avalia uma povoação, e StDev avalia uma mostra da povoação. Se a consulta contém
menos de dois registros (ou nenhum registro para StDevP), estas funções devolvem um valor
Null (o qual indica que o desvio padrão não pode se calcular).
SELECT
StDev(Gastos) AS Desvio
FROM
Pedidos
WHERE
País = 'Espanha'
SELECT
StDevP(Gastos) AS Desvio
FROM
Pedidos
WHERE
País = 'Espanha'
Sum
Devolve a soma do conjunto de valores contido em um campo especifico de uma consulta. Sua
sintaxe é:
Sum(expr)
Onde expr representa o nome do campo que contém os dados que se desejam somar ou uma
expressão que realiza um cálculo utilizando os dados de tais campos. Os operandos de expr
podem incluir o nome de um campo de uma tabela, uma constante ou uma função (a qual pode
ser intrínseca ou definida pelo usuário, mas não outras das funções agregadas de SQL).
SELECT
Sum(PrecoUnidade * Quantidad) AS Total
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 55 of 90
FROM
DetalhePedido
Var, VarP
Devolve uma estimação da variabilidade de uma povoação (sobre o total dos registros) ou uma
mostra da povoação (mostra aleatória de registros) sobre os valores de um campo. Sua sintaxe
é:
Var(expr)
VarP(expr)
VarP avalia uma povoação, e Var avalia uma mostra da povoação. Expr o nome do campo que
contém os dados que se desejam avaliar ou uma expressão que realiza um cálculo utilizando os
dados de tais campos. Os operandos de expr podem incluir o nome de um campo de uma
tabela, uma constante ou uma função (a qual pode ser intrínseca ou definida pelo usuário, mas
não outras das funções agregadas de SQL)
Se a consulta contiver menos de dois registros, Var e VarP devolvem Null (isto indica que a
variabilidade não pode ser calculada). Pode utilizar Var e VarP em uma expressão de consulta
ou em uma Instrução SQL.
SELECT
Var(Gastos) AS Variabilidade
FROM
Pedidos
WHERE
País = 'Espanha'
SELECT
VarP(Gastos) AS Variabilidade
FROM
Pedidos
WHERE
País = 'Espanha'
COMPUTE de SQL-SERVER
Esta cláusula acrescenta uma fila no conjunto de dados que se está recuperando, se utiliza para
realizar cálculos em campos numéricos. COMPUTE age sempre sobre um campo ou expressão
do conjunto de resultados e esta expressão deve figurar exatamente igual na cláusula SELECT e
sempre se deve ordenar o resultado pela mesma ou ao memos agrupar o resultado. Esta
expressão não pode utilizar nenhum ALIAS.
SELECT
IdCliente, Count(IdPedido)
FROM
Pedidos
GROUP BY
IdPedido
HAVING
Count(IdPedido) > 20
COMPUTE
Sum(Count(IdPedido))
SELECT
IdPedido, (PrecoUnidade * Quantidade - Desconto)
FROM
[Detalhes de Pedidos]
ORDER BY
IdPedido
COMPUTE
Sum((PrecoUnidade * Quantidade - Desconto)) // Calcula o Total
BY IdPedido // Calcula o Subtotal
Informe de Claudio
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 56 of 90
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Consultas de ação
As consultas de ação são aquelas que não devolvem nenhum registro, são as encarregadas de
ações como adicionar, excluir e modificar registros. Tanto as sentenças de atualização como as
de exclusão desencadeiarão (segundo o motor de dados) as atualizações em cascata, exclusões
em cascata, restrições e valores padrões definidos para os diferentes campos ou tabelas
afetadas pela consulta.
DELETE
Cria uma consulta de eliminação que elimina os registros de uma ou mais das tabelas listadas
na cláusula FROM que satisfaçam a cláusula WHERE. Esta consulta elimina os registros
completos, não é possível eliminar o conteúdo de algum campo em concreto. Sua sintaxe é:
Uma vez eliminados os registros utilizando uma consulta de exclusão, não se poderá desfazer a
operação. Se desejar saber que registros foram eliminados, primeiro examine os resultados de
uma consulta de seleção que utilize o mesmo critério e depois execute a consulta de exclusão.
Mantenha cópias de segurança (back ups) de seus dados em todo momento. Se eliminar os
registros errados poderá recuperá-los a través das cópias de segurança.
DELETE
FROM
Empregados
WHERE
Cargo = 'Vendedor'
INSERT INTO
Agrega um registro em uma tabela. É conhecida como uma consulta de dados adicionados. Esta
consulta pode ser de dois tipos: Inserir um único registro ou Inserir em uma tabela os registros
contidos em outra tabela.
Pode-se utilizar as consultas de criação de tabela para arquivar registros, fazer cópias de
segurança das tabelas ou fazer cópias para exportar a outro banco de dados ou utilizar em
informes que mostrem os dados de um período de tempo concreto. Por exemplo, se poderia
criar um informe de Vendas mensais por região executando a mesma consulta de criação de
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 57 of 90
Neste caso se selecionarão os campos 1,2,..., n da tabela origem e se gravarão nos campos
1,2,.., n da Tabela. A condição SELECT pode incluir a cláusula WHERE para filtrar os registros a
copiar. Se Tabela e Tabela Origem possuem a mesma estrutura podemos simplificar a sintaxe
a:
Desta forma os campos de Tabela Origem se gravarão em Tabela, para realizar esta operação é
necessário que todos os campos de Tabela Origem estejam contidos com igual nome em
Tabela. Com outras palavras que Tabela possua todos os campos de Tabela Origem (igual nome
e igual tipo).
Neste tipo de consulta há que ter especial atenção com os campos contadores ou auto-
numéricos visto que ao inserir um valor em um campo deste tipo se escreve o valor que
contenha seu campo homólogo na tabela origem, não incrementando-se como lhe corresponde.
Pode-se utilizar a instrução INSERT INTO para agregar um registro único a uma tabela,
utilizando a sintaxe da consulta de adição de registro único tal e como se mostrou
anteriormente. Nesse caso, seu código especifica o nome e o valor de cada campo do registro.
Deve especificar cada um dos campos do registro ao que se vai atribuir um valor assim como o
valor para tal campo. Quando não se especifica tal campo, se insere o valor pré-determinado ou
Null. Os registros se agregam no final da tabela.
Também se pode utilizar INSERT INTO para agregar um conjunto de registros pertencentes a
outra tabela ou consulta utilizando a cláusula SELECT... FROM como se mostrou anteriormente
na sintaxe da consulta de adição de múltiplos registros. Neste caso, a cláusula SELECT
especifica os campos que se vão agregar na tabela destino especificada.
A tabela destino ou origem pode especificar uma tabela ou uma consulta. Se a tabela destino
contiver uma chave principal, há que certificar-se que é a única, e com valores não nulos; se
não for assim, não se agregarão os registros. Se se agregam registros a uma tabela com um
campo Contador, não se deve incluir o campo Contador na consulta. Pode-se empregar a
cláusula IN para agregar registros a uma tabela em outro banco de dados.
Pode-se averiguar os registros que se agregarão na consulta executando primeiro uma consulta
de seleção que utilize o mesmo critério de seleção e ver o resultado. Uma consulta de adição
copia os registros de uma ou mais tabelas em outra. As tabelas que contém os registros que se
vão agregar não se verão afetadas pela consulta de adição. Ao invés de agregar registros
existentes em outra tabela, pode-se especificar os valores de cada campo em um novo registro
utilizando a cláusula VALUES. Se se omite a lista de campos, a cláusula VALUES deve incluir um
valor para cada campo da tabela, de outra forma falhará INSERT.
Exemplos
INSERT INTO
Clientes
SELECT
ClientesAntigos.*
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 58 of 90
FROM
ClientesNovos
SELECT
Empregados.*
INTO Programadores
FROM
Empregados
WHERE
Categoria = 'Programador'
Esta consulta cria uma tabela nova chamada programadores com a mesma estrutura que a
tabela empregado e copia aqueles registros cujo campo categoria seja programador
INSERT INTO
Empregados (Nome, Sobrenome, Cargo)
VALUES
(
'Luis', 'Sánchez', 'Estagiario'
)
INSERT INTO
Empregados
SELECT
Vendedores.*
FROM
Vendedores
WHERE
Cidade = 'Madri'
UPDATE
Cria uma consulta de atualização que muda os valores dos campos de uma tabela especificada
baseando-se em um critério específico. Sua sintaxe é:
UPDATE
Pedidos
SET
Pedido = Pedidos * 1.1,
Transporte = Transporte * 1.03
WHERE
PaisEnvio = 'ES'
UPDATE não gera nenhum resultado. Para saber que registros mudarão, há que examinar
primeiro o resultado de uma consulta de seleção que utilize o mesmo critério e depois executar
a consulta de atualização.
UPDATE
Empregados
SET
Grau = 5
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 59 of 90
WHERE
Grau = 2
UPDATE
Produtos
SET
Preco = Preco * 1.1
WHERE
Provedor = 8
AND
Familia = 3
UPDATE
Empregados
SET
Salario = Salario * 1.1
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Tipo de
Longitude Descrição
Dados
Para consultas sobre tabela anexa de produtos de banco de dados
BINARY 1 byte
que definem um tipo de dados Binário.
BIT 1 byte Valores Sim/Não ou True/False
BYTE 1 byte Um valor inteiro entre 0 e 255.
COUNTER 4 bytes Um número incrementado automaticamente (de tipo Long)
Um inteiro escalável entre 922.337.203.685.477,5808 e
CURRENCY 8 bytes
922.337.203.685.477,5807.
DATETIME 8 bytes Um valor de data ou hora entre os anos 100 e 9999.
Um valor em ponto flutuante de precisão simples com uma
classificação de - 3.402823*1038 a -1.401298*10-45 para
SINGLE 4 bytes
valores negativos, 1.401298*10- 45 a 3.402823*1038 para
valores positivos, e 0.
Um valor em ponto flutuante de dupla precisão com uma
classificação de - 1.79769313486232*10308 a -
DOUBLE 8 bytes 4.94065645841247*10-324 para valores negativos,
4.94065645841247*10-324 a 1.79769313486232*10308 para
valores positivos, e 0.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 60 of 90
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 61 of 90
Subconsultas em SQL
Uma subconsulta é uma instrução SELECT adicionada dentro de uma instrução SELECT,
SELECT...INTO, INSERT...INTO, DELETE, ou UPDATE ou dentro de outra subconsulta. Pode
utilizar três formas de sintaxe para criar uma subconsulta:
comparação [ANY | ALL | SOME] (instrução sql) expressão [NOT] IN (instrução sql) [NOT] EXISTS (instrução sql)
Onde:
Pode-se utilizar uma subconsulta no lugar de uma expressão na lista de campos de uma
instrução SELECT ou em uma cláusula WHERE ou HAVING. Em uma subconsulta, se utiliza uma
instrução SELECT para proporcionar um conjunto de um ou mais valores especificados para
avaliar na expressão da cláusula WHERE ou HAVING.
Pode-se utilizar o predicado ANY ou SOME, os quais são sinônimos, para recuperar registros da
consulta principal, que satisfaçam a comparação com qualquer outro registro recuperado na
subconsulta. O exemplo seguinte devolve todos os produtos cujo preço unitário for maior que o
de qualquer produto vendido com um desconto igual ou maior ao 25 por cento:
SELECT *
FROM
Produtos
WHERE
PrecoUnidade
ANY
(
SELECT
PrecoUnidade
FROM
DetalhePedido
WHERE
Desconto = 0 .25
)
O predicado ALL se utiliza para recuperar unicamente aqueles registros da consulta principal
que satisfazem a comparação com todos os registros recuperados na subconsulta. Se se muda
ANY por ALL no exemplo anterior, a consulta devolverá unicamente aqueles produtos cujo preço
unitário for maior que o de todos os produtos vendidos com um desconto igual ou maior ao 25
por cento. Isto é muito mais restritivo.
SELECT *
FROM
Produtos
WHERE
IDProduto
IN
(
SELECT
IDProduto
FROM
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 62 of 90
DetalhePedido
WHERE
Desconto = 0.25
)
Inversamente, pode-se utilizar NOT IN para recuperar unicamente aqueles registros da consulta
principal para os que não têm nenhum registro da subconsulta que contenha um valor igual.
SELECT
Clientes.Companhia, Clientes.Telefone
FROM
Clientes
WHERE EXISTS (
SELECT
FROM
Pedidos
WHERE
Pedidos.IdPedido = Clientes.IdCliente
)
SELECT
Clientes.Companhia, Clientes.Telefone
FROM
Clientes
WHERE
IdClientes
IN
(
SELECT
Pedidos.IdCliente
FROM
Pedidos
)
Pode-se utilizar também alias do nome da tabela em uma subconsulta para se referir às tabelas
listadas na cláusula FROM fora da subconsulta. O exemplo seguinte devolve os nomes dos
empregados cujo salário for igual ou maior do que o salário médio de todos os empregados com
o mesmo título. À tabela Empregados foi dado o alias T1:
SELECT
Sobrenome, Nome, Titulo, Salario
FROM
Empregados AS T1
WHERE
Salario =
(
SELECT
Avg(Salario)
FROM
Empregados
WHERE
T1.Titulo = Empregados.Titulo
)
ORDER BY Titulo
SELECT
Sobrenomes, Nome, Cargo, Salario
FROM
Empregados
WHERE
Cargo LIKE 'Agente Ven*'
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 63 of 90
AND
Salario ALL
(
SELECT
Salario
FROM
Empregados
WHERE
Cargo LIKE '*Chefe*'
OR
Cargo LIKE '*Diretor*'
)
(Obtém uma lista com o nome, cargo e salário de todos os agentes de ventas cujo salário for
maior que o de todos os chefes e diretores.)
SELECT DISTINCT
NomeProduto, Preco_Unidade
FROM
Produtos
WHERE
PrecoUnidade =
(
SELECT
PrecoUnidade
FROM
Produtos
WHERE
NomeProduto = 'Almíbar anisado'
)
(Obtém uma lista com o nome e o preço unitário de todos os produtos com o mesmo preço que
o almíbar anisado.)
SELECT DISTINCT
NomeContato, NomeCompanhia, CargoContato, Telefone
FROM
Clientes
WHERE
IdCliente IN (
SELECT DISTINCT IdCliente
FROM Pedidos
WHERE DataPedido <#07/01/1993#
)
(Obtém uma lista das companhias e dos contatos de todos os clientes que realizaram um
pedido no segundo trimestre de 1993.)
SELECT
Nome, Sobrenomes
FROM
Empregados AS E
WHERE EXISTS
(
SELECT *
FROM
Pedidos AS O
WHERE O.IdEmpregado = E.IdEmpregado
)
SELECT DISTINCT
Pedidos.Id_Produto, Pedidos.Quantidade,
(
SELECT
Produtos.Nome
FROM
Produtos
WHERE
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 64 of 90
Produtos.IdProduto = Pedidos.IdProduto
) AS ElProduto
FROM
Pedidos
WHERE
Pedidos.Quantidade = 150
ORDER BY
Pedidos.Id_Produto
SELECT
NumVoo, Lugares
FROM
Voos
WHERE
Origem = 'Madri'
AND Exists (
SELECT T1.NumVoo FROM Voos AS T1
WHERE T1.LuagaresLivres > 0 AND T1.NumVuelo=Vuelos.NumVuelo)
(Recupera números de vôo e capacidades de aqueles vôos com destino Madri e lugares livres
Suponhamos agora que temos uma tabela com os identificadores de todos nossos produtos e o
stock de cada um deles. Em outra tabela se encontram todos os pedidos que temos pendentes
de servir. Trata-se de averiguar que produtos não se podem servir por falta de estoque.
SELECT
PedidosPendentes.Nome
FROM
PedidosPendentes
GROUP BY
PedidosPendentes.Nome
HAVING
SUM(PedidosPendentes.Quantidade <
(
SELECT
Produtos.Estoque
FROM
Produtos
WHERE
Produtos.IdProduto = PedidosPendentes.IdProduto
)
)
Suponhamos que em nossa tabela de empregados desejamos buscar todas as mulheres cuja
idade seja maior da de qualquer homem:
SELECT
Empregados.Nome
FROM
Empregados
WHERE
Sexo = 'M' AND Idade > ANY
(SELECT Empregados.Idade FROM Empregados WHERE Sexo ='H')
SELECT
Empregados.Nome
FROM
Empregados
WHERE
Sexo = 'M' AND Idade >
(SELECT Max( Empregados.Idade )FROM Empregados WHERE Sexo ='H')
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 65 of 90
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
As vinculações entre tabelas se realizam mediante a cláusula INNER que combina registros de
duas tabelas sempre que tiver concordância de valores em um campo comum. Sua sintaxe é:
Onde:
tb1, tb2 São os nomes das tabelas desde as que se combinam os registros.
São os nomes dos campos que se combinam. Se não são numéricos, os campos
campo1,
devem ser do mesmo tipo de dados e conter o mesmo tipo de dados, porém não
campo2
tem que ter o mesmo nome.
comp É qualquer operador de comparação relacional: =, <,<>, <=, =>, ó >.
Pode-se utilizar uma operação INNER JOIN em qualquer cláusula FROM. Isto cria uma
combinação por equivalência, conhecida também como união interna. As combinações
equivalentes são as mais comuns; estas combinam os registros de duas tabelas sempre que
tiver concordância de valores em um campo comum a ambas tabelas. Pode-se utilizar INNER
JOIN com as tabelas Departamentos e Empregados para selecionar todos os empregados de
cada departamento. Do contrário, para selecionar todos os departamentos (inclusive se algum
deles não tiver nenhum empregado atribuído) se emprega LEFT JOIN ou todos os empregados
(inclusive se algum não estiver atribuído a nenhum departamento), neste caso RIGHT JOIN.
Se se tenta combinar campos que contenham dados Memo ou Objeto OLE, se produz um erro.
Podem-se combinar dois campos numéricos quaisquer, inclusive se são de diferentes tipos de
dados. Por exemplo, pode combinar um campo Numérico para o que a propriedade Size de seu
objeto Field está estabelecida como Inteiro, e um campo Contador.
O exemplo seguinte mostra como poderia combinar as tabelas Categorias e Produtos baseando-
se no campo IDCategoria:
SELECT
NomeCategoria, NomeProduto
FROM
Categorias
INNER JOIN
Produtos
ON
Categorias.IDCategoria = Produtos.IDCategoria
No exemplo anterior, IDCategoria é o campo combinado, porém não está incluído na saída da
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 66 of 90
consulta já que não está incluído na instrução SELECT. Para incluir o campo combinado, incluir
o nome do campo na instrução SELECT, neste caso, Categorias.IDCategoria.
Também se pode linkar várias cláusulas ON em uma instrução JOIN, utilizando a seguinte
sintaxe:
SELECT campos FROM tb1 INNER JOIN (tb2 INNER JOIN [( ]tb3
[INNER JOIN [( ]tablax [INNER JOIN ...)]
ON tb3.campo3 comp tbx.campox)]
ON tb2.campo2 comp tb3.campo3)
ON tb1.campo1 comp tb2.campo2
Um LEFT JOIN ou um RIGHT JOIN pode se aninhar dentro de um INNER JOIN, porém um INNER
JOIN não pode se aninhar dentro de um LEFT JOIN ou um RIGHT JOIN.
Exemplo:
SELECT DISTINCT
Sum(PrecoUnitario * Quantidade) AS Sales,
(Nome + ' ' + Sobrenome) AS Name
FROM
Empregados
INNER JOIN(
Pedidos
INNER JOIN
DetalhesPedidos
ON
Pedidos.IdPedido = DetalhesPedidos.IdPedido)
ON
Empregados.IdEmpregado = Pedidos.IdEmpregado
GROUP BY
Nome + ' ' + Sobrenome
(Cria duas combinações equivalentes: uma entre as tabelas Detalhes de pedidos e Pedidos, e a
outra entre as tabelas Pedidos e Empregados. Isto é necessário já que a tabela Empregados
não contem dados de vendas e a tabela Detalhes de pedidos não contem dados dos
empregados. A consulta produz uma lista de empregados e suas vendas totais.)
A sintaxe exposta anteriormente pertence a ACCESS, onde todas as sentenças com a sintaxe
funcionam corretamente. Os manuais de SQL-SERVER dizem que esta sintaxe é incorreta e que
há que adicionar a palavra reservada OUTER: LEFT OUTER JOIN e RIGHT OUTER JOIN. Na
prática funciona corretamente de uma forma ou de outra.
Não obstante, os INNER JOIN ORACLE não é capaz de interpretá-los, mas existe uma sintaxe
em formato ANSI para os INNER JOIN que funcionam em todos os sistemas. Tomando como
referência a seguinte sentença:
SELECT
Faturas.*,
Alvaras.*
FROM
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 67 of 90
Faturas
INNER JOIN
Alvaras
ON
Faturas.IdAlvara = Alvaras.IdAlvara
WHERE
Faturas.IdCliente = 325
SELECT
Faturas.*,
Alvaras.*
FROM
Faturas, Alvaras
WHERE
Faturas.IdAlvara = Alvaras.IdAlvara
AND
Faturas.IdCliente = 325
Referente aos OUTER JOIN, não funcionam em ORACLE e ademais conheço uma sintaxe que
funciona nos três sistemas. A sintaxe em ORACLE é igual à sentença anterior, porém
adicionando os caracteres (+) atrás do nome da tabela na qual desejamos aceitar valores
nulos, isto equivale a um LEFT JOIN:
SELECT
Faturas.*,
Alvaras.*
FROM
Faturas, Alvaras
WHERE
Faturas.IdAlvara = Alvaras.IdAlvara (+)
AND
Faturas.IdCliente = 325
SELECT
Faturas.*,
Alvaras.*
FROM
Faturas, Alvaras
WHERE
Faturas.IdAlvara (+) = Alvaras.IdAlvara
AND
Faturas.IdCliente = 325
Em SQL-SERVER se pode utilizar uma sintaxe parecida, neste caso não se utiliza os caracteres
(+), e sim os caracteres =* para o LEFT JOIN e *= para o RIGHT JOIN.
Consultas de Auto-combinação
A auto-combinação se utiliza para unir uma tabela consigo mesma, comparando valores de
duas colunas com o mesmo tipo de dados. A sintaxe na seguinte:
SELECT
alias1.coluna, alias2.coluna, ...
FROM
tabla1 as alias1, tabela2 as alias2
WHERE
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 68 of 90
alias1.coluna = alias2.coluna
AND
outras condicoes
Por exemplo, para visualizar o número, nome e posto de cada empregado, junto com o número,
nome e posto do supervisor de cada um deles se utilizaria a seguinte sentença:
SELECT
t.num_emp, t.nome, t.posto, t.num_sup,s.nome, s.posto
FROM
empregados AS t, empregados AS s
WHERE
t.num_sup = s.num_emp
A maioria das combinações está baseada na igualdade de valores das colunas que são o critério
da combinação. As não comuns se baseiam em outros operadores de combinação, tais como
NOT, BETWEEN, <>, etc.
Por exemplo, para listar o grau salarial, nome, salário e posto de cada empregado ordenando o
resultado por grau e salário haveria que executar a seguinte sentença:
SELECT
graus.grau,empregados.nome, empregados.salario, empregados.posto
FROM
empregados, graus
WHERE
empregados.salario BETWEEN grados.salarioinferior And grados.salariosuperior
ORDER BY
grados.grado, empregados.salario
Para listar o salário médio dentro de cada grau salarial haveria que lançar esta outra sentença:
SELECT
graus.grau, AVG(empregados.salario)
FROM
empregados, graus
WHERE
empregados.salario BETWEEN graus.salarioinferior And graus.salariosuperior
GROUP BY
graus.grau
Utiliza-se em SQL-SERVER para realizar consultas de união. Suponhamos que temos uma
tabela com todos os autores e outra com todos os livros. Se desejássemos obter uma listagem
combinando ambas tabelas de tal forma que cada autor aparecesse junto a cada título,
utilizaríamos a seguinte sintaxe:
SELECT
Autores.Nome, Livros.Titulo
FROM
Autores CROSS JOIN Livros
SELF JOIN
SELF JOIN é uma técnica empregada para conseguir o produto cartesiano de uma tabela
consigo mesma. Sua utilização não é muito freqüente, mas colocaremos algum exemplo de sua
utilização.
Suponhamos a seguinte tabela (O campo autor é numérico, embora para ilustrar o exemplo
utilize o nome):
Autores
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 69 of 90
SELECT
A.Codigo, A.Autor, B.Autor
FROM
Autores A, Autores B
WHERE
A.Codigo = B.Codigo
O resultado é o seguinte:
Como podemos observar, os pares de autores se repetem em cada um dos livros, podemos
omitir estas repetições da seguinte forma:
SELECT
A.Codigo, A.Autor, B.Autor
FROM
Autores A, Autores B
WHERE
A.Codigo = B.Codigo AND A.Autor < B.Autor
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 70 of 90
SELECT
Homens.Nome, Mulheres.Nome
FROM
Empregados Homem, Empregados Mulheres
WHERE
Homem.Sexo = 'Homem' AND
Mulheres.Sexo = 'Mulher' AND
Homens.Id <>Mulheres.Id
Empregados
Id Nome SeuChefe
1 Marcos 6
2 Lucas 1
3 Ana 2
4 Eva 1
5 Juan 6
6 Antonio
Queremos obter um conjunto de resultados com o nome do empregado e o nome de seu chefe:
SELECT
Empre.Nome, Chefes.Nome
FROM
Empregados Empre, Empregados Chefe
WHERE
Empre.SeuChefe = Chefes.Id
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 71 of 90
Onde:
CREATE TABLE
Empregados (
Nome TEXT (25),
Sobrenomes TEXT (50)
)
(Cria uma nova tabela chamada Empregados com dois campos, um chamado Nome de tipo
texto e longitud 25 e outro chamado sobrenomes com longitude 50).
CREATE TABLE
Empregados (
Nome TEXT (10),
Sobrenomes TEXT,
DataNascimento DATETIME
)
CONSTRAINT
IndiceGeral
UNIQUE (
Nome, Sobrenomes, DataNascimento
)
(Cria uma nova tabela chamada Empregados com um campo Nome de tipo texto e longitude
10, outro chamado Sobrenomes de tipo texto e longitude pré-determinada (50) e um mais
chamado DataNascimento de tipo Data/Hora. Também cria um índice único - não permite
valores repetidos - formado pelos três campos.)
CREATE TABLE
Empregados (
IdEmpregado INTEGER CONSTRAINT IndicePrimario PRIMARY,
Nome TEXT,
Sobrenomes TEXT,
DataNascimento DATETIME
)
(Cria uma tabela chamada Empregados com um campo Texto de longitude pré-determinada
(50) chamado Nome e outro igual chamado Sobrenomes, cria outro campo chamado
DataNascimento de tipo Data/Hora e o campo IdEmpregado de tipo inteiro o que estabelece
como chave principal.)
A cláusula CONSTRAINT
Utiliza-se a cláusula CONSTRAINT nas instruções ALTER TABLE e CREATE TABLE para criar ou
eliminar índices. Existem duas sintaxes para esta cláusula dependendo se deseja Criar ou
Eliminar um índice de um único campo ou se se trata de um campo multi-índice. Se se utiliza o
motor de dados de Microsoft, só poderá utilizar esta cláusula com os bancos de dados próprias
de tal motor. Para os índices de campos únicos:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 72 of 90
Onde:
Se se deseja criar um índice para um campo quando se está utilizando as instruções ALTER
TABLE ou CREATE TABLE a cláusula CONTRAINT deve aparecer imediatamente depois da
especificação do campo indexado.
Se se deseja criar um índice com múltiples campos quando se está utilizando as instruções
ALTER TABLE ou CREATE TABLE a cláusula CONSTRAINT deve aparecer fora da cláusula de
criação de tabela.
Indice Descrição
Gera um índice de chave única. O que implica que os registros da tabela não podem
UNIQUE
conter o mesmo valor nos campos indexados.
Gera um índice primário o campo ou os campos especificados. Todos os campos da
PRIMARY
chave principal devem ser únicos e não nulos, cada tabela só pode conter uma
KEY
única chave principal.
Gera um índice externo (toma como valor do índice campos contidos em outras
tabelas). Se a chave principal da tabela externa consta de mais de um campo, se
deve utilizar uma definição de índice de múltiplos campos, listando todos os campos
de referência, o nome da tabela externa, e os nomes dos campos referenciados na
FOREIGN
tabela externa na mesma ordem que os campos de referência listados. Se os
KEY
campos referenciados são a chave principal da tabela externa, não tem que
especificar os campos referenciados, pré-determinado por valor, o motor Jet se
comporta como se a chave principal da tabela externa estivesse formada pelos
campos referenciados.
Criação de Índices
Se se utiliza o motor de dados Jet de Microsoft só se podem criar índices em banco ed dados do
mesmo motor. A sintaxe para criar um índice em uma tabela já definida na seguinte:
Onde:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 73 of 90
No caso de ACCESS, se pode utilizar CREATE INDEX para criar um pseudo índice sobre uma
tabela adjunta em uma fonte de dados ODBC tal como SQL Server que não tenha ainda um
índice. Não necessita permissão ou ter acesso a um servidor remoto para criar um pseudo
índice, ademais o banco de dados remoto não é consciente e não é afetado pelo pseudo índice.
Utiliza-se a mesma sintaxe para as tabelas adjuntas que para as originais. Isto é especialmente
útil para criar um índice em uma tabela que seria só de leitura devido à falta de um índice.
CREATE INDEX
MeuIndice
ON
Empregados (Prefixo, Telefone)
(Cria um índice chamado MeuIndice na tabela empregados com os campos Prefixo e Telefone.)
Onde:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 74 of 90
Operação Descrição
ADD Utiliza-se para adicionar um novo campo à tabela, indicando o nome, o tipo de
COLUMN campo e opcionalmente o tamanho (para campos de tipo texto).
ADD Utiliza-se para agregar um índice de multicampos ou de um único campo.
DROP
Utiliza-se para apagar um campo. Especifica-se unicamente o nome do campo.
COLUMN
Utiliza-se para eliminar um índice. Especifica-se unicamente o nome do índice a
DROP
seguir da palavra reservada CONSTRAINT.
ALTER TABLE
Empregados
ADD COLUMN
Salario CURRENCY
(Agrega um campo Salario de tipo Moeda a tabela Empregados.)
ALTER TABLE
Empregados
DROP COLUMN
Salario
(Elimina o campo Salario da tabela Empregados.)
ALTER TABLE
Pedidos
ADD CONSTRAINT
RelacaoPedidos
FOREIGN KEY
(IdEmpregado)
REFERENCES
Empregados (IdEmpregado)
(Agrega um índice externo à tabela Pedidos. O índice externo se baseia no campo IdEmpregado e se refere ao campo
IdEmpregado da tabela Empregados. Neste exemplo, não é necessário indicar o campo junto ao nome da tabela na
cláusula REFERENCES, pois ID_Empregado é a chave principal da tabela Empregados.)
ALTER TABLE
Pedidos
DROP CONSTRAINT
RelacaoPedidos
(Elimina o índice da tabela Pedidos.)
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Cursores em SQL
Em alguns SGDB é possível a abertura de cursores de dados desde o próprio ambiente de
trabalho, para isso se utilizam, normalmente procedimentos armazenados. A sintaxe para
definir um cursor é a seguinte:
DECLARE
nome-cursor
FOR
especificacao-consulta
[ORDER BY]
Por exemplo:
DECLARE
Meu_Cursor
FOR
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 75 of 90
Este comando é meramente declarativo, simplesmente especifica as filas e colunas que iremos
recuperar. A consulta se executa quando se abre ou se ativa o cursor. A cláusula [ORDER BY] é
opcional e especifica uma ordenação para as filas do cursor; se não se especifica, a ordenação
das filas é definida pelo gerenciador de SGBD.
Para abrir ou ativar um cursor se utiliza o comando OPEN do SQL, a sintaxe é a seguinte:
OPEN
nome-cursor
[USING lista-variaveis]
Ao abrir o cursor, avalia-se a consulta que aparece em sua definição, utilizando os valores
atuais de qualquer parâmetro referenciado na consulta, para produzir uma coleção de filas. O
ponteiro se posiciona diante da primeira fila de dados (registro atual), esta sentença não
recupera nenhuma fila.
Uma vez aberto o cursor, utiliza-se a cláusula FETCH para recuperar as filas do cursor, a sintaxe
é a seguinte:
FETCH
nome-cursor
INTO
lista-variaveis
Lista - variaveis são as variáveis que vão conter os dados recuperados da fila do cursor, na
definição devem ir separadas por vírgulas. Na lista de variáveis, deve-se definir tantas variáveis
como colunas quantas tiver a fila a recuperar.
Para fechar um cursor, utiliza-se o comando CLOSE, este comando faz desaparecer o ponteiro
sobre o registro atual. A sintaxe é:
CLOSE
nome-cursor
Por último, e para eliminar o cursor, utiliza-se o comando DROP CURSOR. Sua sintaxe é a
seguinte:
DROP CURSOR
nome-cursor
WHILE @@FETCH_STATUS = 0
BEGIN
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 76 of 90
END
CLOSE Employee_Cursor
DEALLOCATE Employee_Cursor
SET NOCOUNT ON
DECLARE
@au_id varchar(11),
@au_fname varchar(20),
@au_lname varchar(40),
@message varchar(80),
@title varchar(80)
OPEN authors_cursor
FETCH NEXT FROM authors_cursor
INTO @au_id, @au_fname, @au_lname
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
PRINT @message
SELECT t.title
OPEN titles_cursor
IF @@FETCH_STATUS <> 0
WHILE @@FETCH_STATUS = 0
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 77 of 90
BEGIN
PRINT @message
END
CLOSE titles_cursor
DEALLOCATE titles_cursor
Percorrer um cursor
USE pubs
GO
DECLARE authors_cursor CURSOR FOR
SELECT au_lname
FROM authors
WHERE au_lname LIKE "B%"
ORDER BY au_lname
OPEN authors_cursor
FETCH NEXT FROM authors_cursor
WHILE @@FETCH_STATUS = 0
BEGIN
END
CLOSE authors_cursor
DEALLOCATE authors_cursor
USE pubs
GO
DECLARE @au_lname varchar(40)
DECLARE @au_fname varchar(20)
OPEN authors_cursor
FETCH NEXT FROM authors_cursor INTO @au_lname, @au_fname
WHILE @@FETCH_STATUS = 0
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 78 of 90
BEGIN
END
CLOSE authors_cursor
DEALLOCATE authors_cursor
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Se tivermos uma tabela de produtos e outra tabela de pedidos, podemos visualizar em total de
produtos pedidos por ano para um artigo determinado, tal e como se visualiza na tabela
anterior. A sintaxe para este tipo de consulta é a seguinte:
Onde:
Para resumir dados utilizando uma consulta de referência cruzada, se selecionam os valores dos
campos ou expressões especificadas como cabeçalhos de colunas de tal forma que podem se
ver os dados em um formato mais compacto que com uma consulta de seleção.
TRANSFORM é opcional, porém se for incluída é a primeira instrução de uma cadeia SQL.
Precede à instrução SELECT que especifica os campos utilizados como cabeçalhos de fila e uma
cláusula GROUP BY que especifica o agrupamento das filas. Opcionalmente pode incluir outras
cláusulas como, por exemplo, WHERE, que especifica uma seleção adicional ou um critério de
ordenação.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 79 of 90
Também pode incluir valores fixos, para os que não existem dados, para criar colunas
adicionais.
Exemplos
TRANSFORM
Sum(Quantidade) AS Vendas
SELECT
Produto, Quantidade
FROM
Pedidos
WHERE
Data Between #01-01-1998# And #12-31-1998#
GROUP BY
Produto
ORDER BY
Produto
PIVOT
DatePart("m", Data)
(Cria uma consulta de tabela de referências cruzadas que mostra as vendas de produtos por mês para um ano
específico. Os meses aparecem da esquerda à direita como colunas e os nomes dos produtos aparecem de cima para
baixo como filas.)
TRANSFORM
Sum(Quantidade) AS Vendas
SELECT
Companhia
FROM
Pedidos
WHERE
Data Between #01-01-1998# And #12-31-1998#
GROUP BY
Companhia
ORDER BY
Companhia
PIVOT
"Trimestre " &
DatePart("q", Data)
In ('Trimestre1', 'Trimestre2', 'Trimestre 3', 'Trimestre 4')
(Cria uma consulta de tabela de referências cruzadas que mostra as vendas de produtos por trimestre de cada provedor
no ano indicado. Os trimestres aparecem da esquerda à direta como colunas e os nomes dos provedores aparecem de
cima para baixo como filas.)
Um caso prático:
Trata-se de resolver o seguinte problema: temos uma tabela de produtos com dois campos, o
código e o nome do produto. Temos outra tabela de pedidos na que anotamos o código do
produto, a data do pedido e a quantidade pedida. Desejamos consultar os totais de produto por
ano, calculando a média anual de vendas.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 80 of 90
TRANSFORM
Sum(Pedidos.Quantidade) AS Resultado
SELECT
Nombre AS Produto, Pedidos.Id AS Código,
Sum(Pedidos.Quantidade) AS TOTAL,
Avg(Pedidos.Quantidade) AS Media
FROM
Pedidos, Artigos
WHERE
Pedidos.Id = Artigos.Id
GROUP BY
Pedidos.Id, Artigos.Nome
PIVOT
Year(Data)
Comentários à consulta:
A cláusula TRANSFORM indica o valor que desejamos visualizar nas colunas que realmente
pertencem à consulta, neste caso 1996 e 1997, visto que ademais colunas são opcionais.
SELECT especifica o nome das colunas opcionais que desejamos visualizar, neste caso, Produto,
Código, Total e Média, indicando o nome do campo que desejamos mostrar em cada coluna ou
o valor da mesma. Se incluirmos uma função de cálculo o resultado se fará baseando-se nos
dados da fila atual e não ao total dos dados.
FROM especifica a origem dos dados. A primeira tabela que deve figurar é aquela de onde
desejamos extrair os dados, esta tabela deve conter ao menos três campos, um para os títulos
da fila, outros para os títulos da coluna e outro para calcular o valor das células.
Neste caso em concreto se desejava visualizar o nome do produto, como na tabela de pedidos
só figurava o código do mesmo se adicionou uma nova coluna na cláusula select chamada
Produto que se corresponda com o campo Nome da tabela de artigos. Para vincular o código do
artigo da tabela de pedidos com o nome do mesmo da tabela artigos, foi inserido a cláusula
INNER JOIN.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 81 of 90
registros pelo campo do qual extrairemos a informação. Neste caso existem dois campos dos
que extraímos a informação: pedidos.quantidade e artigos.nome, por isso, agrupamos pelos
campos.
Para finalizar, a cláusula PIVOT indica o nome das colunas não opcionais, neste caso 1996 e
1997 e como vamos ao dado que aparecerá nas colunas, neste caso empregamos o ano em que
se produziu o pedido, extraindo-o do campo pedidos.fecha.
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Os catálogos não se atualizam automaticamente nem se salvam junto com o banco de dados e
cada tabela pode ter um único catálogo.
Para a utilização destes catálogos dentro de uma consulta, podemos utilizar dois métodos, o
primeiro consiste em incluir os critérios dentro de uma cláusula WHERE (CONTAINS ou
FREETEXT) e o segundo é utilizando uma tabela temporária que contém o ratio de acerto na
consulta (CONTAINSTABLE ou FREETEXTTABLE).
O predicado CONTAINS
Utiliza-se este predicado para buscar um texto específico em uma tabela. Seu funcionamento é
similar ao predicado LIKE, a diferença é que este não pode realizar buscas nos campos grandes
de texto. CONTAINS não diferencia entre maiúsculas e minúsculas.
Sintaxe:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 82 of 90
Esta busca permite indicar o peso que terá cada uma das palavras ou frases que se buscam
sobre o resultado da busca, o peso oscila entre o valor mais baixo 0.0 e o valor mais alto 1.0.
Podemos realizar buscas por duas palavras e indicar que se encontrem próximas uma da outra.
A ordem das palavras não altera o resultado da busca.
Podem-se indicar três palavras, de tal forma que a segunda e a primeira devem estar próximas
ao igual que a segunda e a terceira.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 83 of 90
O predicado FREETEXT
Ao utilizar este predicado se analisam todas as palavras das frases e nos devolve como
resultado, aqueles registros que contém a frase completa ou algum fragmento da mesma. A
sintaxe é igual que o predicado CONTAINS.
... FREETEXT(descricao, ' "Em um lugar da mancha de cujo nome não quero me lembrar" ')
O predicado CONTAINSTABLE
Este predicado tem igual funcionamento e sintaxe que CONTAINS a diferença que neste caso
devolve uma tabela com duas colunas, a primeira chamada [KEY] contem o valor da chave
primária da tabela que a que buscamos, a segunda chamada RANK devolve um valor indicando
a porcentagem de acerto na busca para cada registro.
O predicado FREETEXTTABLE
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Para especificar um banco de dados que não pertence a Access Basic, se agrega um ponto e
vírgula (;) ao nome e se fecha entre aspas simples. Também pode utilizar a palavra reservada
DATABASE para especificar o banco de dados externo. Por exemplo, as linhas seguintes
especificam a mesma tabela:
SELECT
IdCliente
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 84 of 90
FROM
Clientes
IN 'C:\MEUSDADOS.MDB'
WHERE
IDCliente Like 'A*'
SELECT
IdCliente
FROM
Clientes
IN 'C:\DBANCO\DADOS\VENDAS' 'dBASE IV';
WHERE
IDCliente Like 'A*'
(Para recuperar dados de uma tabela de dBASE III+ há que utilizar 'dBASE III+;' em lugar de
'dBASE IV;'.)
SELECT
IdCliente
FROM
Clientes
IN 'C:\PARADOX\DADOS\VENDAS' 'Paradox 4.x;'
WHERE
IDCliente Like 'A*'
(Para recuperar dados de uma tabela de Paradox versão 3.x, há que substituir 'Paradox 4.x;'
por 'Paradox 3.x;'.)
SELECT
IdCliente
FROM
Clientes
IN 'C:\BTRIEVE\DADOS\VENDAS\FILE.DDF' 'Btrieve;'
WHERE
IDCliente Like 'A*'
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
As consultas com parâmetros são aquelas cujas condições de busca se definem mediante
parâmetros. Se se executam diretamente desde o banco de dados onde foram definidas
aparecerá uma mensagem solicitando o valor de cada um dos parâmetros. Se desejarmos
executá-las desde uma aplicação há que atribuir primeiro o valor dos parâmetros e depois
executá-las. Sua sintaxe é a seguinte:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 85 of 90
Onde:
Podem-se utilizar nomes, mas não tipos de dados em uma cláusula WHERE ou HAVING.
PARAMETERS
PrecoMinimo Currency,
DataInicio DateTime;
SELECT
IdPedido, Quantidade
FROM
Pedidos
WHERE
Preco = PrecoMinimo
AND
DataPedido = DataInicio
SELECT
Sobrenome, Nome, Salario
FROM
Empregados
ORDER BY
Sobrenome
WITH OWNERACCESS OPTION
Esta opção requer que esteja declarado o acesso ao arquivo de grupo de trabalho (geralmente
system.mda ou system .mdw) do banco de dados atual.
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Esta cláusula é pouco usual e se utiliza para criar uma consulta ao mesmo tempo que se
executa, opcionalmente define os parâmetros da mesma. Sua sintaxe é a seguinte:
Onde:
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 86 of 90
PROCEDURE
ListaCategorias;
SELECT DISTINCTROW
NomeCategoria, IdCategoria
FROM
Categorias
ORDER BY
NomeCategoria
(Atribui o nome Lista_de_categorias à consulta e a executa.)
PROCEDURE
Resumo
DataInicio DATETIME,
DtaaFinal DATETIME;
SELECT DISTINCTROW
DataEnvio, IdPedido, ImportePedido, Format(DataEnvio, "yyyy") AS Ano
FROM
Pedidos
WHERE
DataEnvio Between DataInicio And DataFinal
(Atribui o nome Resumo à consulta e inclui dois parâmetros.)
Para gerar este tipo de consultas o mais simples é utilizar o assistente de consultas de Access,
editar a sentença SQL da consulta e colá-la em nosso código. Não obstante, este tipo de
consulta se consegue da seguinte forma:
Um caso prático, se desejarmos localizar aqueles empregados com nome igual e visualizar seu
código correspondente, a consulta seria a seguinte:
SELECT DISTINCT
Empregados.Nome, Empregados.IdEmpregado
FROM
Empregados
WHERE
Empregados.Nome
In (
SELECT Nome FROM Empregados As Tmp GROUP BY Nome HAVING Count(*) > 1)
ORDER BY
Empregados.Nome
Informe de Claudio
Mail: claudio@lobocom.es
URL: http://personal.lobocom.es/claudio/
Depois de ler este artigo soube da existência da função DatePart(), porém a forma de colocá-la
em prática tal como o problema me enfocava, não é nada simples, ou nesse momento, não o vi
claro. De fato, fazendo uma busca, tudo era bastante confuso implementando programinhas em
VBA (Visual Basic Aplications). (Importante: O formato de data em Access é o formato
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 87 of 90
americano: mm/dd/aaaa, porém neste caso o formato americano e o da tabela quanto ao ano
que se referem coincidem.)
Obtemos:
Até tudo bem, o problema surge quando você quer obter só um tipo de data na qual o ano
coincida com um dado. Por exemplo, quero obter todas as empresas inscritas no ano 2003 e
você dispõe de 1000 empresas com 1000 datas de inscrição... Para isso, há que fazer o
seguinte:
SELECT *
FROM Tabela1
WHERE DatePart("yyyy",FECHA_ALTA)="2003";
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 88 of 90
com um loop.
Para isso criaremos uma tabela temporária onde colocaremos os elementos que queremos
iterar no loop para poder tratá-los.
DECLARE
@Anuncios
TABLE
(
pk_id numeric(18, 0) NOT NULL IDENTITY (1, 1),
Idtruco numeric(18,0),
IdUsuario numeric(18,0),
Alias nvarchar(255),
usuario nvarchar(255)
)
SET @Rows=0
SET @i=1
INSERT INTO
@Anuncios
(
Idtruque,
IdUsuario,
Alias,
Usuario
)
SELECT
a.ARTID,
a.ARTUSR,
p.Alias,
p.LonUsr
FROM
TABELA_ANUNCIOS a
INNER JOIN
TABELA_USUARIOS p
ON a.ARTUSR=p.LONID
Iteramos com o while. Desta maneira podemos emular o funcionamento de um cursor sem ser um cursor, podendo
executá-lo as vezes que quisermos de uma só vez.
SELECT
@Idtruque=Idtruque,
@IdUsuario=IdUsuario,
@Alias=Alias,
@Usuario=Usuario
FROM
@Anuncios
WHERE
pk_id=@i
SET @i=@i + 1
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 89 of 90
END
Dependendo das tarefas, estas sentenças se podem classificar em três grupos principais (DML,
DDL,DCL), embora nos restaria outro grupo que ao meu entender não está dentro da
linguagem SQL, e sim da PLSQL.
INSTRUÇÃO DESCRIÇÃO
Componentes sintáticos
Todas começam por um verbo (select, insert, update, create), a seguir continua com uma ou
mais cláusulas que nos dizem dados com os que vamos operar (from, where), algumas destas
são opcionais e outras obrigatórias como é o caso do from.
http://www.criarweb.com/manuais/32/print.php 11/07/2008
Tutorial de SQL - Manual completo Page 90 of 90
Voltar
http://www.criarweb.com/manuais/32/print.php 11/07/2008