You are on page 1of 100

CURSO DE SQL - APOSTILA

ndice
1. Introduo a SQL 1.1. O que SQL 1.2. O que um Banco de Dados Relacional 1.3. Regras de um Banco de Dados Relacional 2. Introduo a QUERY O comando SELECT 3. Expresses, condies e operadores 3.1. Expresses 3.2. Condies 3.3. Operadores 3.3.1.Operadores aritmticos 3.3.2.Operadores de comparao 3.3.3.Operadores de caractere 3.3.4.Operadores lgicos 3.3.5.Operadores SET 3.3.6.Outros operadores 4. Funes - Modelando os dados capturados 4.1. Funes de agregao 4.2. Funes de data/hora 4.3. Funes aritmticas 4.4. Funes de caractere 4.5. Funes de Converso 4.6. Outras funes 5. Clausulas do SQL 5.1. A clausula WHERE 5.2. A clausula STARTING WITH 5.3. A clausula ORDER BY 5.4. A clausula GROUP BY 5.5. A clausula HAVING 6. Unindo Tabelas JOIN 6.1. INNER JOIN 6.2. OUTER JOIN 7. SUBQUERIES Aprofundando o comando SELECT 8. Manipulando dados 8.1. O comando INSERT 8.2. O comando UPDATE 8.3. O comando DELETE 9. Criando e mantendo Tabelas 9.1. Criando um Banco de Dados 9.2. Criando Tabelas 9.3. Alterando a estrutura de uma Tabela 9.4. Excluindo Tabelas e Banco de Dados 10. VIEW 2

Pag
04 04 04 05 07 11 11 11 11 11 17 22 25 26 30 33 33 36 39 42 48 48 50 50 51 51 53 54 56 57 60 62 68 68 70 73 74 74 74 77 77 78

10.1. WITH CHECK OPTION 10.2. WITH ENCRYPTION 10.3. VIEW de VIEW 11. STORED PROCEDURE 11.1. Regras para criar STORED PROCEDURE 12. Transao 12.1. Comandos de Transao 12.2. @@ERROR 13. Tpicos avanados de SQL CURSOR 13.1. Criando um CURSOR 13.2. Abrindo um CURSOR 13.3. Acessando um CURSOR 13.4. Fechando um CURSOR 14. Erros comuns em SQL e suas solues 15. Exerccios propostos

79 79 80 81 81 84 84 85 87 87 88 88 89 93 95

1 Introduo a SQL. 1.1 O que SQL A histria do SQL se inicia no fim da dcada de 70, nos laboratrios da IBM em San Jose, Califrnia. Inicialmente. No incio, a linguagem era chamada de SEQUEL (Structured English QUery Language) pois o objetivo era fornecer comandos mais intuitivos, prximos lngua inglesa, depois, este prottipo sofreu vrias revises, at que em 1977 a linguagem passa a se chamar SQL (Structured Query Language). O SQL uma linguagem no-procedural, o que significa que os procedimentos desta so menos detalhados que os de uma linguagem procedural. Uma linguagem procedural implica em algoritmos mais complexos para realizar uma tarefa, como ocorre, por exemplo, no Cobol, onde devemos especificar o passo a passo de um procedimento. As linguagens procedurais, como C, Pascal e Cobol so as linguagens de terceira gerao. Linguagens para processamento de Banco de Dados so chamadas de linguagens de quarta gerao. O SQL foi desenvolvido como uma ferramenta pertencente ao Banco de Dados Relacional DB2, criado pelo Dr. E. F. Cood, para a IBM, e foi a ferramenta que tornou realmente possvel a tecnologia de Banco de Dados Relacionais. Devido ao grande sucesso do modelo relacional, surgem vrias verses sobre a linguagem SQL. Devido a isto, em 1982 o ANSI props uma padronizao, que foi aceita em 1986. Em 1987 o ISO aceita esta padronizao e a linguagem passa a ser conhecida como SQL/86. Aps duas novas padronizaes, a linguagem formalmente chamada de SQL2 ou SQL/92. Atualmente est em curso o desenvolvimento do SQL/3, visando transformar o SQL em uma linguagem de programao completa e orientada a objetos. 1.2 O que um Banco de Dados Relacional. Em um banco de dados relacional as bases de dados so vistas como um conjunto de tabelas onde cada uma representa uma relao, onde a integridade de entidade com as chaves primrias mantida, juntamente com a integridade referencial com as chaves estrangeiras. Isto significa que se tivermos duas tabelas e em uma delas nos referenciarmos chave primria da outra, o relacionamento entre as duas garantir a integridade dos dados de ambas.

1.3 Regras de um Banco de Dados Relacional. O Dr. E. F. Cood definiu as seguintes regras para o Banco de Dados Relacional: Um Banco de Dados Relacional deve estar habilitado para gerenciar bases de dados inteiramente atravs de suas capacidades relacionais; Toda informao dentro de um Banco de Dados Relacional, incluindo as tabelas e os seus campos so representados explicitamente como valores dentro de tabelas; Qualquer valor em uma tabela pode ser acessado atravs da combinao entre: nome da tabela, valor da chave primria e nome da coluna ou campo; Um Banco de Dados Relacional deve ter capacidade de tratar valores nulos NULL desconhecidos ou inaplicveis; O BD deve possuir um catlogo relacional ativo e on-line, para tratar as descries de campos no nvel lgico, possibilitando a sua consulta atravs das linguagens para tratamento de banco de dados; O Banco de Dados Relacional deve suportar ao menos uma linguagem bem definida, que: permita a definio e manipulao de dados, possua regras de integridade e possibilite trabalhar com nveis de autorizao e transaes; Todas as VIEWS - vises lgicas que permitem a representao de dados de uma ou mais tabelas como se fosse outra tabela - devem ser atualizveis pelo sistema; Um Banco de Dados relacional deve possibilitar no s a recuperao dos dados, mas tambm a insero, excluso e alterao dos mesmos; A alterao de um mtodo de acesso ou da estrutura de armazenamento fsico dos dados no deve afetar logicamente as aplicaes que utilizam o Banco de Dados Relacional; Alteraes na estrutura de uma tabela no devem afetar logicamente - na medida do possvel - os aplicativos que utilizam o BD; As linguagens suportadas pelo Banco de Dados Relacional devem ser capazes de definir e garantir regras de integridade para suas entidades. Estas regras devem estar disponveis atravs do catlogo relacional on-line e no deve existir a possibilidade de serem dribladas; As aplicaes no devem ser afetadas na redistribuio dos dados; As regras de integridade definidas pela linguagem da base de dados no podem ser dribladas ou alteradas utilizando linguagens de baixo nvel. 5

A maioria dos Bancos de Dados possui a estrutura de relacionamentos paifilho, onde a entidade-pai possui ponteiros apontando para as entidadesfilho. Este mtodo possui muitas vantagens e algumas desvantagens. A seu favor temos o fato de que a estrutura fsica do banco de dados no mais importante, pois o programador passa a armazenar somente a localizao lgica, permitindo que os dados possam ser acessados independente da estrutura de armazenamento fsica. Assim, qualquer acesso aos dados pode ser facilmente executado. Por outro lado, pode no ser fcil juntar grupos de dados distintos para formar novas estruturas. O formato dos dados no disco no pode ser arbitrariamente mudado aps a criao do Banco de Dados. Devido ao fato de que a informao poder ser naturalmente agrupada, Dr E. F. Cood organizou seu sistema de dados em torno deste conceito (teoria dos conjuntos). Dentro do modelo relacional, o Banco de Dados separado em estruturas, chamadas de Tabelas. As Tabelas, por sua vez, so compostas por elementos de dados individuais, chamados de campos ou colunas. Um conjunto nico de campos chamado de registro ou linha. A estrutura das tabelas, depois da escolha da plataforma, a mais importante deciso no desenvolvimento de uma aplicao com Banco de Dados. A estrutura das tabelas afeta tanto o desenvolvimento quanto a performance da aplicao. O processo de estruturao das tabelas chamado de normalizao.

2 Introduo a QUERY O comando SELECT. O comando SELECT de longe a instruo mais comum do SQL. Uma instruo SELECT retorna um conjunto de registros que atendam condio especificada no SELECT. Ao executar este comando, o programa principal do Banco de Dados procura a tabela ou tabelas especificadas, extrai as colunas escolhidas, seleciona as linhas que satisfazem o critrio e classifica as linhas resultantes na ordem especificada. O SELECT no altera o contedo de um Banco de Dados. A sintaxe mnima de uma instruo SELECT : SELECT * FROM Tabela; Onde * especifica que todos os campos da Tabela sero retornados, obedecendo a ordem dos mesmos na estrutura da tabela. Para selecionar alguma coluna ou colunas especificamente, a sintaxe : SELECT campo1, campo2, campo3 FROM Tabela; Neste caso os campos selecionados retornaro na ordem especificada. Comandos SQL no so case-sensitive. Podemos ainda atribuir um nome coluna diferente daquele que consta no banco de dados, usando a clausula AS: Tabela Campo1 XXX CCC XXX DDD campo2 AAA AAA BBB BBB campo3 BBB BBB AAA AAA

SELECT campo1, campo2, campo3 AS teste FROM Tabela; Sada: campo1 ---------XXX CCC XXX DDD 4 rows selected Neste exemplo, as colunas mostradas sero: campo1, campo2 e teste, onde teste corresponde a campo3. A tabela tambm pode ser referenciada atravs de um ALIAS, bastando para isto colocar o ALIAS desejado aps o nome da tabela na clausula FROM: SELECT campo1, campo2, campo3 FROM Tabela T; Assim, a tabela passa a ser referenciada por T. Quando selecionamos campos de mais de uma tabela, freqentemente teremos colunas com o mesmo nome. Nestes casos torna-se necessrio explicitar a relao da coluna com a Tabela. Fazemos isto colocando o nome da tabela seguido de ponto mais o nome da coluna: SELECT Tabela1.campo1, Tabela1.campo2, Tabela2.campo1 FROM Tabela1, Tabela2; Ou: SELECT T1.campo1, T1.campo2, T2.campo1 FROM Tabela1 T1, Tabela2 T2; A instruo SELECT...FROM retorna a lista completa de campos pedidos, ou seja, os campos pertencentes a todas as linhas da tabela selecionada. Caso desejemos selecionar apenas alguns registros utilizamos a clausula WHERE, mais uma condio. Neste caso, o SELECT retornar somente os registros que satisfaam esta condio: campo2 ---------AAA AAA BBB BBB teste ---------BBB BBB AAA AAA

SELECT * FROM Tabela WHERE campo1=XXX; Sada: campo1 ---------XXX XXX 2 rows selected Neste caso so mostrados todos os campos (*) dos registros onde o campo1 tenha o valor de XXX. Ao efetuar uma instruo: SELECT campo1 FROM Tabela; O retorno ser: campo1 ---------XXX CCC XXX DDD 4 rows selected Observamos que ocorrem repeties no valor de campo1. Caso desejemos selecionar somente as ocorrncias sem repetir os valores, usamos a clausula DISTINCT: SELECT DISTINCT campo1 FROM Tabela; Sada: campo1 ---------XXX CCC DDD 3 rows selected campo2 ---------AAA BBB campo3 ---------BBB AAA

Assim sero listados todos os valores de campo1, sem repeties. Esta clausula s pode ser aplicada a uma coluna.

10

3 Expresses, condies e operadores. Como vimos acima, para selecionar determinadas linhas de uma tabela utilizamos a clausula WHERE, seguida de uma expresso ou condio. Neste segmento veremos a diferena entre uma expresso e uma condio, assim como a utilizao de operadores e outras clausulas do WHERE. 3.1 Expresses. Uma expresso retorna um valor booleano: True ou False. No uso de uma expresso, o SELECT retornar as linhas nas quais a expresso retorne True. Em: SELECT * FROM Tabela WHERE campo1=XXX; A expresso campo1=XXX retornar True quando o contedo de campo1 for igual a XXX, neste caso ento a linha ser mostrada aps o SELECT. 3.2 Condies. Uma condio envolve ao menos 4 elementos: a clausula WHERE, uma varivel, um operador e uma constante. No exemplo acima, a condio seria: WHERE campo1=XXX Onde campo1 a varivel, o sinal = o operador e XXX a constante. 3.3 Operadores. Operadores so elementos que fazem parte das expresses e especificam a condio para o SELECT. Os operadores podem ser aritmticos, de comparao, de caractere, lgicos, do tipo SET e variados. 3.3.1 Operadores aritmticos. Os operadores aritmticos so: +, -, *, / e % Onde % representa o resto inteiro de uma diviso. Da mesma forma que em qualquer operao aritmtica, a precedncia dos operadores pode ser manipulada atravs de parnteses. 11

Operador +: Podemos usar o operador + para somar duas colunas da tabela ou para somar uma constante a uma coluna da tabela: tab_frutas nome Mamo Laranja Ma Banana valor_varejo 1.0 .50 1.2 2.0 valor_atacado 1.5 .75 1.8 2.5

Exemplo 1: Somando duas colunas de uma tabela. SELECT F.nome, F.valor_varejo + F.valor_atacado AS soma_coluna FROM tab_frutas F; Sada: nome -----------Mamo Laranja Ma Banana 4 rows selected soma_coluna -------------------------------2.5 1.25 3.0 4.5

12

Exemplo 2: Somando uma constante a uma coluna de uma tabela. SELECT F.nome, F.valor_varejo + 1.0 FROM tab_frutas F; Sada: nome -----------Mamo Laranja Ma Banana 4 rows selected Operador : Assim como o operador +, podemos diminuir uma coluna da outra, ou diminuir uma constante de uma coluna. Alm disso, o operador pode ser usado para mudar o sinal de uma coluna: Exemplo 1: Diminuindo duas colunas de uma tabela. SELECT F.nome, F.valor_varejo F.valor_atacado AS diferena FROM tab_frutas F; Sada: nome -------------Mamo Laranja Ma Banana 4 rows selected diferenca ----------0.5 0.25 0.4 0.5 valor_varejo+1.0 -------------------2.0 1.5 2.2 3.0

13

Exemplo 2: Diminuindo uma constante de uma coluna de uma tabela. SELECT F.nome, F.valor_varejo 0.15 AS valor_desconto FROM tab_frutas F; Sada: nome ---------------Mamo Laranja Ma Banana 4 rows selected Exemplo 3: Mudando o sinal de uma coluna de uma tabela. SELECT F.nome, F.valor_varejo AS sinal_trocado FROM tab_frutas; Sada: nome ------------Mamo Laranja Ma Banana 4 rows selected Operador *: O operador * processa uma multiplicao entre duas colunas ou entre uma coluna e uma constante: Exemplo 1: Multiplicando duas colunas de uma tabela. sinal_trocado ---------------1.0 -0.5 -1.2 -2.0 valor_desconto ----------------0.85 0.35 1.05 1.85

14

SELECT F.nome, F.valor_varejo * F.valor_atacado AS produto FROM tab_frutas F; Sada: nome -----------Mamo Laranja Ma Banana 4 rows selected Exemplo 2: Multiplicando uma constante por uma coluna de uma tabela. SELECT F.nome, F.valor_varejo * 2 AS dobro FROM tab_frutas F; Sada: nome --------------Mamo Laranja Ma Banana 4 rows selected Operador /: O operador / faz uma diviso entre duas colunas ou entre uma coluna e uma constante: dobro -----2.0 1.0 2.4 4.0 produto ---------1.5 0.375 2.16 5.0

15

Exemplo 1: Dividindo duas colunas de uma tabela. SELECT F.nome, F.valor_varejo / F.valor_atacado AS diviso FROM tab_frutas F; Sada: nome -------------Mamo Laranja Ma Banana 4 rows selected Exemplo 2: Dividindo uma coluna de uma tabela por uma constante. SELECT F.nome, F.valor_varejo /2 AS metade FROM tab_frutas F; Sada: nome -------------Mamo Laranja Ma Banana 4 rows selected Operador %: O operador % retorna o resto inteiro de uma diviso: metade ---------0.5 0.25 0.6 1.0 diviso --------0.66666 0.66666 0.66666 0.8

16

SELECT F.nome, F.valor_varejo % 3 AS resto FROM tab_frutas F; Sada: nome ------------Mamo Laranja Ma Banana 4 rows selected Na verdade a operao de diviso retorna um resto fracionado entre 0 e 0,9 que ento arredondado para o nmero inteiro abaixo. 3.3.2 Operadores de comparao. Operadores de comparao, assim como expresses, retornam os valores TRUE e FALSE. Alm destes, um operador de comparao pode retornar um valor desconhecido. Um retorno de valor desconhecido est associado ao conceito de nulidade, o NULL. Dizer que o valor de um campo igual a NULL significa que no existe nenhum valor armazenado no elemento. Quando dizemos nenhum valor, importante diferenciar isto de zeros ou espaos. Quando temos um elemento numrico cujo valor zero, ou um alfanumrico contendo espao vazio, os elementos contm um valor, j quando o contedo especificado como NULL, nenhum valor est associado ao elemento. Ao executar uma busca em uma tabela que tenha campos com valor NULL, estes retornaro como colunas vazias. Por isso fcil perceber quando um campo numrico tem o valor igual a NULL, mas se o campo for alfanumrico, o valor NULL pode ser confundido com espaos. tab_itens Nome Vassoura P Lixeira Null Escovo valor_venda 10.0 5.0 Null 6.0 4.5 resto -----0.0 0.0 0.0 0.0

17

Ao aplicar o comando: SELECT * FROM tab_itens; Teremos a seguinte sada: nome ---------------Vassoura P Lixeira Escovo 4 rows selected Observando a sada do SELECT percebemos facilmente que a terceira linha possui um valor NULL, pois o campo valor_venda numrico e aparece em branco, j na quarta linha, no to claro que o campo nome possui um valor nulo, pois como o campo do tipo texto, o NULL pode facilmente ser interpretado como espao. No momento de processar uma comparao, se o campo contiver um valor NULL o retorno da comparao ser desconhecido (nem verdadeiro nem falso). Levando isto em conta, se quisermos selecionar da tabela os itens que tenham o campo valor_venda igual a NULL, usamos a seguinte sintaxe: SELECT * FROM tab_itens WHERE valor_venda IS NULL; Sada: nome ---------------Lixeira 1 row selected Se ao invs disto usarmos o seguinte comando: SELECT * FROM tab_itens WHERE valor_venda = NULL; Sada: nome ---------------valor_venda -------------valor_venda -------------valor_venda -------------10.0 5.0 6.0 4.5

18

Isto ocorre por que a comparao utilizando o operador = retorna um valor desconhecido, como somente listamos as linhas que retornam TRUE, nenhuma linha ser listada. Operador =: O operador = retorna as linhas cujo campo comparado possui exatamente o valor especificado aps o operador. Considerando a tabela tab_itens: SELECT * FROM tab_itens WHERE nome = Vassoura; Sada: nome -----------------Vassoura 1 row selected Se ao invs disto escrevermos: SELECT * FROM tab_itens WHERE nome = Vasoura; A sada ser: nome -----------------Operador > ou >=: Os operadores > e >= indicam que a seleo se dar nas linhas cujo campo comparado seja maior que, ou maior ou igual ao elemento comparado. Considerando a tabela: tab_carro: Nome Gol Fusca Mercedes Benz Clio Fiat Uno valor_venda 15000 3000 45000 25000 9000 valor_venda -------------valor_venda -------------10.0

Exemplo 1 - selecionando valores maiores que uma constante: 19

SELECT * FROM tab_carro WHERE valor_venda > 9000; Sada: nome --------------------Gol Mercedes Benz Clio 3 rows selected Exemplo 2 - selecionando valores maiores ou iguais a uma constante: SELECT * FROM tab_carro WHERE valor_venda >= 9000; Sada: nome ----------------------Gol Mercedes Benz Clio Fiat Uno 4 rows selected Operador < ou <=: Seleciona as linhas que contenham um valor menor que, ou menor ou igual ao valor indicado para o campo comparado. valor_venda -------------15000 45000 25000 9000 valor_venda -------------15000 45000 25000

20

Exemplo 1 - selecionando valores menores que uma constante: SELECT * FROM tab_carro WHERE nome < Gol; Sada: nome -------------------Fusca Clio Fiat Uno 3 rows selected Exemplo 2 - selecionando valores menores ou iguais a uma constante: SELECT * FROM tab_carro WHERE nome <= Gol; Sada: nome -------------------Gol Fusca Clio Fiat Uno 4 rows selected Operadores <>(Sql-Server) ou =!: Assim como podemos selecionar linhas cujo contedo campos seja igual, maior ou menor que um determinado valor, existem situaes em que necessrio selecionar as linhas cujo campo de comparao seja diferente do valor especificado. Fazemos isto utilizando os operadores <> ou =!: valor_venda -------------15000 3000 25000 9000 valor_venda -------------3000 25000 9000

21

SELECT * FROM tab_carro WHERE valor_venda <> 3000 Sada: nome ------------------------Gol Mercedes Benz Clio Fiat Uno 4 rows selected 3.3.3 Operadores de caractere. Operador LIKE: O operador LIKE indica que selecionaremos as linhas cujo campo comparado contenha algo semelhante ao valor indicado na condio. tab_aluno: Nome Fernando Alex Sheila Ana Maria Luiza Endereco Rua Amaral n 30 Av Oxford n 123 Rua June n 7 apto 802 Rua Bastos n 10 Av London n 2 apto 17 valor_venda -------------15000 45000 25000 9000

Se quisermos selecionar as linhas cujo campo endereo comece por Rua, o comando usado ser: SELECT * FROM tab_aluno WHERE endereco LIKE Rua%;(Sql Server) Ou: SELECT * FROM tab_aluno WHERE endereco LIKE Rua*;(Access)

22

Sada: nome ------------------------Fernando Carla Ana Maria 3 rows selected O sinal % ou o *, utilizado em Rua% - ou Rua* - indica que listaremos todas as linhas cujos campos de comparao comecem pela constante Rua. Podemos usar os sinais % ou * antes da constante, depois, ou em ambos os casos: SELECT * FROM tab_aluno WHERE endereco LIKE %apto%; Sada: nome -----------------------Carla Luiza 2 rows selected Existem casos em que desejamos selecionar linhas cujo campo de comparao contenha o valor comparado com variao em um ou outro caractere, nestes casos usamos o sinal _ ou ?, que indica que sero selecionadas as linhas cujos campos de comparao contiverem o valor comparado, podendo substituir o valor do caractere na posio onde encontrarmos o _. Considerando a tabela abaixo: tab_aluno Nome Fernando Alex Carla Ana Maria Luiza Estado RN MG XRJX GO SP endereco ----------------------------Rua June n 7 apto 802 Av London n 2 apto 17 endereco -----------------------------Rua Amaral n 30 Rua June n 7 apto 802 Rua Bastos n 10

23

SELECT * FROM tab_aluno WHERE estado LIKE R?;(Access) Sada: nome ----------------Fernando 1 row selected Podemos ainda utilizar ambos os sinais: SELECT * FROM tab_aluno WHERE estado LIKE _R%;(Sql Server) Sada: nome --------------------Carla 1 row selected Operador || ou + ou &: Estes operadores indicam a concatenao de duas colunas em uma: SELECT nome + estado AS NomEst FROM tab_aluno; Sada: NomEst -------------------------------Fernando RN Alex MG Carla XRJX Ana Maria GO Luiza SP 5 rows selected Podemos inserir caracteres fixos entre as colunas: SELECT nome + - + estado NomEst FROM tab_aluno; estado -----XRJX estado -------RN

24

Sada: NomEst -------------------------------Fernando RN Alex MG Carla XRJX Ana Maria GO Luiza SP 5 rows selected 3.3.4 Operadores lgicos. Os operadores lgicos so usados para separar duas condies da clausula WHERE, formando condies compostas ou complexas. Os operadores lgicos so: AND, OR e NOT. tab_curso: Nome Cobol C+ VB Java Pascal Professor Rui Ricardo Rui Fabrcio Rui horario manh tarde tarde manh manh

SELECT * FROM tab_curso WHERE professor = Rui AND horario = manh; Sada: nome -----------------Cobol Pascal 2 rows selected Neste caso, as linhas mostradas so aquelas cujos campos de comparao atendem a ambas as condies. professor --------------------Rui Rui horario ------------manh manh

25

SELECT * FROM tab_curso WHERE professor = Rui OR horario = manh; Sada: nome -----------------Cobol Java Pascal 3 rows selected Ao trocarmos o AND pelo OR no SELECT, passamos a listar as linhas que atendam a uma ou outra condio, como na linha 2 da consulta, que atende somente a uma das condies. SELECT * FROM tab_curso WHERE professor NOT = Rui; Sada: nome -----------------C+ Java 2 rows selected Aqui o operador NOT funciona transformando o resultado da condio em FALSE, se a condio for satisfeita e em TRUE se a condio no for satisfeita. 3.3.5 Operadores SET. Operador UNION: Este operador retorna o resultado de duas consultas excluindo as linhas duplicadas. professor --------------------Ricardo Fabrcio horario ------------tarde manh professor --------------------Rui Fabrcio Rui horario ------------manh manh manh

26

tab_futebol Clube Cruzeiro Grmio Flamengo Fluminense Vasco tab_volei Clube Flamengo Minas Gs Parmalat Vasco SELECT * FROM tab_futebol UNION SELECT * FROM tab_volei; Sada: clube -----------------Cruzeiro Grmio Flamengo Fluminense Minas Gs Parmalat Vasco 7 rows selected As duas consultas, se executadas separadamente, retornariam um total de 9 linhas, porm existem duas linhas com o mesmo contedo em ambas as consultas. Estas linhas aparecero apenas uma vez na consulta utilizando UNION. Se desejarmos incluir tambm as linhas duplicadas, usamos o UNION ALL:

27

SELECT * FROM tab_futebol UNION ALL SELECT * FROM tab_volei; Sada: clube -----------------Cruzeiro Grmio Flamengo Fluminense Vasco Flamengo Minas Gs Parmalat Vasco 9 rows selected Operador INTERSECT: (Oracle) Este operador retorna a interseo entre as duas consultas: SELECT * FROM tab_futebol INTERSECT SELECT * FROM tab_volei; Sada: clube -----------------Flamengo Vasco 2 rows selected Operador EXISTS (INTERSEO - Sql Server): Da mesma forma que o INTERSEC, retorna a interseo entre duas consultas. Este exemplo retorna a interseo entre os pases das tabelas Customers e Employees:

28

SELECT DISTINCT Country FROM Customers WHERE EXISTS (SELECT Country FROM Employees WHERE Customers.Country = Employees.Country) Sada: Country ----------------------UK USA Operador MINUS: (Oracle) Retorna as linhas da primeira consulta que no esto presentes na segunda: SELECT * FROM tab_futebol MINUS SELECT * FROM tab_volei; Sada: clube -----------------Cruzeiro Grmio Fluminense 3 rows selected SELECT * FROM tab_volei MINUS SELECT * FROM tab_futebol; Sada: clube -----------------Minas Gs Parmalat 2 rows selected Operador NOT EXISTS (Diferena - Sql Server) Igual ao MINUS, retorna as linhas da que no esto presentes na segunda consulta.

29

O exemplo a seguir retorna os pases no comuns nas tabelas Customers e Employees: SELECT DISTINCT Country FROM Customers WHERE NOT EXISTS (SELECT Country FROM Employees WHERE Customers.Country = Employees.Country) Sada --------------Argentina Austria Belgium Brazil Canada Denmark Finland France Germany Ireland Italy Mexico Norway Poland Portugal Spain Sweden Switzerland Venezuela 3.3.6 Outros operadores: Operador IN: Este operador retorna as linhas que estiverem contidas em uma lista de argumentos.

30

tab_cidades Cidade Rio de Janeiro Cabo Frio Santos Salvador Ribeiro Preto Estado RJ RJ SP BA SP

Se quisermos listar as linhas cujo campo estado sejam iguais a RJ ou SP: SELECT * FROM tab_cidades WHERE estado = RJ OR estado = SP; Ou, usando o operador IN: SELECT * FROM tab_cidades WHERE estado IN (RJ, SP); Sada: cidade ---------------------Rio de Janeiro Cabo Frio Santos Ribeiro Preto 4 rows selected Operador BETWEEN: tab_livros nome Senhor dos Anis Cem anos de solido Ensaio sobre a cegueira O iluminado A casa dos espritos valor 120.0 40.0 35.0 60.0 30.0 estado -------RJ RJ SP SP

Selecionando as linhas cujo campo valor seja maior a 35 e menor que 100:

31

SELECT * FROM tab_livros WHERE valor > 35 AND valor < 100; Ou, usando o operador BETWEEN: SELECT * FROM tab_livros WHERE valor BETWEEN 35 AND 100; Sada: nome -----------------------Cem anos de Solido Ensaio sobre a cegue O iluminado 3 rows selected O operador BETWEEN lista as linhas contidas entre o intervalo definido pelos parmetros, incluindo os valores iguais aos parmetros. Ambos os comandos produzem o mesmo resultado que quando usamos condies compostas, porm o modo de escrever os comandos fica mais enxuto e claro. valor ----------40.0 35.0 60.0

32

4 Funes - Modelando os dados capturados. As funes do SQL auxiliam na manipulao da informao que retorna de uma instruo SELECT. 4.1 Funes de agregao. Estas funes retornam valores baseados em valores das colunas. Elas so conhecidas tambm como funes de grupo ou de agrupamento. Funo COUNT: Esta funo retorna o nmero de linhas que satisfazem a condio especificada na clausula WHERE. tab_livros Nome Sonhos de Rob O primo Baslio Fundao gua Viva Preo 42.0 40.0 35.0 30.0 autor Isaac Assimov Ea de Queiroz Isaac Assimov Clarice Lispector

SELECT COUNT (*) AS qtd_livros_autor FROM tab_livros WHERE tab_livros.autor = Isaac Assimov; Sada: qtd_livros_autor ---------------------2 Como o COUNT conta as linhas que satisfazem a condio, usamos o *. Poderamos utilizar tambm o nome de um dos campos, que o resultado seria o mesmo. Se desejarmos saber quantas linhas tem a tabela, podemos usar o seguinte formato: SELECT COUNT (*) AS total_linhas FROM tab_livros; Sada: total_linhas ---------------------4 33

Funo SUM: Esta funo retorna o somatrio dos campos de uma coluna: SELECT SUM(L.preo) AS total_preo FROM tab_livros L; Sada: total_preo --------------------147.0 Como neste caso o somatrio associado a uma coluna especfica, o nome do campo deve estar explicitado. Se desejarmos realizar o somatrio de mais de um campo, devemos especificar uma funo SUM para cada campo separadamente. Esta funo somente vlida para campos numricos. Funo AVG: Esta funo retorna a mdia aritmtica de uma coluna: SELECT AVG(L.preo) AS media_total_preo FROM tab_livros L; Sada: media_total_preo --------------------36.75 Assim como a funo SUM, esta funo somente vlida para campos numricos. Funo MAX: Retorna o valor mximo presente em uma coluna, tenha esta o contedo numrico ou alfanumrico:

34

SELECT MAX(L.preo) AS maior_preo FROM tab_livros L; Sada: maior_preo -------------------42.0 Funo MIN: Ao contrrio da funo MAX, retorna o menor valor presente em uma coluna: SELECT MIN(L.preo) AS menor_preo FROM tab_livros L; Sada: menor_preo -------------------30.0 Podemos ainda combinar as duas funes: SELECT MIN(L.preo) AS menor_preo , MAX(L.preo) AS maior_preo FROM tab_livros L; Sada: menor_preo -------------------30.0 Funo VARIANCE:(Oracle) Retorna a variao do desvio-padro, muito utilizado para clculos de estatstica. SELECT VARIANCE(tab_livros.preo) AS variao FROM tab_livros; Sada: variao -------------------10.333 maior_preo -------------------42.0

35

Esta funo somente pode ser usada em colunas numricas. Funo STDDEV: Esta funo retorna o desvio-padro do contedo de uma coluna. SELECT STDDEV(tab_livros.preo) AS desvio_padro FROM tab_livros; Sada: desvio_padro --------------------2 Assim como a funo VARIANCE, somente pode ser utilizado em campos numricos. 4.2 Funes de data/hora. Nesta seo estudaremos funes que facilitam a manipulao de datas nas aplicaes. Funo ADD_MONTHS:(Oracle Esta funo adiciona a quantidade de meses especificados no parmetro coluna a ela associada. tab_projeto Nome Agenda Cadastro Aluno Microsoft Projeto Final Data_inicio 02-Ago-04 03-Set-04 02-Ago-04 04-Nov-04 data_final 02-Set-04 03-Nov-04 03-Nov-04 03-Dez-04

36

SELECT P.nome, P.data_inicio, P.data_final AS data_prevista ADD_MONTHS(P.data_final, 2) AS nova_data_fina FROM tab_projeto P; Sada: nome ----------------Agenda Cadastro Aluno Microsoft Projeto Final 4 rows selected Os parmetros desta funo so o nome do campo e a quantidade de meses a serem acrescidos. Funo DATEADD(): (Sql Server) Acrescenta um valor, na prte da data especificada, e mostra a nova data resultante. DateAdd(unidade,valorAcrescimo,DataOrigem) Sintaxe : Select DateAdd(dd,01,DATA_PRECO) AS DATANOVA FROM TAB_FRUTAS WHERE NOME = 'MAMAO' Sada : retorna a data acrescida de 01 dia. DATANOVA ------------2004-11-02 Funo LAST_DAY: (Oracle) A funo LAST_DAY retorna o ltimo dia do ms: data_inicio -----------02-Ago-04 03-Set-04 02-Ago-04 04-Nov-04 data_prevista ---------------02-Set-04 03-Nov-04 03-Nov-04 03-Dez-04 nova_data_final -----------------02-Nov-04 03-Jan-05 03-Jan-05 03-Fev-05

37

SELECT P.data_final, LAST_DAY(P.data_final) AS ultimo_dia_mes FROM tab_projeto P; data_final ---------------02-Set-04 03-Nov-04 03-Nov-04 03-Dez-04 4 rows selected Funo MONTHS_BETWEEN: (Oracle) Retorna a quantidade de meses entre duas datas. Retorna um nmero que pode ser fracionado: SELECT P.nome,MONTHS_BETWEEN(P.data_inicio P.data_final) AS durao_projeto FROM tab_projeto P; Sada: nome ---------------------Agenda Cadastro Aluno Shell Projeto_final 4 rows selected Funo NEXT_DAY: (Oracle) Esta funo retorna a data do prximo dia da semana a partir da data passada pelo parmetro: durao_projeto --------------------1.033333 2.033333 3.933333 0.967741 ultimo_dia_mes -----------------30-Set-04 30-Nov-04 30-Nov-04 31-Dez-04

38

SELECT P.data_inicio NEXT_DAY(P.data_inicio, monday) AS prox_segunda_feira FROM tab_projeto P; Sada: data_inicio ------------02-Ago-04 03-Set-04 02-Ago-04 04-Nov-04 4 rows selected Funo SYSDATE: (Oracle) Retorna a data e hora do sistema: SELECT DISTINCT SYSDATE FROM tab_projeto; Sada: SYSDATE ---------------------29-Jul-04 1030AM Usamos a clausula DISTINCT para que apenas uma linha seja mostrada, pois teramos a mesma resposta para cada linha da tabela. 4.3 Funes aritmticas. Muitas das operaes a serem realizadas com dados de uma tabela envolvem operaes aritmticas, por isso, muitas das implementaes de SQL possuem funes para isto. Funo ABS: Esta funo retorna o valor absoluto de uma coluna (o valor absoluto o nmero sem considerar a sinalizao): prox_segunda_feira ----------------------09-Ago-04 06-Set-05 09-Ago-05 05-Nov-05

39

tab_saldo saldo_anterior Movimento saldo_atual 500.90 -600.00 -99.10 -100.30 1000.00 899.70 300.00 -450.00 -150.00 251.20 100.00 351.20 SELECT ABS(tab_saldo.movimento) AS movimento_absoluto FROM tab_saldo; movimento_absoluto -----------------------600.00 1000.00 450.00 100.00 4 rows selected Funes CEIL(CEILING -> Sql Server) e FLOOR: A funo CEIL retorna o menor nmero inteiro maior que ou igual ao parmetro: SELECT S.saldo_atual, CEIL(S.saldo_atual) AS aprox_cima FROM tab_saldo S; Sada: saldo_atual ----------------99.10 899.70 -150.00 351.20 4 rows selected A funo FLOOR retorna o maior nmero inteiro menor que ou igual ao parmetro: aprox_cima ------------------98.00 900.00 -150.00 352.00

40

SELECT S.saldo_atual, FLOOR(S.saldo_atual) AS aprox_baixo FROM tab_saldo S; Sada: saldo_atual ----------------99.10 899.70 -150.00 351.21 4 rows selected Funes COS, COSH, SIN, SINH, TAN e TANH: (Oracle) COS(),ACOS(),SIN(), ASIN(),TAN(),ATAN(): (Sql Server) As funes COS, SIN e TAN retornam respectivamente Co-seno, seno e tangente de um ngulo em radianos. As funes COSH, SINH e TANH retornam os mesmos valores em graus. O formato geral : SELECT campo1, FUNO(campo1) FROM tabela; Funo EXP: Eleva o campo do parmetro a um valor correspondente a uma constante matemtica: SELECT campo1, EXP(campo1) FROM tabela; Funo LN e LOG:(Oracle) LOG(),LOG10(): (Sql Server) Ambas as funes retornam o logaritmo do parmetro: SELECT campo1, LOG(campo1) FROM tabela; SELECT campo1, LN(campo1) FROM tabela; Funo MOD: (Oracle) Retorna o resto da diviso do primeiro pelo segundo parmetro: aprox_baixo ------------------100.00 898.00 -150.00 351.00

41

SELECT campo1, campo2, MOD(campo1, campo2) FROM tabela; Funo POWER: Retorna o valor correspondente ao primeiro parmetro elevado pelo segundo: SELECT campo1, campo2, POWER(campo1, campo2) FROM tabela; Funo SIGNS:(Oracle) SIGN() : (Sql Server) Retorna 1 quando o parmetro um nmero negativo: SELECT campo1, SIGNS(campo1) FROM tabela; Funo SQRT: Retorna a raiz quadrada do parmetro: SELECT campo1, SQRT(campo1) FROM tabela; 4.4 Funes de caractere. Estas funes so utilizadas para manipulao de caracteres ou cadeias de caracteres. Funo CHR (Oracle), CHAR (Sql Server): Retorna o caractere equivalente a um nmero usado como parmetro na tabela ASCII: tab_caracteres Nome Isabel Garcia Isaac Carlos Sobrenome ALLENDE MARQUES ASIMOV CASTAEDA codigo 73 77 65 67

42

SELECT C.codigo ,CHR(C.codigo) AS caractere FROM tab_caracteres C; Ou: SELECT C.codigo ,CHAR(C.codigo) AS caractere FROM tab_caracteres C; Sada codigo -------73 77 65 67 4 rows selected Funo CONCAT (Oracle) + (Sql Server): Concatena duas ou mais colunas em uma s: SELECT CONCAT(C.nome, C.sobrenome) AS nome_sobrenome FROM tab_caracteres C; Sada: nome_sobrenome ------------------------------Isabel ALLENDE Garcia MARQUES Isaac ASIMOV Carlos CASTAEDA 4 rows selected Funo INITCAP: (Oracle) Transforma em maiscula a primeira letra da coluna selecionada e o restante em minscula: caractere ----------I M A C

43

SELECT C.sobrenome AS antes, INITCAP(C.sobrenome) AS depois FROM tab_caracteres C; Sada: antes --------------ALLENDE MARQUES ASIMOV CASTAEDA 4 rows selected Funo LOWER e UPPER. Afuno LOWER retorna o parmetro em minsculas e a funo UPPER, em maisculas: SELECT C.nome, LOWER(C.nome) AS minusculas, UPPER(C.nome) AS maiusculas FROM tab_caractere C; Sada: nome ----------------Isabel Garcia Isaac Carlos 4 rows selected Funes LPAD e RPAD: (Oracle) Estas funes possuem um mnimo de dois e um mximo de trs parmetros. O primeiro o nome do campo, o segundo o tamanho da mscara que definiremos e o terceiro o caractere de preenchimento a ser utilizado. Se nenhum caractere de preenchimento for especificado este ser feito por espaos. Por exemplo, suponhamos que o campo nome foi especificado como tendo um tamanho de 10 caracteres. A funo LPAD preenche os campos esquerda, o RPAD preenche direita: minusculas ----------------isabel garcia isaac carlos maiusculas ------------------ISABEL GARCIA ISAAC CARLOS depois --------------Allende Marques Asimov Castaeda

44

SELECT LPAD(C.nome, 15, *) AS esquerda, RPAD(C.nome, 15, *) AS direita FROM tab_caractere C; Sada: esquerda --------------------*****Isabel *****Garcia *****Isaac *****Carlos 4 rows selected Funes LTRIM e RTRIM: Estas funes retiram os espaos em branco esquerda (LTRIM) e direita (RTRIM). Podemos utilizar estas funes em conjunto com as funes LPAD e RPAD: SELECT RPAD(RTRIM(C.nome), 15, *) AS esquerda, LPAD(LTRIM(C.nome) , 15, *) AS direita FROM tab_caractere C; Sada: esquerda --------------------**********Isabel **********Garcia **********Isaac **********Carlos 4 rows selected Combinamos duas funes (LPAD e LTRIM, RPAD e RTRIM) para que o efeito da retirada dos espaos em branco fosse visvel. Funo REPLACE: Substitui o caractere especificado do contedo da coluna passada no parmetro pelo terceiro argumento do parmetro, quando este existir. Se no, faz a substituio por espaos: direita --------------------Isabel********* Garcia********* Isaac********** Carlos********* direita --------------------Isabel***** Garcia***** Isaac***** Carlos*****

45

SELECT REPLACE(C.nome, a, *) AS subst_a FROM tab_caractere C; Sada: subst_a ----------------Is*bel G*rci* Is**c C*rlos 4 rows selected Funo SUBSTR (Oracle) SUBSTRING (Sql Server): Esta funo retorna um pedao da string do campo selecionado. Recebe trs parmetros: o nome do campo, a posio inicial e a quantidade de caracteres a serem mostrados: SELECT SUBSTR(C.nome, 3,2) FROM tab_caractere C; nome -------------------ab rc aa rl 4 rows selected Funo TRANSLATE:(Oracle) Transforma os caracteres especificados em outros, ambos passados por parmetro juntamente com o nome do campo a ser transformado. Esta funo case-sensitive:

46

SELECT TRANSLATE(C.nome, abcdefghijklmnopqrstuvwxyz, @@@@@@@@&&&&&&&&**********) FROM tab_caractere C; Sada: nome --------------------I*@@@& G@*@&@ I*@@@ C@*&** 4 rows selected Funo INSTR (Oracle) CHARINDEX (Sql Server): Retorna a posio em que se encontra o caractere buscado na string do campo utilizado no parmetro: SELECT INSTR(C.nome, c) AS posio_C FROM tab_caractere C; SELECT CHARINDEX(c, C.nome) AS posio C FROM tab_caractere C Sada: posicao_C -----------0 4 5 1 4 rows selected Funo LENGHT (Oracle) LEN (Sql Server): Retorna o nmero de caracteres de uma string:

47

SELECT LENGHT(C.sobrenome) AS tam_sobrenome FROM tab_caractere C; Ou: SELECT LEN(C.sobrenome) AS tam_sobrenome FROM tab_caractere C; Sada: tam_sobrenome -----------------7 6 6 9 4 rows selected 4.5 Funes de converso. Estas funes convertem um tipo de dado em outro. So elas: Funo TO_CHAR (Oracle): converte um campo numrico em um campo do tipo CHAR. Funo TO_NUMBER (Oracle): converte um campo alfabtico em um campo numrico. A sintaxe : SELECT TO_CHAR(campo_num) FROM tabela; SELECT TO_NUMBER(campo_alfa) FROM tabela; Funes CAST() e CONVERT() (Sql Server): convertem uma expresso de um tipo de dado para outro. Sintaxe : SELECT CAST(Expresso as DataType) FROM tabela SELECT CONVERT(DataType, Expresso) FROM tabela 4.6 Outras funes. Funes GREATEST() e LEAST() (Oracle): 48

Estas funes retornam respectivamente o maior e o menor de uma lista de argumentos. SELECT GREATEST(campo1, campo2, campo3) FROM tabela; SELECT LEAST(campo1, campo2, campo3) FROM tabela; Funes : MAX() e MIN() (Sql Server): Estas funes retornam respectivamente o maior e o menor valor existente em uma determinada coluna. Sintaxe : SELECT MAX(Coluna) FROM Tabela SELECT MIN(Coluna) FROM Tabela Funo TOP n (Sql Server): Esta funo retorna um nmero n de linhas, a partir da linha inicial. n deve ser um nmero inteiro. Sintaxe : SELECT TOP n * FROM Tabela Funo TOP n PERCENT : A clusula PERCENT indica que deve ser retornado um valor percentual de quantidade de linhas da consulta base. SELECT TOP n PERCENT * FROM Tabela

49

5 Clausulas do SQL. tab_curso curso C+ Cobol Fortran C++ Delphi professor Joo Ana Joo Guilherme Lucia turno Manh Manh Tarde Noite Tarde

5.1 A clausula WHERE. A clusula WHERE utilizada para restringir as linhas que sero afetadas pelos comandos SELECT, UPDATE E DELETE. Ao usarmos o comando SELECT no seu formato mais bsico: SELECT * FROM tab_curso; Sada: curso ------------C+ Cobol Fortran C++ Delphi 5 rows selected Trazemos todas as linhas que compem a tabela. Caso desejemos selecionar as linhas que satisfaam uma condio, devemos utilizar a clausula WHERE: professor -------------Joo Ana Joo Guilherme Lucia turno --------------Manh Manh Tarde Noite Tarde

50

SELECT * FROM tab_curso C WHERE C.curso = C+; Sada: curso ------------C+ 1 row selected Neste caso somente sero includas no resultado da consulta as linhas em que o campo curso satisfaa a condio. 5.2 A clausula STARTING WITH. (Oracle) Esta clausula faz exatamente o que o operador LIKE seguido do operador % ou *: Seleciona as linhas cujo campo de comparao comea com o caractere ou cadeia de caracteres indicados: SELECT * FROM tab_curso WHERE tab_curso.curso STARTING WITH C+; Sada: curso ------------C+ C++ 2 rows selected O resultado da consulta retorna as linhas em que o campo curso contenha C+ no incio. 5.3 A clausula ORDER BY. A clausula ORDER BY ordena as linhas da consulta por um campo da tabela. Podemos usar qualquer campo ou uma combinao de campos. Podemos ordenar as linhas de forma ascendente ou descendente: SELECT * FROM Tabela ORDER BY campo1 ASC/DESC; A clausula ASC (ascendente) opcional, pois o default do comando. professor -------------Joo Guilherme turno --------------Manh Noite professor -------------Joo turno --------------Manh

51

SELECT * FROM tab_curso C ORDER BY C.curso; Sada: curso ------------C+ C++ Cobol Delphi Fortran 5 rows selected SELECT * FROM tab_curso C ORDER BY C.curso DESC; Sada: curso ------------Fortran Delphi Cobol C++ C+ 5 rows selected Ordenando a tabela por mais de um campo: SELECT * FROM tab_curso C ORDER BY C.professor ASC, C.turno DESC; curso ------------Cobol C++ Fortran C+ Delphi 5 rows selected O resultado da consulta ser ordenado por professor de modo ascendente e por turno de modo descendente 52 professor -------------Ana Guilherme Joo Joo Lucia turno --------------Manh Noite Tarde Manh Tarde professor -------------Joo Lucia Ana Guilherme Joo turno --------------Tarde Tarde Manh Noite Manh professor -------------Joo Guilherme Ana Lucia Joo turno --------------Manh Noite Manh Tarde Tarde

5.4 A clausula GROUP BY. J estudamos as funes de agregao, tais como SUM e COUNT, porm, usando o formato geral, somente podemos contar ou totalizar todas as linhas de uma consulta. s vezes precisamos agrupar estes resultados a partir de um determinado campo, ou combinao de campos. Uma soluo seria elaborar diversas instrues SELECT, cada uma delas com a clausula WHERE selecionando o grupo desejado, o que geraria vrios processamentos e vrias consultas. Felizmente, o SQL possui uma clausula que realiza este agrupamento sem necessidade de executarmos uma instruo SELECT para cada grupo, agregando todos os resultados em uma nica consulta. tab_livros Nome O Banquete A idade da razo A Nusea A genealogia da moral A repblica Autor Plato J.P.Sartre J.P.Sartre Nietzsche Plato editora Ouro Brasil Ouro Ouro Brasil qtd 100 300 350 30 200

Na tabela, desejamos saber quantos livros existem para cada autor, ou quantos volumes existem por editora. Se simplesmente utilizarmos as clausulas COUNT e SUM, teramos: SELECT COUNT(tab_livros.autor) AS QtdLivrosAutor FROM tab_livros; Sada: QtdLivrosAutor ------------------5 SELECT SUM(tab_livros.qtd) AS QtdLivrosEditora FROM tab_livros; Sada: QtdLivrosEditora ------------------980

53

A informao assim apresentada no nos diz o que realmente queremos saber. Se fossemos utilizar as funes de agregao combinadas com a clausula WHERE, teramos que realizar vrias instrues de SQL, alm de termos que conhecer antecipadamente o contedo da tabela, para assim poder selecionar os dados que desejamos. Podemos ao invs disto utilizar a clausula GROUP BY. Esta clausula agrupa os resultados obtidos em um SELECT a partir do campo ou lista de campos apresentada. Assim, se quisermos saber a quantidade de livros por autor na tabela, podemos simplesmente dizer: SELECT L.autor, COUNT(L.autor) AS QtdLivrosAutor FROM tab_livros L GROUP BY L.autor; Sada: Autor ------------------Plato J.P. Sartre Nietzsche QtdLivrosAutor --------------------2 2 1

Para selecionar o somatrio da quantidade de livros por editora: SELECT L.editora, SUM(L.qtd) AS QtdLivrosEditora FROM tab_livros L GROUP BY L.editora; Sada: editora ------------------Brasil Ouro QtdLivrosEditora -------------------500 480

Certamente, este formato muito mais claro e eficiente. Podemos agregar por qualquer campo, e todos os campos presentes no SELECT, com exceo dos campos agregados, devem estar presentes no GROUP BY. 5.5 A clausula HAVING. A clausula HAVING indica quais linhas sero mostradas em uma consulta que utilizou a clausula GROUP BY. Esta clausula se assemelha a clausula WHERE, com a diferena de que o WHERE se refere a colunas da tabela e

54

o HAVING se refere a colunas que trazem resultados de funes, ou seja, no pertencem estrutura da tabela: SELECT L.autor, COUNT(L.autor) AS QtdLivrosAutor FROM tab_livros L GROUP BY L.autor HAVING COUNT(L.autor) = 2; Sada: autor -------------Plato J.P.Sartre QtdLivrosAutor -----------------2 2

Finalmente, podemos combinar tantas quantas clausulas desejemos: SELECT L.autor, COUNT(L.autor) AS QtdLivrosAutor FROM tab_livros L WHERE L.autor STARTING WITH 'P' GROUP BY L.autor HAVING COUNT(L.autor) = 2; Sada: autor -------------Plato QtdLivrosAutor -----------------2

A seqncia para combinao de clausulas do SELECT : SELECT FROM WHERE GROUP BY HAVING ORDER BY campo(s) tabela(s) condio/expresso(es) para os campos campo(s) a serem agrupados condio(es) do grupo campo(s)

55

6. Unindo Tabelas JOIN. Um dos aspectos mais interessantes do SQL a capacidade de realizar pesquisas em mais de uma tabela. Sem esta caracterstica teramos que armazenar todos os dados necessrios para uma aplicao na mesma tabela, dificultando a manuteno. Graas a esta capacidade do SQL podemos trabalhar com tabelas comuns, menores e mais especficas. Existem duas formas bsicas de associar dados de tabelas, dependendo do resultado que se deseja obter: INNER JOIN: Esta clausula seleciona de duas ou mais tabelas apenas os dados relacionados entre todas elas; OUTER JOIN: Seleciona em duas ou mais tabelas tanto os dados relacionados quanto os no relacionados entre elas.

tab_livro Codigo 001 002 003 004 005 006 tab_editora Codigo 001 002 003 tab_vendas codigo_editora 001 001 002 001 003 002 codigo_livro 002 004 006 001 005 003 qtd_vendida 15 20 40 22 10 15 valor_unit 25.00 42.00 35.00 42.00 26.00 32.00 nome Ouro Brasil Europa Uf RJ SP RJ nome O Rei do Inverno 1984 Neuromancer Excalibur Admirvel Mundo Novo O caador de andrides Autor Bernard Cornwell George Orwell William Gibson Bernard Cornwell Aldous Huxley Philip K. Dick codigo_editora 001 001 002 001 003 002

56

6.1 INNER JOIN. Uma associao do tipo INNER JOIN tem por objetivo selecionar de duas ou mais tabelas apenas os dados relacionados entre todas elas. Um INNER JOIN pode ser: NATURAL JOIN: Neste tipo de associao relacionamos as duas tabelas atravs de uma coluna, que contm dados em comum, como por exemplo, nas tabelas acima apresentadas, a coluna codigo_editora, da tabela tab_livro corresponde coluna cdigo da tabela tab_editora, e ambas se relacionam com a tabela tab_vendas atravs das colunas codigo_editora e codigo_livro respectivamente. Um NATURAL JOIN se caracteriza por selecionar campos de duas ou mais tabelas que se relacionam atravs de um ou mais campos:

SELECT L.nome AS NomeLivro, E.nome AS NomeEditora, V.qtd_vendida AS QTD, V.valor_venda AS Valor, V.qtd_vendida*V.valor_venda AS Total FROM tab_livro L, tab_editora E, tab_vendas V WHERE L.codigo=V.codigo_livro And E.codigo=V.codigo_editora; Sada: NomeLivro -------------O Rei do Inv 1984 Excalibur Neuromance O caador de Admirvel Mu NomeEditora ---------------Ouro Ouro Ouro Brasil Brasil Europa QTD --------22 15 20 15 40 10 Valor ---------42 25 42 32 35 26 Total ----------924 375 840 480 1400 260

6 rows selected O exemplo acima um INNER JOIN atravs da clausula WHERE, com a qual realizamos a juno entre as tabelas. Podemos usar tambm a sintaxe como demonstrado a seguir, para isto, as tabelas devem ter chaves especificadas com seus relacionamentos:

57

SELECT E.nome, L.nome, V.qtd_vendida, V.valor_venda, V.qtd_vendida*V.valor_venda AS TOTAL FROM (tab_editora E INNER JOIN tab_livro L ON E.codigo=L.codigo_editora INNER JOIN tab_vendas V ON L.codigo=V.codigo_livro AND E.codigo=V.codigo_editora; O resultado produzido o mesmo, porm existe uma diferena na performance da consulta, que muito mais rpida ao utilizarmos o JOIN. EQUI JOIN: Semelhante ao NATURAL JOIN, porm retorna todos os campos das tabelas envolvidas no relacionamento, inclusive os campos atravs dos quais as tabelas se relacionam, ocasionando repetio de dados (produto cartesiano):

58

SELECT * FROM tab_editora, tab_livro; Sada:


Editora.codigo Editora.nome estado livro.codigo 1 OURO 2 BRASIL 3 EUROPA 1 OURO 2 BRASIL 3 EUROPA 1 OURO 2 BRASIL 3 EUROPA 1 OURO 2 BRASIL 3 EUROPA 1 OURO 2 BRASIL 3 EUROPA 1 OURO 2 BRASIL 3 EUROPA RJ SP RJ RJ SP RJ RJ SP RJ RJ SP RJ RJ SP RJ RJ SP RJ livro.nome autor BERNARD CORNWELL BERNARD CORNWELL BERNARD CORNWELL GEORGE ORWELL GEORGE ORWELL GEORGE ORWELL codigo_editora 1 1 1 1 1 1 2 2 2 1 1 1 3 3 3 2 2 2

1 O REI DO INVERNO 1 O REI DO INVERNO 1 O REI DO INVERNO 2 1984 2 1984 2 1984

3 NEUROMANCER WILLIAM GIBSON 3 NEUROMANCER WILLIAM GIBSON 3 NEUROMANCER WILLIAM GIBSON 4 EXCALIBUR 4 EXCALIBUR 4 EXCALIBUR 5 ADMIRVEL MUNDO NOVO 5 ADMIRVEL MUNDO NOVO 5 ADMIRVEL MUNDO NOVO BERNARD CORNWELL BERNARD CORNWELL BERNARD CORNWELL ALDOUS HUXLEY ALDOUS HUXLEY ALDOUS HUXLEY

6 O CAADOR DE PHILIP K. ANDRIDES DICK 6 O CAADOR DE PHILIP K. ANDRIDES DICK 6 O CAADOR DE PHILIP K. ANDRIDES DICK

18 rows selected Neste caso, listaremos 18 linhas, ou seja, o produto cartesiano entre as linhas das tabelas envolvidas. Este tipo de JOIN tambm chamado de CROSS JOIN e no muito utilizado. Outra sintaxe possvel : SELECT * FROM tab_editora CROSS JOIN tab_livros;

59

SELF JOIN: um INNER JOIN de uma tabela com ela mesma.

6.2 OUTER JOIN. Um OUTER JOIN os dados relacionados e os no relacionados tambm. LEFT JOIN: lista todas as linhas da tabela esquerda do JOIN, independente do relacionamento:

Considerando as tabelas tab_editora e tab_livro, adicionando uma linha a tab_editora: tab_editora Cdigo 001 002 003 004 Nome Ouro Brasil Europa frica Uf RJ SP RJ SP

Se quisermos listar todas as editoras com seus respectivos livros, escrevemos: SELECT E.nome AS Editora, L.nome AS Livro, L.autor AS Autor FROM tab_editora E, tab_livro L WHERE L.codigo_editora=E.codigo; Sada: Editora ---------Ouro Ouro Ouro Brasil Brasil Europa 6 rows selected Neste caso, a linha contendo a editora frica no aparece, pois no existem livros com esta editora. Se quisermos listar todas as editoras e seus livros, mesmo aquelas que no tenham livros editados, usamos um OUTER LEFT JOIN, assim listaremos todas as linhas da tabela esquerda 60 Livro ---------O Rei do 1984 Excalibur Neuroma O caado Admirave Autor ------------Bernard Co George Orw Bernard Co William Gib Philip K Dic Aldoux Hux

do JOIN, independente delas terem ou no dados correspondentes na segunda tabela: SELECT E.nome, L.nome, L.autor FROM tab_editora E LEFT JOIN tab_livro L ON E.codigo=L.codigo_editora; Sada: Editora ---------Ouro Ouro Ouro Brasil Brasil Europa frica 7 rows selected Agora aparecem na consulta todas as linhas de tab_editora, mesmo aquela que no encontra correspondncia em tab_livros. RIGHT JOIN: lista todas as linhas da tabela direita do JOIN, independente do relacionamento: Livro ---------O Rei do 1984 Excalibur Neuroma O caado Admirave Autor ------------Bernard Co George Orw Bernard Co William Gib Philip K Dic Aldoux Hux

SELECT L.nome AS Livro, L.autor AS Autor, E.nome AS Editora FROM tab_livro L RIGHT JOIN tab_editora E ON E.codigo=L.codigo_editora; Sada: Livro ---------O Rei do 1984 Excalibur Neuroma O caado Admirave Autor -----------Bernard Co George Orw Bernard Co William Gib Philip K Dic Aldoux Hux Editora -----------Ouro Ouro Ouro Brasil Brasil Europa frica

7 rows selected

61

7 SUBQUERIES Aprofundando o comando SELECT. As SUBQUERIES permitem a obteno de dados de uma tabela com base na existncia desses dados em outra consulta ou consultas. O primeiro SELECT do comando chamado de OUTER QUERY ou simplesmente QUERY. Ao segundo SELECT chamamos de SUBQUERY. Considerando as tabelas tab_editora e tab_livro: SELECT L.nome AS Livro FROM tab_livro L WHERE L.codigo_editora= (SELECT E.codigo FROM tab_editora E WHERE E.nome='OURO'); Sada: Livro ------------------O Rei do Inverno 1984 Excalibur 3 rows selected No exemplo acima seria a mesma coisa se escrevssemos: SELECT tab_livro.nome AS Livro FROM tab_livro WHERE tab_livro.codigo_editora=001; Ou seja, testamos o resultado da SUBQUERY. Quando usamos uma SUBQUERY utilizando operadores de comparao, estas devem retornar sempre um nico valor (uma nica linha). Podemos usar todos os operadores de comparao: >, >=, <, <=, =, <> ou !=. Uma SUBQUERY deve selecionar o valor de somente uma coluna, e deve ser escrita entre parnteses. Podemos usar as funes de agregao em uma SUBQUERY:

62

tab_filmes Nome ET Pulp Fiction Homem Aranha O homem que copiava qtd_espectadores 1500000 500000 2000000 750000

SELECT F.nome AS Filme FROM tab_filmes F WHERE F.qtd_espectadores = (SELECT MAX(tab_filmes.qtd_espectadores) FROM tab_filmes); Sada: Filme ----------------Homem Aranha 1 row selected No caso de utilizarmos uma SUBQUERY que retorne mais de uma linha (mas somente de uma coluna) no podemos usar os operadores de comparao, pois estes comparam somente a um argumento. Para fazer uma comparao em uma lista de argumentos, ou seja em SUBQUERIES que retornem mais de uma linha, usamos os operadores IN e NOT IN: SELECT F.nome AS Filme FROM tab_filmes F WHERE F.qtd_espectadores IN (SELECT tab_filmes.qtd_espectadores FROM tab_filmes WHERE tab_filmes.qtd_espectadores >= 750000 AND tab_filmes.qtd_espectadores < 2000000); Sada: Filme --------------------ET O homem que copi 2 rows selected

63

A SUBQUERY: (SELECT tab_filmes.qtd_espectadores FROM tab_filmes WHERE tab_filmes.qtd_espectadores >= 750000 AND tab_filmes.qtd_espectadores < 2000000); Retorna as seguintes linhas: Sada: tab_filmes.qtd_espectadores -------------------------------750000 2000000 Ao realizarmos a QUERY principal, comparamos o campo tab_filmes.qtd_espectadores aos valores selecionados na SUBQUERY. Se, ao contrrio desejarmos selecionar os dados que no estejam contidos no conjunto de linhas selecionado na SUBQUERY, usamos: SELECT F.nome AS Filme FROM tab_filmes F WHERE F.qtd_espectadores NOT IN (SELECT tab_filmes.qtd_espectadores FROM tab_filmes WHERE tab_filmes.qtd_espectadores >= 750000 AND tab_filmes.qtd_espectadores < 2000000); Sada: Filme --------------------Pulp Fiction Homem Aranha 2 rows selected Agora selecionamos as linhas que no encontram correspondncia no conjunto obtido na SUBQUERY.

64

tab_bilheteria Nome ET Homem Aranha bilheteria 2000000 2500000

Considerando as tabelas tab_filmes e tab_bilheteria, usaremos os operadores EXISTS e NOT EXISTS para obter dados relacionados entre as duas tabelas: SELECT tab_filmes.nome AS Filme FROM tab_filmes WHERE EXISTS (SELECT tab_bilheteria.nome FROM tab_bilheteria WHERE tab_bilheteria.nome = tab_filmes.nome); Sada: Filme ----------------ET Homem Aranha 2 rows selected Aqui selecionamos apenas os filmes que tem correspondentes em tab_bilheteria. Se, ao contrrio, quisermos selecionar os filmes que no tem correspondncia em tab_bilheteria, usamos o NOT EXISTS: SELECT tab_filmes.nome AS Filme FROM tab_filmes WHERE NOT EXISTS (SELECT tab_bilheteria.nome FROM tab_bilheteria WHERE tab_bilheteria.nome = tab_filmes.nome); Sada: Filme -----------------Pulp Fiction O homem que c 2 rows selected

65

Ao utilizarmos este formato, para cada linha selecionada na tabela tab_filmes o SQL executa uma vez a SUBQUERY que obtm os dados da tabela tab_bilheteria, assim a SUBQUERY executada 4 vezes, uma para cada linha da tabela tab_filmes. Pelo fato destas SUBQUERIES estarem amarradas QUERY, so chamadas de SUBQUERIES correlacionadas. Este tipo de SUBQUERY consome muitos recursos do sistema no seu processamento, portanto seu uso deve ser cuidadoso. Podemos utilizar uma tcnica de aninhamento de SUBQUERIES. SUBQUERIES aninhadas so compostas de vrios comandos SELECT: Considerando as tabelas: tab_editora Codigo 001 002 003 004 tab_livro Codigo 001 002 003 004 005 006 tab_vendas Cdigo_editora 001 001 002 001 003 002 codigo_livro 002 004 006 001 005 003 qtd_vendida 15 20 40 22 10 15 valor_unit 25.00 42.00 35.00 42.00 26.00 32.00 Nome O Rei do Inverno 1984 Neuromancer Excalibur Admirvel Mundo Novo O caador de andrides autor Bernard Cornwell George Orwell William Gibson Bernard Cornwell Aldous Huxley Philip K. Dick codigo_editora 001 001 002 001 003 002 Nome Ouro Brasil Europa frica Uf RJ SP RJ SP

66

Aninhando SUBQUERIES temos: SELECT tab_editora.nome AS EditoraLivrosVendidos FROM tab_editora WHERE tab_editora.codigo IN (SELECT tab_livro.codigo_editora FROM tab_livro WHERE tab_livro.codigo_editora IN (SELECT tab_vendas.codigo_editora FROM tab_vendas)); Sada EditoraLivrosVendidos ---------------------------Ouro Brasil Europa 3 rows selected Aqui selecionamos as linhas de tab_editora que tenham livros vendidos, utilizando o conjunto obtido na seleo em tab_livro em relao ao conjunto obtido na seleo realizada em tab_vendas.

67

8 Manipulando dados. At agora, aprendemos como recuperar dados ou listas de dados, sem em momento algum alterarmos o contedo do banco de dados. Neste captulo, estudaremos os comandos utilizados para inserir, alterar ou deletar linhas nas tabelas. 8.1 O comando INSERT. Este comando habilita uma incluso no banco de dados. A sintaxe geral : INSERT INTO Tabela (campo1, campo2...) VALUES (valor1, valor2...); Este formato, que adiciona tabela os valores especificados na lista de valores nos campos correspondentes, chamado de INSERT DECLARATIVO. Observamos que: Os valores devem ser do mesmo tipo dos especificados na declarao dos campos no banco de dados; Os valores inseridos devem respeitar o tamanho mximo do campo ao qual sero inseridos; Os valores inseridos aps a clausula VALUES entraro na seqncia especificada na lista de campos, ou seja, no exemplo acima, campo1 assume o valor de valor1, campo2 de valor2 e assim sucessivamente.

Se quisermos inserir os valores de todos os campos na ordem em que estes esto posicionados no precisamos listar os campos. Este formato chamado de INSERT POSICIONAL. Assim o comando ser: INSERT INTO Tabela VALUES (valor1, valor2...); Neste caso, todos os valores correspondentes aos campos da tabela devero ser especificados na ordem em que esto declarados:

68

tab_filmes Nome ET Pulp Fiction Homem Aranha O homem que copiava qtd_espectadores 1500000 500000 2000000 750000

INSERT INTO tab_filmes VALUES (Homem Aranha II, 2500000); Ou: INSERT INTO tab_filmes (qtd_espectadores, nome) VALUES (2500000, Homem Aranha II); Aps qualquer um dos comandos, a tabela passa a ter: tab_filmes Nome ET Pulp Fiction Homem Aranha O homem que copiava Homem Aranha II qtd_espectadores 1500000 500000 2000000 750000 2500000

Podemos utilizar uma combinao de INSERT e SELECT para preencher uma tabela a partir de outra, como no exemplo: INSERT INTO tab_filmes_tmp SELECT * FROM tab_filmes; Neste caso teramos como Resultado uma cpia de tab_filmes em tab_filmes_tmp:

69

tab_filmes_tmp Nome ET Pulp Fiction Homem Aranha O homem que copiava Homem Aranha II qtd_espectadores 1500000 500000 2000000 750000 2500000

Este formato muito mais eficiente do que realizar um comando INSERT para cada linha, mas somente pode ser utilizado quando e se as colunas da tabela receptora forem do mesmo tipo, tamanho e aparecerem na mesma ordem das colunas na tabela original. Podemos usar um comando SELECT mais elaborado: INSERT INTO tab_filmes_tmp SELECT tab_filmes.nome, tab_filmes.qtd_espectadores FROM tab_filmes WHERE tab_filmes.qtd_espectadores > 1500000; tab_filmes_tmp Nome qtd_espectadores Homem Aranha 2000000 Homem AranhaII 2500000 Neste caso obtemos como resultado uma tabela contendo exatamente as linhas do SELECT. Este formato de combinao do INSERT com SELECT pode ser usado sempre que os campos da tabela destino estejam contidos na tabela origem. 8.2 O comando UPDATE. Este comando nos permite alterar o contedo de uma linha existente na tabela. A sintaxe geral do comando : UPDATE Tabela SET campo1=valor1, campo2=valor2... WHERE condio;

70

Onde a primeira clausula executada o WHERE, e os valores sero alterados sempre que a condio for verdadeira. Se a clausula WHERE no existir todas as linhas da tabela sero alteradas: tab_filmes Nome ET Pulp Fiction Homem Aranha O homem que copiava Homem Aranha II qtd_espectadores 1500000 500000 2000000 750000 2500000

UPDATE tab_filmes SET tab_filmes.nome= Teste WHERE tab_filmes.nome=ET; Resultado: tab_filmes Nome Teste Pulp Fiction Homem Aranha O homem que copiava Homem Aranha II qtd_espectadores 1500000 500000 2000000 750000 2500000

UPDATE tab_filmes SET tab_filmes.nome= Teste; Resultado: tab_filmes Nome Teste Teste Teste Teste Teste qtd_espectadores 1500000 500000 2000000 750000 2500000

71

Podemos usar qualquer tipo de condio no WHERE, inclusive uma SUBQUERY: tab_filmes nome ET Pulp Fiction Homem Aranha O homem que copiava Homem Aranha II tab_bilheteria nome ET Pulp Fiction Homem Aranha O homem que copiava Homem Aranha II Bilheteria 25000000 1000000 4000000 1500000 5000000 qtd_espectadores 1500000 500000 2000000 750000 2500000

UPDATE tab_filmes SET tab_filmes.qtd_espectadores=0 WHERE tab_filmes.nome IN (SELECT tab_bilheteria.nome FROM tab_bilheteria WHERE tab_bilheteria.bilheteria > 2000000); Resultado: tab_filmes nome ET Pulp Fiction Homem Aranha O homem que copiava Homem Aranha II qtd_espectadores 0 500000 0 750000 0

72

8.3 O comando DELETE. O DELETE nos permite excluir uma linha de uma tabela. A sintaxe do comando : DELETE FROM Tabela WHERE condio; Da mesma forma que o UPDATE, o comando DELETE analisa primeiro a clausula WHERE, e as linhas que obedecerem a condio sero excludas: tab_filmes Nome ET Pulp Fiction Homem Aranha O homem que copiava Homem Aranha II qtd_espectadores 0 500000 0 750000 0

DELETE FROM tab_filmes WHERE tab_filmes.qtd_espectadores=0 ; Resultado: tab_filmes Nome Pulp Fiction O homem que copiava qtd_espectadores 500000 750000

Podemos usar qualquer tipo de condio aps o WHERE, sejam elas simples ou SUBQUERIES. Ateno: se nenhuma clausula WHERE for especificada, todas as linhas da tabela sero excludas.

73

9 Criando e mantendo Tabelas. At o momento, utilizamos tabelas j criadas ou as geramos atravs de ferramentas prprias do banco de dados, mas o SQL possui comandos prprios para a criao e manuteno do banco de dados e das tabelas. 9.1 Criando um Banco de Dados. O comando usado para a criao de um BD : CREATE DATABASE NomeBD; Muitos gerenciadores de Banco de Dados no aceitam esta sintaxe, somente permitem criar tabelas via SQL. 9.2 Criando Tabelas. O comando para criao de uma tabela via comando SQL um pouco mais complexo do que o usado para criar o Banco de Dados. Alm do comando CREATE TABLE, devemos especificar os campos, com o tipo e o tamanho de cada um: CREATE TABLE NomeBD.Tabela (campo1 CHAR(30) NOT NULL, campo2 Number... PRIMARY KEY ("campo1") ); Na criao de uma tabela alm do tipo de dados declaramos se um campo aceita ou no valores nulos e as suas chaves. Os tipos de dados que podemos usar em uma declarao de tabela so:

74

Para o Oracle: Tipo CHAR DATE LONG LONG RAW NUMBER RAW ROWID Descrio Dados alfanumricos com tamanho suportado entre 1 e 255 caracteres. Data/hora, incluindo sculo, ano, ms, dia, horas minutos e segundos. Dados alfanumricos de at 2 Gb. Tambm chamado de MEMO Dados binaries at 2 Gb, tambm chamado de BINARY LARGE OBJECT, ou BLOB Numrico, positivo ou negativo inteiro ou com casas decimais. Dado Binrio de at 255 bytes. Hexadecimal representando o endereo da linha na tabela. Tambm chamado de chave primria ou IDENTFY FIELD

VARCHAR2 Alfanumrico cujo tamanho pode variar entre 1 e 2.000 caracteres. Para o Sql Server
Numricos Inteiros bigint Armazena dados numa faixa de valores entre -2^63 (9223372036854775808) e 2^63-1 (9223372036854775807), utiliza 8 bytes. int Armazena dados numa faixa de valores entre -2^31 (-2,147,483,648) e 2^31 - 1 (2,147,483,647), utiliza 4 bytes. smallint Armazena dados numa faixa de valores entre 2^15 (-32,768) e 2^15 - 1 (32,767), utiliza 2 bytes tinyint Armazena dados numa faixa de valores entre 0 e 255, utiliza 1 bytes. Bin bit Datatype utilizado para armazenar os valores 1 ou 0, utiliza 1 byte. decimal e numeric decimal Precisao fixa e faixa de valores vai de -10^38 +1 a 10^38 1. numeric Funcionalidade igual ao decimal. Numricos Monetrios money Representa valor na moeda norte-americana, que podem ter at quatro dgitos para as casas decimais e, portanto, tero o arredondamento acontecendo na quarta casa decimal. Ocupa 8 bytes armazena uma faixa de valor que vai de -2^63 (-922,337,203,685,477.5808) a 2^63 - 1 (+922,337,203,685,477.5807). smallmoney Representa valor na moeda norte-americana, que podem ter at quatro dgitos para as casas decimais e, portanto, tero o arredondamento acontecendo na quarta casa decimal. Ocupa 4 bytes armazena uma faixa de valor que vai de -214,748.3648 e +214,748.3647.

75

Numricos Aproximados float Datatype para armazenar nmeros que no tm uma quantidade certa de dgitos para as casas decimais, e justamente por isso so chamados de ponto flutuante, armazena valores na faixa de -1.79E + 308 a 1.79E + 308, ocupa 8 bytes. real Datatype para armazenar nmeros que no tm uma quantidade certa de dgitos para as casas decimais, e justamente por isso so chamados de ponto flutuante, armazena valores na faixa de -3.40E + 38 through 3.40E + 38, ocupa 4 bytes. Data/Hora datetime

Armazena uma data que vai de 1/1/1753 a 31/12/9999, com uma precisao de 3.33 milissegundos. Ocupa 8 bytes. Os primeiros 4 so usados pra data(ms/dia/ano), e os outros 4 bytes so usados pro horrio(HH:MM:SS:MS). Armazena uma data que vai de 1/1/1900 at 6/6/2079 com uma preciso de 1 minuto. Os 2 primeiros bytes so usados pra data(ms/dia/ano), e outros 2 pro horrio(HH:MM:SS). Datatype de tamanho fixo que armazena at 8.000 caracteres, cada caracter ocupa 1 byte. Datatype de tamanho varivel que armazena at 8.000 caracteres, cada caracter ocupa 1 byte. Datatype de tamanho varivel que armazena at 2^31 - 1 (2,147,483,647) caracteres, cada caracter ocupa 1 byte.

smalldatetime Caracteres char varchar text

Caracteres Unicode - O unicode foi inventado para resolver o problema de um nico dgito ser armazenado com um determinado valor em um sistema de cdigos e ser armazenado com outro valor em outro sistema de cdigos diferente. O unicode atribui apenas um nico nmero a cada caractere existente. nchar Datatype de tamanho fixo que armazena dados no formato caractere unicode, pode armazenar at 4.000 caracteres, cada caracter ocupa 2 bytes. nvarchar Datatype de tamanho varivel que armazena dados no formato caractere unicode, pode armazenar at 4.000 caracteres, cada caracter ocupa 2 bytes. ntext Datatype de tamanho varivel que armazena dados no formato caractere unicode, pode armazenar at 2^30 - 1 (1,073,741,823) characters, cada caracter ocupa 2 bytes. Datatypes Binrios binary Datatype de tamanho fixo que armazena dados binarios no formato hexadecimal, armazena at 8,000 bytes. varbinary image Datatype de tamanho varivel que armazena dados binarios no formato hexadecimal, armazena at 8,000 bytes. Datatype de tamanho varivel que armazena dados binarios no formato hexadecimal, armazena at 2^31 - 1 (2,147,483,647) bytes.

Alguns gerenciadores permitem a criao e preenchimento da tabela ao mesmo tempo, utilizando a sintaxe: CREATE TABLE Tabela2 (campo1 CHAR(30), campo2 NUMBER) AS (SELECT campo1, campo2 FROM Tabela1 [WHERE condio]); Assim criamos a Tabela2 com o contedo trazido a partir da seleo efetuada na Tabela1.

76

9.3 Alterando a estrutura de uma Tabela. Muitas vezes necessrio alterar a estrutura de uma tabela, seja criando novos campos ou alterando seu formato ou tamanho. Para isto temos o comando ALTER TABLE. Para adicionar um novo campo para a tabela, usamos o seguinte formato: ALTER TABLE Tabela ADD campo3 CHAR(20), campo4 VARCHAR2; A clausula ADD adiciona o(s) campo(s) no formato e tamanho indicado. Se quisermos alterar o formato ou tamanho de um dos campos, a sintaxe utilizada : ALTER TABLE Tabela MODIFY campo3 CHAR(40);(Oracle) ALTER TABLE Tabela ALTER COLUMN campo3 CHAR(40) (Sql Server) Ao usar o comando ALTER TABLE com a clausula MODIFY ou ALTER COLUMN, devemos observar que os campos que tiverem seu tamanho modificado no podero conter dados ocupando um tamanho maior do que o novo tamanho especificado. A clausula MODIFY no aceita para todos os gerenciadores. 9.4 Excluindo Tabelas e Banco de Dados. Para excluir um Banco de Dados ou uma Tabela, temos o comando DROP DATABASE e DROP TABLE respectivamente. A sintaxe dos comandos : DROP DATABASE NomeBD; Usado para excluir uma base de dados, no aceito em todos os gerenciadores. DROP TABLE Tabela; Este comando exclui definitivamente a tabela e seus ndices, por isso importante seu uso aps acabar de utilizar uma tabela temporria, por exemplo, evitando sobrecarregar o Banco de Dados com ndices que no sero mais usados. Como o comando no exige nenhum tipo de confirmao para sua execuo, devemos ter cuidado ao utiliza-lo, pois uma vez apagada a tabela atravs deste recurso, no poderemos recupera-la.

77

10 VIEW um objeto que permite que os dados de uma ou mais tabelas sejam visualizados de uma forma diferente da maneira de como foram criados. Este objeto permite que essa visualizao lgica seja compartilhada por uma ou mais aplicaes. um objeto que os gerenciadores de banco de dados utilizam para gravar os resultados de uma consulta como se fosse uma tabela. Uma VIEW uma consulta, portanto dentro dela s podemos escrever o comando SELECT. Os comandos SELECT dentro de uma VIEW podem ser combinados com: JOIN; UNION; GROUP BY - com funo de totalizao; SUBQUERY; ORDER BY - apenas com TOP.

Em uma VIEW podemos ocultar linhas e/ou colunas de uma ou mais tabelas. Sintaxe: CREATE VIEW Nome_da_VIEW AS SELECT Campo1 as Alias1, Campo2 as Alias2,... FROM Tabela WHERE Campo3 = valor Depois disso podemos acessar os dados da tabela atravs da VIEW: SELECT * FROM Nome_da_VIEW possvel ainda manipular dados de uma tabela por meio de VIEWS, com os comandos INPUT, UPDATE E DELETE: Sintaxe: INSERT INTO Nome_da_View VALUES(Dado1,Dado2,...) UPDATE Nome_da_View SET Alias1 = Dado1 WHERE Alias2 = Dados2 DELETE Nome_da_View WHERE Alias1 = Dado1

78

Para alterar a estrutura de uma VIEW j existente, voc pode utilizar o comando ALTER VIEW com o qual possvel realizar qualquer alterao dentro de uma VIEW, desde que no altere o seu nome. ALTER VIEW Nome_da_VIEW AS SELECT Campo1 as Alias1, Campo2 as Alias2,... FROM Tabela WHERE Campo3 = valor Para eliminar uma VIEW de uma base de dados, utilizamos o comando DROP VIEW: DROP VIEW Nome_da_VIEW 10.1 - WITH CHECK OPTION Se for necessrio que todas as operaes realizadas com os dados das tabelas por meio da VIEW obedeam clusula WHERE devemos acrescentar a clusula WITH CHECK OPTION na criao da VIEW: CREATE VIEW Nome_da_View AS SELECT Campo1 as Alias1, Campo2 as Alias2,... FROM Tabela WHERE Campo3 = Xvalor WITH CHECK OPTION 10.2 - WITH ENCRYPTION Quando uma VIEW criada, algumas informaes sobre ela so registradas nas tabelas do sistema: O nome da VIEW registrado na tabela SYSOBJECTS; Os comandos de criao da VIEW (cdigo fonte), so registrados na tabela do sistema SYSCOMMENTS.

Qualquer usurio que tenha acesso s tabelas do sistema conseguir ler o cdigo de criao das suas prprias VIEWS: SELECT Text FROM SYSCOMMENTS WHERE Id = (SELECT Id FROM SYSOBJECTS WHERE Name = 'Nome_da_VIEW') Podemos tambm criptografar o cdigo de criao das VIEWS, atravs da clusula WITH ENCRYPTION: CREATE VIEW Nome_da_VIEW 79

WITH ENCRYPTION AS SELECT Campo1 as Alias1, Campo2 as Alias2,... FROM Tabela WHERE Campo3 = valor 10.3 VIEW de VIEW possvel ainda criar uma VIEW que filtre dados de outra VIEW. Mas a necessidade de criar VIEWS aninhadas deve sempre ser bem avaliada, j que esta prtica pode causar problemas de performance. Primeira VIEW: CREATE VIEW Nome_da_VIEW_um AS SELECT Campo1 as Alias1, Campo2 as Alias2,... FROM Tabela VIEW aninhada: CREATE VIEW Nome_da_VIEW_dois AS SELECT Campo1 as Alias1 FROM Tabela WHERE Campo3 = valor Se for mesmo necessrio trabalhar com VIEWS aninhadas, devemos atribuir nomes a elas que indiquem seu nvel de aninhamento para facilitar a deteco de possveis problemas de performance.

80

11 STORED PROCEDURES STORED PROCEDURE um tipo de programa criado no servidor do banco de dados, dentro de uma base de dados especfica, que tem como principal objetivo concentrar operaes realizadas com os dados contidos no banco de dados. 11.1 Regras para Criar STORED PROCEDURES Uma STORED PROCEDURE pode receber parmetros de entrada; Os parmetros de entrada de uma STORED PROCEDURE no podem ser do tipo TABLE; (Sql Server); Uma STORED PROCEDURE usa trs formas para retornar valores: o Com o comando RETURN; o Com um SELECT como ltimo comando (retornando o contedo de uma tabela); o Com parmetros OUTPUT (retornando vrios valores de uma s vez); Dentro de uma STORED PROCEDURE podemos executar qualquer comando da linguagem Transact-SQL, exceto o prprio comando CREATE PROCEDURE; Para executar uma STORED PROCEDURE, devemos utilizar o comando EXECUTE ou a procedure SP_EXECUTESQL.

Sintaxe: CREATE PROC[EDURE] Nome_Da_Procedure[;Numero] [{@parmetro datatype}] [VARYING][=default][OUTPUT] [,n] [WITH{RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}] [FOR REPLICATION] [AS] Corpo da Procedure: Comandos Transact-SQL: Numero um numero inteiro usado para agrupar PROCEDURES de mesmo nome, assim elas podem ser eliminadas juntas com um nico comando DROP PROCEDURE. Suponha que na base de dados existam as seguintes PROCEDURES: P_AlteraSal;1 P_AlteraSal;2 81

P_AlteraSal;3 P_AlteraSal;4

Se alterar salrio tiver clculos diferenciados, interessante utilizar o mesmo nome com o Numero. Podemos utilizar uma PROCEDURE de cada vez, na situao adequada: EXEC EXEC EXEC EXEC P_AlteraSal;1 P_AlteraSal;2 P_AlteraSal;3 P_AlteraSal;4 <parametros> <parametros> <parametros> <parametros>

Estas PROCEDURES no podem ser eliminadas individualmente, devem ser eliminadas todas de uma s vez. DROP PROCEDURE P_AlteraSal. VARYING Tipo de dado que se aplica apenas a parmetros de cursores. DEFAULT um valor definido como padro para um parmetro de uma PROCEDURE para que o gerenciado de banco de dados tenha um valor definido previamente para o referido parmetro, no caso de nada ser informado durante a sua execuo. OUTPUT um parmetro que indica que a PROCEDURE retorna um valor sem utilizar o comando RETURN: CREATE PROCEDURE P_Conta @Num_1 int, @Num_2 int, @Resposta bigint OUTPUT AS SET @Resposta = @Num_1 * @Num_2 Esta PROCEDURE recebe trs parmetros, sendo @Num_1, @Num_2 e @Resposta OUTPUT. No exemplo acima, a PROCEDURE apenas atribui varivel @Resposta o resultado da multiplicao de @Num_1 por @Num_2, no retornando diretamente valor algum. Observando o comando para executar a PROCEDURE abaixo: DECLARE @Resultado bigint EXEC P_Conta 10,7,@Resultado OUTPUT 82

PRINT @Resultado Neste caso temos um retorno direto da PROCEDURE. WITH RECOMPILE Indica que o servidor de banco de dados no deve manter na memria o plano de execuo desta PROCEDURE, gerando um novo plano todas as vezes que ela for executada. WITH ENCRYPTION Faz com que o gerenciador do banco de dados criptografe o cdigo da STORED PROCEDURE na tabela de sistema SYSCOMMENTS, de modo a que a procedure no seja publicada durante uma replicao. FOR REPLICATION Especifica que a STORED PROCEDURE no pode ser executada no servidor SUBSCRIBER. Uma procedure criada com este parmetro usada como um filtro e executada apenas durante a replicao. Esta opo no pode ser utilizada em conjunto com WITH RECOMPILE.

83

12 Transao uma unidade lgica de processamento que tem por objetivo preservar a integridade e a consistncia dos dados de um sistema. Ela parte essencial de um sistema, pois permite que o gerenciador de banco de dados restaure os dados para uma situao anterior a uma falha no processamento, caso isto ocorra. Supondo que em um Banco Comercial fosse necessrio realizar uma retirada um determinado valor em dinheiro de uma conta corrente, creditando esse mesmo valor em uma conta de aplicao, imaginemos que as contas correntes do Banco sejam controladas pela tabela ContaCorrente, e as contas de aplicao sejam controladas pela tabela Aplicao. Sendo assim, a unidade de processamento que deve ser criada vai conter um dbito de uma conta e um crdito em outra conta. Assim sendo, altamente imprescindvel que o dbito e o crdito sejam realizados. Esta unidade de processamento precisa ser realizada em duas etapas e necessrio garantir que o gerenciador de banco de dados realizar a tarefa por inteiro ou que no far nada, caso ocorra algum problema entre a realizao do dbito e do crdito, preservando as tabelas ContaCorrente e Aplicao. Este requerimento do tipo ou faz tudo ou no faz nada chamado de atomicidade. 12.1 Comandos de Transao Begin Transaction, Rollback Transaction e Commit Transaction No Sql Server, para realizar esta unidade de processamento com atomicidade, devemos abrir a transao, realizar as operaes com dados e verificar se algum problema ocorreu. Se todas as operaes com os dados forem realizadas com sucesso, devemos confirmar a operao. Caso algum problema tenha ocorrido, devemos garantir que nada seja feito: Criar a Unidade de Processamento; Realizar o DBITO; Checar a ocorrncia de erro; Se ocorreu erro: o Desfazer qualquer operao que tenha sido feita at este ponto; 84

o Interromper o processamento; Realizar o CRDITO; Checar a ocorrncia de erro Se ocorreu erro: o Desfazer qualquer operao que tenha sido feita at este ponto; o Interromper o processamento; Se no ocorrer nenhum problema: o Confirmar a operao.

Para realizar este processamento, so necessrios trs comandos: BEGIN TRANSACTION: Cria uma transao(unidade de processamento lgico); ROLLBACK TRANSACTION: Encerra a transao e desfaz qualquer operao que tenha sido realizada com os dados; COMMIT TRANSACTION: Encerra a transao e efetiva qualquer operao que tenha sido realizada com os dados. Observando o seguinte esquema: BEGIN TRANSACTION Realizar o DBITO Checar a ocorrncia de algum erro Se ocorreu erro : ROLLBACK TRANSACTION RETURN Realizar o CRDITO Checar a ocorrncia de algum erro Se ocorreu erro : ROLLBACK TRANSACTION RETURN Se no ocorrer nenhum problema COMMIT TRANSACTION 12.2 - @@ERROR @@ERROR: uma varivel global (tambm chamada de funo), alimentada pelo prprio Sql Server aps a realizao de qualquer comando da linguagem Transact-Sql. Dentro de @@ERROR haver o valor igual a zero se, aps a realizao de um comando nenhum erro ocorrer, ou aparecer um numero 85

representando um determinado erro (existente na tabela SYSMESSAGES), caso tenha ocorrido algum problema no processamento do comando: BEGIN TRANSACTION Realizar o DBITO IF @@ERROR <> 0 BEGIN ROLLBACK TRANSACTION RETURN END Realizar o CRDITO IF @@ERROR <> 0 BEGIN ROLLBACK TRANSACTION RETURN END COMMIT TRANSACTION

86

13 Tpicos avanados de SQL CURSOR. Cursores so variveis utilizadas para navegar pelas linhas retornadas de um comando SQL. Algumas vezes conveniente armazenar o resultado de uma consulta para uso posterior, ou ento utilizarmos o SQL em conjunto com algumas linguagens que no conseguem tratar o retorno de SQL contendo mais de uma linha, como acontece com o Cobol. Nestes casos, armazenamos o resultado em uma varivel do tipo CURSOR, atravs da qual podemos navegar atravs de ponteiros. Quando no for necessrio o uso de cursores, estes devem ser evitados, pois o SQL uma linguagem criada para tratamento de conjuntos, ou seja, a performance de um comando SQL utilizando cursores menos eficaz do que a manipulao de dados em conjunto. Cursores podem ser utilizados para operaes de consulta, alterao e excluso, nunca para uma operao de incluso. A seguir, veremos como criar, abrir, acessar, fechar e desalocar da memria uma varivel do tipo cursor. 13.1 Criando um CURSOR. A declarao de um CURSOR no padro SQL 92: DECLARE NomeCursor CURSOR FOR comando SELECT [FOR UPDATE OF campo1, campo2.../ ORDER BY campo1]; Onde: No uso de UPDATE no necessrio que a coluna a ser atualizada aparea no SELECT; O uso de FOR UPDATE OF e ORDER BY mutuamente exclusivo; Se especificarmos as colunas aps o UPDATE, somente as especificadas podero ser alteradas, se nenhuma coluna for especificada, todas as colunas da tabela podero ser alteradas.

Existem outras clausulas que podem ser acrescidas no momento da criao de um cursor, vlidas para o padro Transact SQL. So elas:

87

DECLARE NomeCursor CURSOR [LOCAL/ GLOBAL/ FORWARD_ONLY/ SCROLL/ STATIC/ KEYSET/ DYNAMIC/ FAST_FORWARD/ READ ONLY/ SCROLL_LOCKS/ OPTIMISTIC/ TYPE_WARNING] FOR comando SELECT [FOR UPDATE OF campo1, campo2.../] Onde: LOCAL: Especifica que o cursor de uso local; GLOBAL: Disponibiliza o escopo do cursor para toda a conexo; FORWARD_ONLY: Neste caso a navegao pelo cursor somente poder ser executada da primeira para a ltima linha; SCROLL: Disponibiliza todas as operaes de busca no cursor; STATIC: Impossibilita a alterao dos dados contidos no cursor; KEYSET: Cria um controle atravs de ndice para o cursor; DYNAMIC: Este tipo de cursor reflete todas as alteraes nos valores dos dados contidos no cursor; FAST_FORWARD: Otimiza a performance da navegao. No pode ser usado em conjunto com a opo FOWARD_ONLY; READ_ONLY: Impede a alterao ou excluso de algum dado presente no cursor; SCROLL_LOCKS: garante que os dados recuperados possam ser alterados posteriormente. No pode ser utilizada em conjunto com FAST_FORWARD; OPTIMISTIC: Garante que as linhas que tiverem seu valor alterado dentro do cursor no possam ser novamente alteradas ou deletadas; TYPE_WARNING: envia mensagens de advertncia sempre que for alterado o tipo de dado em um cursor.

13.2 Abrindo um CURSOR. O comando SELECT de um cursor somente ser executado na abertura do cursor. nesse momento que o SQL monta a lista de ponteiros e a associa ao cursor. A sintaxe do comando : OPEN NomeCursor; 13.3 Acessando um CURSOR. Navegamos dentro de um cursor utilizando o comando FETCH: FETCH NomeCursor [INTO varivel/variveis receptora(s)];

88

Ao utilizarmos o comando, o ponteiro do cursor avana atravs do resultado da consulta, uma linha por vez. Quando usamos a opo INTO, os dados resultantes sero armazenados na(s) varivel(variveis) especificada(s). Para resgatar todas as linhas de uma consulta necessrio que o comando FETCH seja executado dentro de uma estrutura de repetio. Podemos checar o STATUS do cursor durante o processamento. Para isto, o Transact SQL possui duas variveis: @@SQLSTATUS e @@ROWCOUNT. O status pode assumir os seguintes valores: 0 (zero) se o processamento for OK; 1 (um) se o processamento ocasionou erro; 2 (dois) se no existirem mais linhas a serem processadas no cursor.

Outros BDs possuem diferentes variveis para armazenar o status, como o DB2, que possui a varivel chamada SQLCA (SQL COMMUNICATION REA), que composta, dentre outras subvariveis pela SQLERRM e o SQLCODE. Caso haja erro (SQLCODE < 0) a SQLERRM contem uma parte da descrio do erro: Valores menores que zero: indicam que ocorreu erro; Valores entre zero e cem (inclusive): indicam que o comando foi executado, porm com restries; Valor igual a 100 (cem): Indica que o fim da lista de dados foi atingido; Valor igual a zero: Processamento OK.

13.4 Fechando um CURSOR. O fechamento de um cursor simples e tem a mesma sintaxe para todos os gerenciadores: CLOSE NomeCursor; O fechamento de um cursor no implica no desalocamento do mesmo na rea de memria, aps fecharmos um cursor, podemos reabri-lo sem problemas. Quando desejarmos desalocar o cursor da memria, usamos o comando DEALLOCATE: DEALLOCATE CURSOR NomeCursor; Assim liberamos a rea de memria utilizada pelo cursor. 89

Exemplos : Primeiro exemplo: Declarao de variveis que sero utilizadas no cursor: DECLARE @cod_pai int, @nome_pai char(50), @idade_pai tinyint Primeira linha da declarao do cursor: DECLARE COPIA_TABELA CURSOR FOR (copia_tabela o nome do cursor) Seleo de campos em uma tabela pra preencher o cursor: SELECT Cod_Pai, Nome_Pai, Idade_pai FROM PAI2 Abrindo o cursor: OPEN COPIA_TABELA Lendo a primeira linha do cursor: FETCH NEXT FROM COPIA_TABELA Colocando os dados da primeira linha do cursor nas variveis: INTO @cod_pai, @nome_pai, @idade_pai Verificando se no ocorreu erro na leitura: WHILE @@FETCH_STATUS = 0 BEGIN Inserindo na tabela pai os valores da linha do cursor: INSERT INTO PAI VALUES(@cod_pai, @nome_pai, @idade_pai) 90

Lendo a prxima linha do cursor: FETCH NEXT FROM COPIA_TABELA INTO @cod_pai, @nome_pai, @idade_pai END Fechando o cursor: CLOSE COPIA_TABELA Desalocando o cursor da memria: DEALLOCATE COPIA_TABELA Segundo exemplo: DECLARE @codrt int, @codgrpprio int, @codsusep char(4), @codresolucao int, @indpriosusep int DECLARE tblParametros_Cursor CURSOR FOR SELECT codGrpPrio, codSusep, codResolucao, indPrioSusep FROM tblPrioridades OPEN tblParametros_Cursor FETCH NEXT FROM tblParametros_Cursor INTO @codgrpprio, @codsusep , @codresolucao, @indpriosusep SET @Codrt = 10 WHILE @@FETCH_STATUS = 0 BEGIN 91

INSERT INTO tblPrioridadesRT (codRT, codGrpPrio, codSusep, codResolucao, indPrioSusep ) VALUES (@codrt, @codgrpprio, @codsusep, @codresolucao, @indpriosusep) FETCH NEXT FROM tblParametros_Cursor INTO @codgrpprio, @codsusep , @codresolucao, @indpriosusep SET @codrt = @codrt + 1 END CLOSE tblParametros_Cursor DEALLOCATE tblParametros_Cursor

92

14 Erros comuns do SQL e suas solues. Neste captulo apresentaremos os erros mais comuns com as mensagens e as opes de tratamento dos mesmos. Erros de sintaxe/operacionais: table or view does not exist Esta mensagem pode aparecer se o nome da tabela ou VIEW estiver escrito errado ou se o usurio no tiver acesso permitido tabela ou ao VIEW; invalid username/password; logon denied Acontece quando o login e/ou a senha do usurio esto incorretas. Pode ocorrer tambm quando o servidor no est disponvel; FROM keyword not found where expected Esta mensagem de erro pode nos induzir a procurar o erro no lugar errado. Pode ser que a clausula FROM no esteja realmente especificada, ento a soluo fcil, porm muitas vezes o FROM est l, mas existem erros nas clausulas anteriores, como, por exemplo, esquecer de fechar um parntese ou esquecer a virgula para separar campos em um SELECT. Como o SQL no entende a sintaxe do SELECT, acusa o erro como se a clausula FROM tivesse sido esquecida; group function is not allowed here Isto ocorre quando utilizamos uma funo de agregao, como COUNT ou SUM na clausula GROUP BY, que s pode ser usada com campos da tabela; invalid column name Este erro ocorre quando nos referenciamos a uma coluna da tabela que no existe; missing left parenthesis Ocorre quando no fechamos os parnteses corretamente; missing right parenthesis Parnteses foram fechados sem serem abertos; missing comma Ocorre quando esquecemos de colocar a virgula em uma lista de campos a serem recuperados em uma instruo SELECT ou em uma lista de valores a serem inseridos em um INSERT; column ambigously defined Aparece quando o nome de uma coluna no est bem definido na consulta, por exemplo ao realizar uma consulta em duas tabelas, ambas possuem a coluna nome. Neste caso devemos nos referenciar coluna nome da tabela1 como tabela1.nome e a coluna da tabela2 como tabela2.nome. Se utilizarmos apenas nome o SQL no saber a qual campo a consulta se refere; command not properly ended Quando o caractere delimitador de um comando SQL (ponto e virgula, barra) no est presente;

93

missing expression Acontece quando terminamos uma lista de argumentos com virgula, como em um SELECT ou valores a serem inseridos em um INSERT; not enough arguments for function Os argumentos passados para a funo esto incompletos ou incorretos; not enough values Ocorre quando ao realizar um INSERT a lista de campos maior que a lista de valores a serem inseridos; integrity constraint (campo1) violated parent key not found Acontece quando tentamos inserir um valor em uma tabela1 que possui uma chave estrangeira da tabela2 e este valor invlido, ou seja, no existe na tabela2; inserted value too large for column Um ou mais valores inseridos maior que a capacidade da coluna; insufficient privileges O usurio no tem permisso para executar o comando;

Erros de lgica: Usar palavras reservadas para nomear tabelas ou campos, como DATE, por exemplo; Usar a clausula DISTINCT em mais de uma coluna; DROPAR uma tabela sem querer: comum ter mais de uma tabela com o mesmo nome em um sistema, por isso devemos estar atentos ao remover a tabela indicando a qual database a tabela pertence; Gerar um produto cartesiano ao realizar um JOIN de uma tabela: ocorre quando realizamos um JOIN sem utilizar a clausula WHERE, neste caso teremos valores duplicados; Permitir a duplicao de linhas nas tabelas: ocorre quando no existe uma definio de chave primria ou chaves estrangeiras na elaborao do Banco de dados. Um bom planejamento evita este tipo de redundncia Incluir valores numricos entre plics; Incluir alfanumricos sem plics ou colchetes.

94

15 Exerccios propostos. 1 - Usando a tabela Customers, escreva uma QUERY que retorne todas as companhias (CompanyName). 2 - Usando a tabela Customers, escreva uma QUERY que retorne todas as companhias (CompanyName), endereo (Address) e pas (Country). 3 - Usando a tabela Customers, escreva uma QUERY que retorne todas as companhias (CompanyName), endereo (Address), e pas (Country), mostrando nesta ordem : PAIS, COMPANHIA e ENDEREO, com nome da coluna em portugus. 4 - Usando a QUERY do exerccio n 3, reescreva-a retornando apenas a primeira linha do resultado. 5 Usando a tabela Customers, escreva uma QUERY que retorne todos os Pases, sem repeti-los. 6 - Usando a tabela Employees, escreva uma QUERY que retorne o PrimeiroNome (FirstName) e o Sobrenome (LastName) dos empregados, onde o Primeiro nome inicie com a letra M. 7 Usando a QUERY do exerccio n 6, reescreva-a incluindo tambm a Cidade (City) filtrando pelos empregados que moram em Londres (London). 8 Usando a tabela Products, escreva uma QUERY que retorne o Cdigo do Produto (ProductID),Nome do Produto (ProductName) e Preo Unitrio (UnitPreo), onde o preo esteja entre 18,00 e 20,00, ordenado pelo nome do produto. 9 Usando a tabela Suppliers, escreva uma QUERY que retorne os trs primeiros caracteres dos Pases (Country), sem repeti-los. 10 Usando a tabela Order Details, escreva uma QUERY que mostre o nmero de Itens do Pedido (OrderID), do pedido nmero 10273. 11 Usando a tabela Order Details, mostre o Pedido (OrderID), o Cdigo do Produto (ProductID), o Preo (UnitPrice) e a Quantidade (Quantity), onde o nmero do pedido seja igual a 10273. 12 Usando a QUERY do exerccio 11, inclua a coluna Valor, que retornar o resultado da quantidade vezes o preo unitrio dos produtos listados.

95

13 Usando a tabela Order Details, escreva uma QUERY que retorne o Valor Total do pedido (OrderID), cujo numero seja o 10273. 14 Usando a tabela Products, escreva uma QUERY que retorne a Media dos preos (UnitPrice) dos produtos. 15 Usando a tabela Customers e Employees, escreva uma QUERY que retorne os pases onde constem Clientes e Empregados. 16 Usando a tabela Customers, escreva uma QUERY que retorne Companhia, Cidade e Pais, onde os pases sejam Alemanha e Brasil, ordenados por Pais, Cidade e Companhia. 17 Usando a tabela Products, escreva uma QUERY que retorne Nome do Produto, Preo Unitrio e Quantidade em estoque, onde os preos variem entre 10,00 e 20,00 e que estejam em estoque, ordenados pelo Preo Unitrio e pelo Nome do Produto. 18 Usando a tabela Products, escreva uma QUERY que retorne a quantidade de produtos que NO estejam em estoque. 19 Usando a tabela Products, escreva uma QUERY que retorne o Maior e o Menor preo dos produtos. 20 Usando a tabela Tab_Frutas (FRUTAS), escreva uma QUERY que retorne a Data da Validade, acrescida de 05 anos, para o produto MAMAO. 21 Usando a tabela Orders (NORTHWIND), escreva uma QUERY que retorne o OrderID e ShipName, trocando todas as letras a por * na coluna ShipName, onde OrderID esteja entre 10248 e 10255. 22 Usando a tabela Orders, escreva uma QUERY que retorne Shipname e Posio da letra a na coluna Shipname onde OrderId seja menor que 10255. 23 Usando a tabela Customers, escreva uma QUERY que retorne Cdigo do Cliente, Companhia, Tamanho do nome da companhia e Pas, onde o pas seja o Brasil e o Cdigo do Cliente comece com a letra Q, ordenado pelo nome da companhia. 24 Usando a tabela Order Details, escreva uma QUERY que retorne Cdigo do Pedido, Preo Unitrio e Quantidade de todos os pedidos.

96

25 Usando a tabela Order Details, escreva uma QUERY que retorne Cdigo do Pedido, Preo Unitrio, Quantidade e o Valor do Pedido de todos os pedidos. 26 - Usando a tabela Order Details, escreva uma QUERY que retorne Cdigo do Pedido, Valor Total por Pedido de todos os pedidos agrupados. 27- Observe a QUERY abaixo: SELECT P.Nome_Pai as 'Nome do Pai', F.Nome_Filho as 'Nome do Filho', Sexo_Filho as 'Sexo do Filho' FROM Pai P, Filho F Rode-a no banco TESTE e observe o seu resultado. Houve linha repetida? Quantas linhas retornaram? 28 Agora rode a QUERY abaixo. SELECT P.Nome_Pai as 'Nome do Pai', F.Nome_Filho as 'Nome do Filho', Sexo_Filho as 'Sexo do Filho' FROM Pai P, Filho F WHERE P.Cod_Pai = F.Cod_Pai Quantas linhas retornaram? Qual foi a diferena entre esta consulta e a anterior? 29 Faa a mesma consulta, agora utilizando a clusula INNER JOIN. 30 Observe o retorno da QUERY: SELECT * FROM Pai, Filho. 31 Utilizando a QUERY acima, altere-a pra no mostrar valores repetidos, sem utilizar INNER JOIN. 32 Faa a mesma consulta, agora utilizando a clusula INNER JOIN. 33 Utilizando a QUERY do exerccio 29, inclua a condio de listar somente os Filhos de Sexo Feminino. 34 Rode as QUERIES abaixo e observe os resultados: SELECT P.Nome_Pai as 'Nome do Pai', F.Nome_Filho as 'Nome do Filho', Sexo_Filho as 'Sexo do Filho' FROM Pai P LEFT JOIN Filho F ON P.Cod_Pai = F.Cod_Pai

97

SELECT P.Nome_Pai as 'Nome do Pai', F.Nome_Filho as 'Nome do Filho', Sexo_Filho as 'Sexo do Filho' FROM Pai P RIGHT JOIN Filho F ON P.Cod_Pai = F.Cod_Pai SELECT P.Nome_Pai as 'Nome do Pai', F.Nome_Filho as 'Nome do Filho', Sexo_Filho as 'Sexo do Filho' FROM Pai P CROSS JOIN Filho F Vamos discutir os resultados 35 Execute a QUERY: SELECT * FROM Funcionario. Analise o resultado, observando que h uma recursividade. 36 Usando a tabela Funcionrio, escreva uma QUERY que retorne Nome do Chefe, Nome do Funcionrio, ordenado pelo Nome do Chefe. 37 Usando as tabelas Pai, Filho e Notas, escreva um QUERY que retorne o Nome do Pai, Nome do Filho e as Notas do Filho. 38 Usando as tabelas Pai e Filho, escreva uma QUERY com SUBQUERY que retorne Os Nomes dos Filhos, onde o Nome do Pai possua a slaba o, na terceira posio. 39 - Usando as tabelas Pai e Filho, escreva uma QUERY com SUBQUERY que retorne os Nomes dos Filhos, onde o Nome do Pai contenha o sobrenome Sobrinho. 40 Usando as tabelas Filho e Notas, escreva uma QUERY com SUBQUERY que retorne os Nomes dos filhos que tenham notas maiores que 8. 41 Usando as tabelas Filho e Notas, escreva uma QUERY com SUBQUERY que retorne os Nomes dos filhos que NO tenham notas maiores que 8. 42 Execute a QUERY: INSERT INTO PAI VALUES ('5', 'seu nome', 'sua idade'). Descreva o resultado. 43 Execute a QUERY: INSERT INTO PAI VALUES ('seu nome', 'sua idade'). Analise o resultado. 44 Execute a QUERY: INSERT INTO PAI VALUES ('seu nome', sua idade). Analise o resultado.

98

45 Execute a QUERY: INSERT INTO PAI VALUES (seu nome, sua idade). Descreva o resultado. 46 Execute a QUERY: INSERT INTO PAI VALUES ([seu nome],sua idade). Descreva o resultado. 47 Execute a QUERY: INSERT INTO PAI VALUES ('seu nome'). Descreva o resultado. 48 Execute a QUERY: INSERT INTO PAI (Idade_pai, Nome_pai) VALUES (sua idade, seu nome). Descreva o resultado. 49 Execute a QUERY: INSERT INTO PAI (Idade_Pai, Nome_Pai) VALUES (sua idade,"seu nome"). Descreva o resultado. 50 Execute a QUERY: INSERT INTO PAI (Idade_Pai, Nome_Pai) VALUES (sua idade, [seu nome]). Descreva o resultado. 51 Execute a QUERY: INSERT INTO PAI (Idade_Pai, Nome_Pai) VALUES (sua idade, 'seu nome'). Analise o resultado. 52 Faa livremente DUAS QUERIES INSERT, utilizando qualquer tabela. Utilize INSERT POSICIONAL E DECLARATIVO. 53 Altere a tabela pai, colocando o nome Julio Cezar onde o Cdigo do Pai for igual a 7. 54 Altere a tabela pai colocando o sobrenome Ribeiro entre os dois nomes existentes, onde o cdigo do pai for igual a 4, sem alterar o nome todo, incluindo apenas o Ribeiro. 55 Altere a tabela pai colocando no final da cada nome a string: ** velho **, onde a idade for maior que 36. 56 Insira dois pais na tabela Pai e depois os exclua. 57 Crie um Banco de Dados Chamado Exercicioseu nome, utilizando o QUERY ANALYZER. Copie a resposta do QUERY ANALYZER e analise-a. 58 Crie uma Tabela no seu Banco Chamada Paisua idade, com trs colunas: Coluna Cod_Pai -> do tipo que suporte de 32768 a 32767, com autonumerao, no aceitando nulos e Constraint Chave Primria.

99

Coluna Nome_Pai -> do tipo de tamanho varivel que receba at 8000 caracteres, limitada a 30 e que no aceite nulos. Coluna Idade_Pai -> do tipo que aceite apenas nmeros de 0 a 255 e que aceite nulos.

59 Popule a tabela com pelo menos 5 linhas, usando o comando INSERT. 60 Adicione duas colunas ao mesmo tempo, utilizando o comando ALTER: Estado_Civil -> de contedo varivel com 10 bytes permitindo nulos Ativo -> de contedo fixo de 01 byte no permitindo nulos e valor padro 1.

61 Altere todos os dados da tabela, incluindo valores nos campos criados na ltima questo. 62 Altere a coluna Estado_Civil para um contedo varivel unicode, de tamanho 15 e que no permita nulos. 63 Utilizando o database SYSAMPLE: Crie uma VIEW que apresente o nome dos clientes, o salrio de cada um (totalizado com o salrio dos cnjuges daqueles que tiverem cnjuge) e o valor do maior crdito concedido a cada um. Crie uma VIEW que apresente o nome de todos os produtos vendidos em cada pedido. Crie uma VIEW que apresente o nome dos funcionrios e o total de bnus de cada um. Obs: Estude a funo ISNULL. 64 No database AVBP, a tabela Verso possui registros sobre as verses de vrios sistemas. Crie uma VIEW que mostre todos as colunas relativas a ltima verso de cada sistema.

100

You might also like