Apostila Linguagem SQL

64
1 Apostila de Linguagem SQL (2009) Focada em MS SQL SERVER 2005 Prof. Ms. Eduardo Rosalém Marcelino [email protected] Bibliografias utilizadas: ELMASRI, Ramez; NAVATHE, S.B., Sistemas de Bancos de Dados, 4º ed. São Paulo: Pearson, 2005. DATE, C.J. Introdução a Sistemas de Banco de Dados. 7 ed. São Paulo: Campus, 2000. MACHADO, Felipe N.R. Projeto de Banco de Dados – Uma visão prática. 9 ed. São Paulo: Érica, 2000. BATTISTI, Julio. SQL SERVER 2005 ADMINISTRAÇÃO & DESENVOLVIMENTO: CURSO COMPLETO. São Paulo: Axcel Books, 2005 MSDN, http://msdn.microsoft.com/pt-br/default.aspx BORGES, N.A., Curso Microsoft SQL SERVER 2000 – Utilizando a linguagem Transact-SQL. Centro Universitário Fundação Santo André.

Transcript of Apostila Linguagem SQL

  • 1

    Apostila de Linguagem SQL (2009)

    Focada em MS SQL SERVER 2005

    Prof. Ms. Eduardo Rosalm Marcelino [email protected]

    Bibliografias utilizadas: ELMASRI, Ramez; NAVATHE, S.B., Sistemas de Bancos de Dados, 4 ed. So Paulo: Pearson, 2005. DATE, C.J. Introduo a Sistemas de Banco de Dados. 7 ed. So Paulo: Campus, 2000. MACHADO, Felipe N.R. Projeto de Banco de Dados Uma viso prtica. 9 ed. So Paulo: rica, 2000. BATTISTI, Julio. SQL SERVER 2005 ADMINISTRAO & DESENVOLVIMENTO: CURSO COMPLETO. So Paulo: Axcel Books, 2005 MSDN, http://msdn.microsoft.com/pt-br/default.aspx BORGES, N.A., Curso Microsoft SQL SERVER 2000 Utilizando a linguagem Transact-SQL. Centro Universitrio Fundao Santo Andr.

  • 2 ndice: Histria e caractersticas da linguagem SQL ................................................................................................... 4 Tabelas utilizadas nos exemplos desta apostila:.............................................................................................. 5 CREATE DATABASE..................................................................................................................................... 6 Tipos de Dados........................................................................................................................................... 7 Create Table .............................................................................................................................................. 8 Instruo INSERT ....................................................................................................................................... 8 Instruo DELETE ....................................................................................................................................... 8 Instruo UPDATE ...................................................................................................................................... 8 Instruo SELECT ....................................................................................................................................... 9 ALIAS (Apelido) .........................................................................................................................................10 Clusula Where (Restries)........................................................................................................................11 BETWEEN (Condio com uma faixa de valores)............................................................................................11 LIKE (Comparao com uma parte de uma literal) .........................................................................................12 IN (Condio com valores fixos) ..................................................................................................................13 DISTINCT (Valores nicos) .........................................................................................................................13 TOP (limitando a quantidade de registros) ....................................................................................................14 Clusula ORDER BY....................................................................................................................................15 FUNES DE AGRUPAMENTO .....................................................................................................................16

    COUNT (Contador de registros) ...............................................................................................................16 SUM (Somatria de valores) ....................................................................................................................17 AVG (Mdia de valores) ..........................................................................................................................17 MIN, MAX (Menor e maior valor)..............................................................................................................18

    Clusula Group By......................................................................................................................................19 Clusula Having.........................................................................................................................................20 Exerccios..................................................................................................................................................21 JOINS (Junes) .......................................................................................................................................22

    INNER JOIN (juno interna)..................................................................................................................22 OUTER JOIN (juno externa) ................................................................................................................23 LEFT JOIN (juno externa esquerda)....................................................................................................23 RIGHT JOIN (juno externa direita) .....................................................................................................24 FULL OUTER JOIN (juno externa total) ..................................................................................................25 SELF JOIN (Auto Juno) ........................................................................................................................26

    Clusula Union ..........................................................................................................................................27 CAST e CONVERT .....................................................................................................................................29 Subconsultas (Subqueries ou Consultas Encadeadas) .....................................................................................30

    EX. 1: Utilizando um subconsulta para retornar um campo adicional: .......................................................30 EX. 2: Utilizando um subconsulta para restringir os registros retornados...................................................31 EX. 3: Aplicao da Clusula TOP e Operadores In e Not In em subconsultas..........................................32

    Vises (Views) ...........................................................................................................................................33 Principais estruturas do Transact-SQL ..........................................................................................................36

    BEGIN...END (Transact-SQL) ...................................................................................................................36 IF...ELSE (Transact-SQL) ........................................................................................................................36 WHILE (Transact-SQL) ...........................................................................................................................36 CASE (Transact-SQL)..............................................................................................................................37

    Stored Procedures (Procedimentos Armazenados) ........................................................................................39 Parmetros de Entrada e Sada................................................................................................................43 SPs que acessam dados do banco ..........................................................................................................43

    Tabelas temporrias...................................................................................................................................44 Triggers (Gatilhos) .....................................................................................................................................46

    TRIGGER INSERT...................................................................................................................................48 TRIGGER DELETE ..................................................................................................................................48 TRIGGER UPDATE..................................................................................................................................49 Habilitando e Desabilitando Triggers ........................................................................................................50

    Cursores (Transact-SQL).............................................................................................................................51 FETCH (Transact-SQL)............................................................................................................................53 @@FETCH_STATUS (Transact-SQL).........................................................................................................53 Exemplos ..............................................................................................................................................54

    Funes definidas pelo usurio (FUNCTIONS) ...............................................................................................57 Benefcios da funo definida pelo usurio ............................................................................................57 Componentes de uma funo definida pelo usurio ................................................................................57

  • 3 Exemplo de valor escalar: ...................................................................................................................58 Exemplo de valor de tabela: ................................................................................................................58

    Controle de Transao................................................................................................................................60 Controle de exceo ( TRY...CATCH ) ...........................................................................................................61

    Recuperando informaes de erro........................................................................................................63 Usando TRYCATCH em uma transao...............................................................................................64

  • 4

    Histria e caractersticas da linguagem SQL Fonte: http://sweet.ua.pt/~a35438/Outros/SQL.htm A histria do SQL comea em 1970 com a publicao por E. F. Codd, no ACM Journal, de um artigo intitulado A Relational Model of Data for Large Shared Data Banks. O modelo proposto por Codd hoje considerado a base de trabalho para qualquer Sistema Gerenciador de Base de Dados Relacional (SGBDR). A primeira implementao da linguagem SEQUEL foi realizada pela IBM e tinha por objectivo a implementao do modelo de Codd. A evoluo desta linguagem veio a dar origem ao SQL. A primeira implementao comercial de SQL foi realizada pela Relational Software, Inc., hoje conhecida por Oracle Corporation. Nos dias de hoje, a linguagem SQL considerada um standard dos Sistemas de Gesto de Base de Dados Relacionais (SGBDR); por isso, todos os fabricantes a integram nos seu produtos. A linguagem SQL pertence 4 Gerao das Linguagens de Programao. No , no entanto, uma evoluo das linguagens de 3 Gerao (Pascal, BASIC, C, COBOL, FORTRAN), j que estas tm caractersticas bem diferentes:

    Existncia de Variveis, vectores, ...; Existncia de instrues condicionais (if, switch, case, ...); Existncia de ciclos (for, while, do...while, repeat...until); Possibilidade de escrita de funes e procedimentos;

    Nenhuma destas caractersticas existe no SQL, havendo maior ligao entre a 3 e 5 geraes de linguagens de programao do que com a 4. A linguagem SQL destina-se, por isso e pela sua simplicidade, no s a informticos, como tambm a gestores, utilizadores, administradores de bases de dados, etc.. No entanto, a sua principal diferena em relao s linguagens de 3 gerao a ausncia nestas de um objetivo pr-definido, coisa que no SQL est bem determinado: proporcionar a interface entre o SGBDR e o usurio, atravs da manipulao de dados. A linguagem SQL implementa os conceitos definidos no modelo relacional, reduzindo assim as incompatibilidades entre os sistemas e evitando a opo por arquitecturas proprietrias que implicam maiores custos de desenvolvimento e maior esforo financeiro e humano por parte dos desenvolvedores. Com a linguagem SQL possvel:

    Criar, alterar e remover todos os componentes de uma base de dados, como tabelas, ndices, views, etc.; Inserir, alterar e apagar dados; Interrogar a base de dados; Controlar o acesso dos usurios base de dados, e s operaes a que cada um deles tem acesso; Obter a garantia da consistncia e integridade dos dados;

    A linguagem SQL composta por vrios conjuntos de comandos, como por exemplo: DDL (Data Definition Language): comandos para definir ou modificar a composio das tabelas, apagar tabelas, criar ndices, definir views, especificar direitos de acesso a tabelas e views; DML (interactive Data Manipulation Language): inclui uma linguagem de consulta baseada em lgebra relacional e em clculo relacional sobre registos; inclui tambm comandos para inserir, apagar e modificar registos na base de dados; A linguagem de SQL inclui ainda a capacidade de verificao de integridade dos dados, bem como comandos para especificao do princpio e fim de transaces; algumas implementaes permitem o impedimento explcito de acesso aos dados, para controle de acesso concorrencial.

  • 5

    Tabelas utilizadas nos exemplos desta apostila: select * from funcionarios

    Select * From setores

  • 6

    CREATE DATABASE Cria um novo banco de dados e os arquivos usados para armazen-lo.Cada banco de dados tem um proprietrio que pode executar atividades especiais no banco de dados. O proprietrio o usurio que cria o banco de dados. O proprietrio do banco de dados pode ser alterado usando sp_changedbowner. Cada banco de dados tem no mnimo dois arquivos, um arquivo primrio e um arquivo de log de transaes. Ex 1: Criando um banco de dados sem especificar os arquivos: Obs: neste caso, o banco de dados ser salvo na pasta padro do SQL Server. create database DBLocadora -- cria o banco de dados Ex 2: Verificando a existncia do banco antes de cri-lo. Caso ele exista, o banco ser apagado. use master -- vai para a banco de dados principal do sql server (master) IF DB_ID ('DBLocadora') IS NOT NULL -- verifica se o banco de dados j existe DROP DATABASE DBLocadora -- se j existir, apaga create database DBLocadora -- cria o banco de dados Ex 3: Complementando o exemplo anterior, agora vamos especificar onde o arquivo de dados e o arquivo de Log sero salvos. use master -- vai para a banco de dados principal do sql server IF DB_ID ('DBLocadora') IS NOT NULL -- verifica se o banco de dados j existe DROP DATABASE DBLocadora -- se j existir, apaga create database DBLocadora -- cria o banco de dados ON ( NAME = dbLocadora_dados,FILENAME = 'd:\BD\dbLocadora_dados.mdf') LOG ON ( NAME = dbLocadora_Log, FILENAME = 'd:\BD\dbLocadora_Log.ldf')

  • 7

    Tipos de Dados Os principais tipos de dados do SQL Server so:

    Outros tipos suportados so: Money, Cursor, Variant (normalmente utilizado na Automao OLE), Table, capaz de armazenar um conjunto de resultados, rowversion (timestamp) e GUID (uniqueidentifier). O tipo sysname utilizado para armazenar nomes de objetos, como tabelas, colunas etc.

  • 8

    Create Table Permite criar uma nova tabela no banco de dados. Este comando possui diversas opes, portanto, ser apresentada a sua verso mais simples. Para maiores detalhes, consulte o MSDN. Ex 1: Cria uma tabela chamada fitas no banco de dados dbLocadora, definindo inclusive a chave primria. use dbLocadora GO create table fitas ( codigo int primary key, descricao varchar(20), data_cadastro datetime, valor decimal(10,2) NOT NULL ) Ex 2: Criando uma tabela locacao_item com uma chave primria formada por 2 campos. create table locacao_item ( locacao_id int NOT NULL, fita_cod int NOT NULL, valor decimal (10, 2) NULL default 0, CONSTRAINT PK_locacao_item PRIMARY KEY ( locacao_id, fita_cod ) )

    Instruo INSERT Insere um registro em uma tabela. Sintaxe: insert into TABELA (campo1, campo2, campoN) values (valor1, valor2, valorN)

    Instruo DELETE Apaga ou mais registros em uma tabela. Sintaxe: Delete from tabela where condio Obs: a clusula where opcional, porm se no for utilizado, TODOS OS REGISTROS DA TABELA SERO APAGADOS!!!!

    Instruo UPDATE Altera um ou mais registros em uma tabela.

  • 9 Sintaxe: Update TABELA Set campo1 = valor1, campo2 = valor2, campoN = valorN WHERE condio Obs: a clusula where opcional, porm se no for utilizado, TODOS OS REGISTROS DA TABELA SERO ALTERADOS!!!!

    Instruo SELECT Instrui o programa principal do banco de dados para retornar a informao como um conjunto de registros. Sintaxe SELECT [predicado { * | tabela.* | [tabela.]campo1 [AS alias1] [, [tabela.]campo2 [AS alias2] [, ...]]} FROM expressotabela WHERE condio GROUP BY campo(s) HAVING condio ORDER BY campo(s) A parte em azul opcional. A instruo SELECT em detalhes: Parte Descrio predicado Um dos seguintes predicados: DISTINCTou TOP.

    Voc usa o predicado para restringir o nmero de registros que retornam. * Especifica que todos os campos da tabela ou tabelas especificadas sero

    selecionados. tabela O nome da tabela que contm os campos dos quais os registros so selecionados. campo1, campo2 Os nomes dos campos dos quais os dados sero recuperados. Se voc incluir mais

    de um campo, eles sero recuperados na ordem listada. alias1, alias2 Os nomes que sero usados como ttulos de colunas em vez dos nomes originais das

    colunas na tabela. expressotabela Tabela(s), subselect(s), etc.. contendo os dados que voc deseja recuperar. Para executar esta operao, o programa principal de banco de dados procura a tabela ou tabelas especificadas, extrai as colunas escolhidas, seleciona as linhas que satisfazem o critrio e classifica ou agrupa as linhas resultantes na ordem especificada.

    A instruo SELECT no muda os dados no banco de dados. SELECT normalmente a primeira palavra em uma instruo SQL. A maior parte das instrues SQL so instrues SELECT. A sintaxe mnima da instruo SELECT : Select Campo(s) From Tabela Voc pode usar um asterisco (*) para selecionar todos os campos na tabela. O exemplo abaixo seleciona todos os campos na tabela Funcionarios:

  • 10 SELECT * FROM Funcionarios Se o nome de um campo estiver includo em mais de uma tabela utilizada na instruo SQL, preceda-o com o nome da tabela e o operador . (ponto). Veja o exemplo abaixo: O campo setor_id existe nas duas tabelas utilizadas na instruo SQL, portanto devemos indicar tambm a tabela, precedendo o nome do campo. Select funcionarios.func_nome, setores.setor_nome From funcionarios Inner join setores on setores.setor_id = funcionarios.setor_id

    ALIAS (Apelido) Literal que identifica um campo, uma funo ou uma tabela Sintaxe: SELECT ( ou ou ) FROM Exemplo: Select func_id as "Cdigo do Funcionrio" From funcionarios Observe que a coluna func_id passou a chamar [Cdigo do Funcionrio]. Observe o exemplo abaixo: Select func_salario * 1.10 From funcionarios where func_nome like '%b%'

    Observe no resultado da instruo acima que a coluna resultante da operao aritmtica est aparecendo como No column name. Para resolver este problema, devemos criar uma alias para o campo resultado, como na instruo abaixo: Select func_salario * 1.10 as "Novo Salrio" From funcionarios where func_nome like '%b%'

    A palavra as opcional. As aspas () s so necessrias caso a palavra seja composta, ou com caracteres especiais. Tambm pode ser utilizado [] ou apstrofo ().

  • 11

    Clusula Where (Restries) Com esta clusula possvel fazermos restrio dos registros a serem manipulados, como veremos posteriormente ela tambm poder ser usados para outros comandos do SQL. Sintaxe: SELECT FROM WHERE Exemplo: Select func_salario * 1.10 as "Novo Salrio" From funcionarios where func_salario >= 5000

    Principais operadores utilizados Operador Significado = Igual > Maior < Menor >= Maior ou igual = e

  • 12

    LIKE (Comparao com uma parte de uma literal) O operador LIKE faz a comparao somente com uma parte de uma literal, desconsidera tudo que possa vir antes ou depois do valor passado. Os caracteres % e _ significam qual parte a ser desconsiderada. Sintaxe: SELECT FROM WHERE LIKE Principais curingas para o operador Like: Curinga Descrio Exemplo % Qualquer cadeia de zero ou

    mais caracteres.

    WHERE title LIKE '%computer%' localiza todos os ttulos de livro com a palavra 'computer' em qualquer lugar no ttulo do livro.

    _ (sublinhado) Qualquer caractere nico.

    WHERE au_fname LIKE '_ean' localiza todos os nomes de quatro letras que terminam com ean (Dean, Sean e assim por diante).

    Exemplos: Retorna todos os funcionrios que iniciam com a letra a Select func_nome From funcionarios where func_nome like 'a%'

    Retorna todos os funcionrios que terminam com a letra a Select func_nome From funcionarios where func_nome like '%a'

    Retorna todos os funcionrios que contm a letra b em qualquer parte do nome Select func_nome From funcionarios where func_nome like '%b%'

    Retorna todos os registros que possuam um nome que inicie com Brun, podendo variar apenas a ltima letra. Select func_nome From funcionarios where func_nome like 'Brun_'

  • 13

    IN (Condio com valores fixos) O operador IN determina os valores fixos aceitos de uma pesquisa. Sintaxe: SELECT FROM WHERE IN () Exemplo: select * from funcionarios where func_id in (1,5,9)

    A instruo acima poderia ser feita utilizando-se o operador OR. Veja o cdigo a seguir: select * from funcionarios where func_id = 1 or func_id = 5 or func_id =9 O operador NOT antecedendo o operador IN traz todos os registros que no estejam no conjunto especificado.

    DISTINCT (Valores nicos) O operador DISTINCT elimina todas as replicaes, significando que somente dados distintos sero apresentados como resultado de uma pesquisa. Sintaxe: SELECT DISTINCT FROM Exemplo: A instruo abaixo ir retornar apenas os setores da tabela funcionrios, porm apenas uma ocorrncia de cada. Observe o valor NULL. O operador distinct tambm o considera um valor nico. select distinct setor_id from funcionarios

  • 14

    TOP (limitando a quantidade de registros) Indica que somente um primeiro conjunto ou porcentagem de linhas especificado ser retornado de um conjunto de resultados de consulta. Sintaxe: Select TOP ( expression ) [ PERCENT ] * from Tabela Onde expression pode ser um nmero ou uma porcentagem de linhas. Se a consulta incluir uma clusula ORDER BY, sero retornadas as primeiras linhas expression, ou porcentagem de linhas expression, solicitadas pela clusula ORDER BY. Exemplos: A instruo abaixo ir retornar apenas os 5 primeiros registros, obedecendo a ordenao solicitada. select top 5 * from funcionarios order by func_salario desc

    A instruo abaixo ir retornar apenas os 10% primeiros registros, obedecendo a ordenao solicitada. select top 10 percent * from funcionarios order by func_salario desc

  • 15

    Clusula ORDER BY ORDER BY opcional. Entretanto, se voc quiser exibir seus dados na ordem classificada, voc deve utilizar ORDER BY. O padro ordem de classificao ascendente (A a Z, 0 a 9). Exemplo: select * from setores order by setor_nome --ou select * from setores order by setor_nome asc

    Para classificar em ordem descendente (Z a A, 9 a 0), adicione a palavra reservada DESC ao final de cada campo que voc quiser classificar em ordem descendente. Exemplo: select * from setores order by setor_nome desc

    ORDER BY normalmente o ltimo item em uma instruo SQL. Voc pode incluir campos adicionais na clusula ORDER BY. Os registros so classificados primeiro pelo primeiro campo listado depois de ORDER BY. Os registros que tiverem valores iguais naquele campo so classificados pelo valor no segundo campo listado e assim por diante.

  • 16 Exemplo: select setor_id, func_nome from funcionarios order by setor_id, func_nome

    FUNES DE AGRUPAMENTO

    COUNT (CONTAR) SUM (SOMAR) AVG (MDIA) MAX (MXIMO) MIN (MNIMO)

    COUNT (Contador de registros) A funo COUNT retorna a quantidade de registros correspondentes a uma pesquisa. Sintaxe: SELECT COUNT([distinct] campo ou * ) FROM Exemplos: Retornar a quantidade de registros na tabela funcionarios: select count(*) from funcionarios

  • 17 Retornar a quantidade de setores informados na tabela funcionarios: select count(setor_id) from funcionarios

    Retornar a quantidade de setores informados na tabela funcionarios, porm sem contar as repeties. select count( distinct setor_id ) from funcionarios

    SUM (Somatria de valores) A funo SUM faz a somatria dos valores de um campo. Sintaxe: SELECT SUM() FROM Exemplo: Soma de todos os funcionrios cadastrados select sum( func_salario ) as "Soma dos Salrios" from funcionarios

    AVG (Mdia de valores) A funo AVG faz a mdia dos valores de um campo. Sintaxe: SELECT AVG() FROM Exemplo: Mdia salarial dos funcinrios cadastrados: select avg( func_salario ) as "Mdia salarial" from funcionarios

    O resultado acima tambm pode ser conseguido com a instruo abaixo: select sum( func_salario ) / count(*) as "Mdia salarial" from funcionarios

  • 18 MIN, MAX (Menor e maior valor) As funes MIN e MAX retornam respectivamente o menor e o maior valor encontrado para um campo. Sintaxe: SELECT MIN() FROM SELECT MAX() FROM Exemplo Retornando o menor e o maior salrio dos funcionrios cadastrados select min( func_salario ) as "Menor salrio" , max(func_salario ) as "Maior Salrio" from funcionarios

  • 19

    Clusula Group By Esta clusula agrupa um conjunto de linhas selecionadas em um conjunto de linhas de resumo pelos valores de uma ou mais colunas ou expresses. Uma linha retornada para cada grupo. Funes de agregao na lista de da clusula SELECT fornecem informaes sobre cada grupo em vez de linhas individuais. Expresses na clusula GROUP BY podem conter colunas de tabelas, exibies ou tabelas derivadas na clusula FROM. No exigido que as colunas apaream na lista de da clusula SELECT. Cada coluna de tabela ou exibio em qualquer expresso de no agregao na lista de deve estar includa na lista GROUP BY: As seguintes instrues so permitidas:

    SELECT ColumnA, ColumnB FROM T GROUP BY ColumnA, ColumnB SELECT ColumnA + ColumnB FROM T GROUP BY ColumnA, ColumnB SELECT ColumnA + ColumnB FROM T GROUP BY ColumnA + ColumnB SELECT ColumnA + ColumnB + constant FROM T GROUP BY ColumnA, ColumnB

    As seguintes instrues NO so permitidas:

    SELECT ColumnA, ColumnB FROM T GROUP BY ColumnA + ColumnB SELECT ColumnA + constant + ColumnB FROM T GROUP BY ColumnA + ColumnB.

    Detalhes sobre Group By:

    Se funes de agregao forem includas na da clusula SELECT, GROUP BY calcular um valor resumido para cada grupo. So conhecidas como agregaes de vetor.

    Linhas que no atendem s condies na clusula WHERE so removidas antes que qualquer operao de agrupamento seja executada.

    A clusula HAVING usada com a clusula GROUP BY para filtrar grupos no conjunto de resultados. A clusula GROUP BY no ordena o conjunto de resultados. Use a clusula ORDER BY para ordenar o

    conjunto de resultados. Se uma coluna de agrupamento contiver valores nulos, todos os valores nulos sero considerados iguais e

    colocados em um nico grupo. No possvel usar GROUP BY com um alias para substituir um nome de coluna na clusula AS, a menos

    que o alias substitua um nome de coluna em uma tabela derivada na clusula FROM. GROUP BY ou HAVING no podem ser usados diretamente em colunas de ntext, text ou image. Essas

    colunas podem ser usadas como argumentos em funes que retornam um valor de outro tipo de dados, como SUBSTRING() e CAST().

    No utitilize SELECT *. Especifique os campos j que depois voc dever especific-los na clusula Group by.

    Exemplo: Selecionar a quantidade de funcionrios por setor select setor_id, count(*) as "Total de funcionrios no setor" from funcionarios where setor_id is not null group by setor_id

  • 20

    Clusula Having

    A clusula HAVING define condies na clusula GROUP BY semelhante ao modo que WHERE interage com SELECT. O critrio de pesquisa WHERE aplicado antes da execuo da operao de agrupamento; o critrio de pesquisa HAVING aplicado depois que a operao de agrupamento executada. A sintaxe HAVING semelhante sintaxe WHERE, exceto se HAVING contiver funes de agregao. Clusulas HAVING podem consultar quaisquer dos itens que aparecem na lista de seleo. Compreendendo a seqncia correta onde as clusulas WHERE, GROUP BY e HAVING so aplicadas, ajuda a codificar consultas eficientes:

    A clusula WHERE usada para filtrar as linhas que resultam das operaes especificadas na clusula FROM.

    A clusula GROUP BY usada para agrupar o resultado da clusula WHERE. A clusula HAVING usada para filtrar linhas do resultado agrupado.

    Para qualquer critrio de pesquisa que poderia ser aplicado antes ou depois da operao de agrupamento, mais eficiente especific-los na clusula WHERE. Isto reduz o nmero de linhas que precisam ser agrupadas. Os nicos critrios de pesquisa que deveriam ser especificados na clusula HAVING so os critrios de pesquisa que devem ser aplicados depois da operao de agrupamento ser executada. Quando possvel, coloque todos os critrios de pesquisa na clusula WHERE em vez de na clusula HAVING. Exemplo: select setor_id, count(*) as "Total de funcionrios no setor" from funcionarios where setor_id is not null group by setor_id having count(*) > 4

  • 21

    Exerccios 1-) Selecione o maior e o menor cdigo de funcionrio. 2-) Selecione a mdia salarial 3-) Selecione todos os campos apenas dos 5 primeiros funcionrios ordenados por ordem decrescente de salrio 4-) Selecione todos os setores que terminam com a letra a. 5-) Selecione o setor_id da tabela funcionrios, de forma distinta . 6-) Selecione a mdia salarial dos funcionrios que so gerentes. 7-) Selecione o cdigo do gerente e a quantidade de funcionrios que trabalham para ele. 8-) Selecione todos os funcionrios que nasceram antes de 1974 e que ganham mais de 4000,00 OU aqueles que trabalham no setor 1 e que ganham mais de 1000,00.

  • 22

    JOINS (Junes) Para que possamos recuperar informaes de um banco de dados, temos, muitas vezes, a necessidade de acessar simultaneamente vrias tabelas relacionadas entre si. Algumas dessas consultas necessitam realizar uma juno (Join) entre tabelas, para poder extrair dessa juno as informaes necessrias para a consulta formulada. Uma clusula SQL combina registro de duas uma ou mais tabelas. Ela cria um conjunto que pode ser salvo como uma tabela ou utilizada de outra forma. Um JOIN um meio de combinar campos de duas tabelas utilizando-se valores em comum O padro SQL ANSI especifica 4 tipos de Joins: Inner, Outer, Left e Right. Em casos especiais, uma tabela pode fazer JOIN consigo mesma, chamado self-join.

    INNER JOIN (juno interna) O tipo default de juno de uma tabela a juno interna (inner join), na qual uma tupla inclusa no resultado somente se existir uma tupla que combine na outra relao. Por exemplo, na consulta abaixo, somente os empregados que possuem um setor vlido na tabela de SETORES sero inclusos no resultado. Uma tupla FUNCIONARIOS que possua no campo setor_id um valor NULL ou mesmo um cdigo de setor que no exista na tabela setores no ser includa no resultado final. Ex: select funcionarios.*, setores.setor_nome from funcionarios Inner join setores on funcionarios.setor_id = setores.setor_id

    SQL permite duas formas diferentes de expressar JOINS. A primeira, chamada de notao join explcita usa a palavra chave JOIN. A segunda, chamada de notao join implcita lista as tabelas para a juno na clusula FROM, separando as tabelas por vrgula. O exemplo abaixo reproduz o mesmo resultado do exemplo apresentado acima. select funcionarios.*, setores.setor_nome from funcionarios, setores where funcionarios.setor_id = setores.setor_id

  • 23 OUTER JOIN (juno externa) Dada 2 tabelas relacionadas R e S, um conjunto de operaes, chamado junes externas (outer joins), pode ser utilizado quando queremos manter todas as tuplas em R, ou todas as tuplas em S, ou todas aquelas em ambas as relaes no resultado da juno, independentemente se elas tm ou no tuplas correspondentes na outra relao. Isso satisfaz a necessidade de consultas nas quais as tuplas de duas tabelas so combinadas pelo casamento de linhas correspondentes, mas sem a perda de qualquer tupla por falta de valores casados.

    LEFT JOIN (juno externa esquerda) Este caso de outer join mantm toda tupla na primeira relao ou na relao R esquerda. Se nenhuma tupla correspondente encontrada em S, ento os atributos de S no resultado da juno sero preenchidos ou enchidos com valores NULL. O resultado dessas operaes e mostrado no exemplo abaixo. select funcionarios.*, setores.setor_nome from funcionarios LEFT OUTER join setores on funcionarios.setor_id = setores.setor_id -- a palavra OUTER opcional! --Ou em SQL Server select funcionarios.*, setores.setor_nome from funcionarios, setores where funcionarios.setor_id *= setores.setor_id

    No exemplo acima, a tabela considerada primeira relao a tabela que est no FROM, ou seja, a tabela FUNCIONARIOS. Como foi utilizado o LEFT OUTER JOIN (OUTER pode ser omitido), foram retornadas todas as tuplas da tabela FUNCIONRIOS, mesmo que o campo Setor_id seja NULL ou no haja um valor correspondente na tabela SETORES.

    Registros que no possuem um valor correspondente na tabela SETORES.

  • 24

    RIGHT JOIN (juno externa direita) Este caso de outer join mantm todas as tuplas na segunda relao, ou relao S direita, no resultado final. Veja o exemplo abaixo. select funcionarios.*, setores.setor_nome from funcionarios RIGHT OUTER join setores on funcionarios.setor_id = setores.setor_id -- a palavra OUTER opcional! -- ou em SQL SERVER: select funcionarios.*, setores.setor_nome from funcionarios, setores where funcionarios.setor_id =* setores.setor_id

    Neste caso, foram retornados todos os registros da tabela SETORES, mesmo que no haja um correspondente na tabela FUNCIONARIOS.

    Registros da tabela SETORES que no possuem um valor correspondente na tabela FUNCIONARIOS.

  • 25

    FULL OUTER JOIN (juno externa total) Este outro caso de outer join, onde so mantidas todas as tuplas em ambas as relaes, esquerda e direita, quando no so encontradas as tuplas com os valores casados, preenchendo-as com valores NULL conforme a necessidade. select funcionarios.*, setores.setor_nome from funcionarios FULL OUTER join setores on funcionarios.setor_id = setores.setor_id -- a palavra OUTER opcional!

    Todos os registros das duas tabelas foram retornados. Quando houve correspondncia (os registros no marcados pelo retngulo vermelho) o SQL retornou os dados relacionados. Quando no houve correspondncia (retngulo vermelho), os campos foram preenchidos com NULL no resultado.

  • 26

    SELF JOIN (Auto Juno) Self Join um tipo de juno onde feito um JOIN de uma tabela com ela mesma. Veja o exemplo abaixo: Vamos listar todos os funcionrios com seus respectivos gerentes. No h a tabela GERENTES, pois os gerentes tambm esto cadastrados na tabela FUNCIONARIOS. O que define um gerente de um funcionrio o preenchimento do cdigo do funcionrio no campo gerente_id. Vejamos como resolver este problema: select funcionarios.*, Gerentes.func_nome as "Gerente_Nome" from funcionarios Inner join funcionarios as "gerentes" on gerentes.func_id = funcionarios.gerente_id -- a palavra reservada as opcional, assim como as aspas ()

    Como estamos trabalhando com duas tabelas de mesmo nome, precisamos da um apelido, um alias para uma das tabelas. Fizemos isso com a tabela utilizada no Inner Join, chamando-a de GERENTES. Tambm demos um apelido para o campo resultante do nome do funcionrio que representa o gerente: gerente_nome. Na expresso SQL acima, GERENTES chamado de alias (apelido). Um apelido representa a mesma tabela a qual est referenciando. Um alias muito importante quando h redundncia nos nomes das colunas de duas ou mais tabelas que esto envolvidas em uma expresso. Ao invs de utilizar o alias, possvel utilizar o nome da tabela, mas isto pode ficar cansativo em consultas muito complexas alm do que, impossibilitaria a utilizao da mesma tabela mais que uma vez em uma expresso SQL, como no exemplo acima.

  • 27

    Clusula Union Combina os resultados de duas ou mais consultas em um nico conjunto de resultados, que inclui todas as linhas pertencentes a todas as consultas da unio. A operao UNION diferente de usar junes que combinam colunas de duas tabelas. A seguir so apresentadas as regras bsicas de combinao dos conjuntos de resultados de duas consultas usando UNION:

    O nmero e a ordem das colunas devem ser iguais em todas as consultas. Os tipos de dados devem ser compatveis.

    Caso seja necessrio ordenar os dados, deve-se ordenar pelos campos indicados na primeira instruo SQL. Caso seja usado um alias, este dever ser utilizado na ordenao. Ex: select funcionarios.func_id as "codigo", funcionarios.func_nome as "nome" from funcionarios where funcionarios.func_nome like 'A%' union select setores.setor_id , setores.setor_nome from setores

  • 28 A clusula ALL (em frente a clusula Union) incorpora todas as linhas nos resultados. Isto inclui duplicatas. Se no for especificado, as linhas duplicadas sero removidas. Sem a clusula ALL select funcionarios.func_id as "codigo", funcionarios.func_nome as "nome" from funcionarios where funcionarios.func_nome like 'A%' union select funcionarios.func_id as "codigo", funcionarios.func_nome as "nome" from funcionarios where funcionarios.func_nome like 'A%'

    Com a clusula ALL select funcionarios.func_id as "codigo", funcionarios.func_nome as "nome" from funcionarios where funcionarios.func_nome like 'A%' union all select funcionarios.func_id as "codigo", funcionarios.func_nome as "nome" from funcionarios where funcionarios.func_nome like 'A%'

  • 29

    CAST e CONVERT Esta funo converte uma expresso de um tipo de dados para outro. Obs: H tambm a funo CONVERT, que possui algumas funcionalidades especiais para o tipo de dados datetime. Sintaxe:

    CAST ( expression AS data_type [ (length ) ]) CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

    Onde: expression : qualquer expresso vlida. data_type : o tipo de dados de designado. length : um inteiro opcional que especifica o comprimento do tipo de dados designado. O valor padro 30. style : uma expresso de inteiro que especifica como a funo CONVERT deve ser convertida para expression. Ex: Concatenando valores: select '1' + '1'

    Ex: convertendo valores e efetuando uma soma select cast('1' as int) + cast( '1' as int)

    Ex. da funo Convert: --103 British/French dd/mm/yy select convert(varchar, getdate(), 103)

    Ex. Retornando apenas o ano com a funo substring: -- SUBSTRING ( expression ,start , length ) select substring( convert(varchar, getdate(), 103), 7,4)

    Ex: O resultado acima poderia ser executado tambm de outra forma: select year( getdate() ) -- h tambm as funes day e month, alm da funo DATEPART ( poro , data )

  • 30

    Subconsultas (Subqueries ou Consultas Encadeadas) Uma subconsulta uma consulta aninhada em uma instruo SELECT, INSERT, UPDATE ou DELETE, ou em subconsulta. Uma subconsulta pode ser usada em qualquer lugar em que permitida uma expresso,exceto na clusula ORDER BY. Neste exemplo, uma subconsulta usada como uma expresso de coluna denominada MaxUnitPrice em uma instruo SELECT. Uma subconsulta tambm chamada de uma consulta interna ou seleo interna, enquanto a instruo que contm uma subconsulta tambm chamada de uma consulta externa ou seleo externa. Na maioria das vezes, h uma juno entre a consulta interna e a consulta externa. Muitas instrues Transact-SQL que incluem subconsultas podem ser alternativamente formuladas como junes. Outras perguntas s podem ser feitas com subconsultas. Em Transact-SQL, normalmente no h nenhuma diferena de desempenho entre uma instruo que inclui uma subconsulta e uma verso equivalente semanticamente que no inclui. Entretanto, em alguns casos em que a existncia deve ser verificada, uma juno tem um desempenho melhor. Em outros casos, a consulta aninhada deve ser processada para cada resultado da consulta externa para assegurar a eliminao de duplicatas. Em tais casos, uma abordagem de juno geraria resultados melhores.

    (A consulta SELECT de uma subconsulta sempre inclusa em parnteses.)

    EX. 1: Utilizando um subconsulta para retornar um campo adicional:

    Este tipo de subconsulta s pode retornar 1 registro e 1 coluna. No exemplo abaixo, sero retornados todos os funcionrios e seus respectivos gerentes. Este mesmo exemplo foi utilizado para explicar SELFJOIN, porm utilizando JOIN no lugar de subconsulta. select funcionarios.*, (select Gerentes.func_nome from funcionarios as "Gerentes" where gerentes.func_id = funcionarios.gerente_id) as "Gerente_Nome" from funcionarios where gerente_id is not null

    Observe que para cada registro da tabela externa FUNCIONARIOS, o SQL ir fazer uma subconsulta na tabela GERENTES para pesquisar o nome do mesmo.

  • 31 No exemplo abaixo, iremos retornar os setores e a sua quantidade de funcionrios. select setores.*, (select count(*) from funcionarios where funcionarios.setor_id = setores.setor_id) as "Total de Funcionrios" from setores -- poderamos substituir as por []

    EX. 2: Utilizando um subconsulta para restringir os registros retornados Podemos utilizar uma subconsulta para restringir os registros que so retornados para o resultado final. O resultado de uma subconsulta apresentada com IN (ou com NOT IN) uma lista com zeros ou outros valores. Depois dos resultados da subconsulta retornarem, a consulta exterior os utiliza. Ex: No exemplo a seguir, iremos retornar os setores e a sua quantidade de funcionrios, porm, diferentemente do exemplo anterior, iremos retornar apenas aqueles que possurem ao menos 1 funcionrio. Obs: H vrias outras formas de se resolver este problema. select setores.*, (select count(*) from funcionarios where funcionarios.setor_id = setores.setor_id) as "Total de Funcionrios" from setores where (select count(*) from funcionarios where funcionarios.setor_id = setores.setor_id) > 0 --ou select setores.*, (select count(*) from funcionarios where funcionarios.setor_id = setores.setor_id) as "Total de Funcionrios" from setores where exists(select func_id from funcionarios where funcionarios.setor_id = setores.setor_id)

  • 32

    EX. 3: Aplicao da Clusula TOP e Operadores In e Not In em subconsultas O operador TOP (qtde) (SQL SERVER) limita a quantidade de registros retornada pela instruo SQL. Ex: Se executarmos a instruo SQL:

    Select TOP 1 * from setores Apenas 1 registro (tupla) ir retornar. Podemos utiliz-lo com quaisquer outras clusulas, como Order by, Where, etc. Esta clusula interessante quando sabemos exatamente a quantidade de registros que precisamos, evitando o processamento de informaes desnecessrias. Os operador IN (aqui ele tem o sentido de est contido) um operador de conjunto. Podemos utilizado, por exemplo, para selecionar os funcionrios que pertenam a um dos setores: 1, 2, 5 ou 7. A sintaxe ficaria assim:

    Select * from funcionarios where setor_id IN (1,2,5,7)

    Da mesma forma, se quisermos todos os funcionrios que NO pertenam aos setores 1, 2, 5 ou 7, basta introduzir o operador NOT na sintaxe anterior:

    Select * from funcionarios

    where setor_id NOT IN (1,2,5,7) Observe que o operador IN opera sobre um conjunto de dados. E esse conjunto pode ser proveniente do resultado de uma subconsulta, desde que ela retorne apenas 1 coluna (campo). Ex: Novamente, vamos retornar apenas os setores que possuem, ao menos, 1 funcionrio. Select * from setores where setor_id in (select funcionarios.setor_id from funcionarios where funcionarios.setor_id = setores.setor_id) /* para melhorar o desempenho, podemos utilizar o operador TOP, pois nos interessa saber se h pelo menos 1 funcionrio no setor, no sendo necessrio retornar todas as tuplas da subconsulta! */ Select * from setores where setor_id in (select TOP 1 funcionarios.setor_id from funcionarios where funcionarios.setor_id = setores.setor_id)

    O resultado acima pode ser obtido sem a utilizao de subconsultas, utilizando-se a clusula DISTINCT.

  • 33

    Vises (Views) View uma instruo que retorna dados e salva no banco de dados com um nome, ou seja, passa a ser um objeto do banco de dados. Quando uma view executada, esta retorna um conjunto de dados no formato de uma tabela. Uma view pode retornar dados de uma ou mais tabelas. As principais vantagens na utilizao de views so:

    Ocultar a complexidade do acesso a dados, criando uma view que consolida o acesso a vrias tabelas; Simplificar a atribuio de permisses, uma vez que uma view pode ser pressionada de forma mais simples

    do que se fossem pressionadas todas as tabelas que a constituem. Facilitar o desenvolvimento e manuteno de aplicaes, dado que se alguma tabela sofrer alguma

    alterao, a aplicao ter que ser modificada, o que pode ser evitado caso seja utilizada uma view. As principais limitaes na utilizaes de view so:

    Somente podemos utilizar uma view no banco de dados atual, embora este possa acessar dados de tabelas de outros bancos de dados ou at mesmo de outros servidores.

    Uma view pode ter, no mximo, 10234 colunas. O usurio que est criando a view deve, obviamente, ter acesso a todas as colunas includas na view. Podemos aninhar view, isto , uma view pode referenciar outra, at um nvel de 32 views aninhadas.

    possvel modificar os dados de uma tabela base subjacente atravs de uma view, porm h uma srie de restries que no sero tratadas aqui. Para saber mais sobre este assunto, acesso o link MSDN abaixo: http://msdn.microsoft.com/pt-br/library/ms180800.aspx Tipos de view que podem ser criadas:

  • 34

    Sintaxe bsica para criao de uma view:

    Onde: Nome_da_view : o nome da exibio. Os nomes de exibio devem seguir as regras para identificadores. A especificao do nome do proprietrio da exibio opcional.

    CREATE VIEW nome_da_view AS instruo_sql

  • 35 Instruo_sql: a instruo SELECT que define a exibio. A instruo pode usar mais de uma tabela e outras exibies. Permisses apropriadas so necessrias para selecionar os objetos referenciados na clusula SELECT da exibio criada. Uma exibio no tem que ser um subconjunto simples das linhas e colunas de uma determinada tabela. Uma exibio pode ser criada usando mais de uma tabela ou outras exibies com uma clusula VIEW de qualquer complexidade. Em uma definio de exibio indexada, a instruo SELECT deve ser uma instruo de tabela simples ou uma JOIN de vrias tabelas com agregao opcional. As clusulas SELECT em uma definio de exibio no podem incluir o seguinte:

    Clusulas COMPUTE ou COMPUTE BY Uma clusula ORDER BY, a no ser que exista tambm uma clusula TOP na lista de seleo da instruo

    SELECT A palavra-chave INTO A clusula OPTION Uma referncia para uma tabela temporria ou uma varivel de tabela.

    Ex: create view vw_func_setor as select funcionarios.func_nome as "Nome do funcionario", setores.setor_nome as "Nome do Setor" from funcionarios inner join setores on setores.setor_id = funcionarios.setor_id Ao selecionarmos os dados da view, o resultado ser: select * from vw_func_setor

    Caso seja necessrio alterar a view, utilize o commando ALTER no lugar do create. Ex: alter view vw_func_setor as select funcionarios.func_nome as "Nome do funcionario", setores.setor_nome as "Nome do Setor" from funcionarios inner join setores on setores.setor_id = funcionarios.setor_id and setores.setor_nome like 'F%'

  • 36 Aps alterar qualquer uma das tabelas que compe uma view, necessrio atualizar a view com o comando sp_refreshview nome_da_view. Ex: sp_refreshview vw_func_setor

    Principais estruturas do Transact-SQL

    BEGIN...END (Transact-SQL) Engloba uma srie de instrues Transact-SQL de modo que um grupo de instrues Transact-SQL pode ser executado. BEGIN e END so palavras-chave da linguagem de controle de fluxo. Sintaxe: BEGIN comandos END

    IF...ELSE (Transact-SQL) Impe condies na execuo de uma instruo Transact-SQL. A instruo Transact-SQL que segue uma palavra-chave IF e sua condio ser executada se a condio for satisfeita: a expresso Booleana retorna TRUE. A palavra-chave opcional ELSE introduz outra instruo Transact-SQL que ser executada quando a condio IF no for satisfeita: a expresso Booleana retorna FALSE. Sintaxe IF Boolean_expression { sql_statement | statement_block } [ ELSE { sql_statement | statement_block } ] A parte em azul opcional. Argumentos

    Boolean_expression: uma expresso que retorna TRUE ou FALSE. Se a expresso booleana contiver uma instruo SELECT, a instruo SELECT dever ser includa entre parnteses.

    {sql_statement | statement_block}: qualquer instruo ou agrupamento de instrues Transact-

    SQL, conforme definido por meio de um bloco de instrues. A menos que um bloco de instrues seja usado, a condio IF ou ELSE poder afetar o desempenho de somente uma instruo Transact-SQL.

    Para definir um bloco de instrues, use as palavras-chave BEGIN e END de controle de fluxo. Os testes IF podem ser aninhados depois de outro IF ou seguindo um ELSE. O limite do nmero de nveis aninhados depende da memria disponvel.

    WHILE (Transact-SQL) Define uma condio para a execuo repetida de uma instruo ou um bloco de instrues SQL. As instrues sero executadas repetidamente desde que a condio especificada seja verdadeira. A execuo de instrues no loop WHILE pode ser controlada internamente ao loop com as palavras-chave BREAK e CONTINUE.

  • 37 Sintaxe WHILE Boolean_expression { sql_statement | statement_block | BREAK | CONTINUE } Argumentos

    Boolean_expression: uma expresso que retorna TRUE ou FALSE. Se a expresso booleana contiver uma instruo SELECT, a instruo SELECT dever ser includa entre parnteses.

    {sql_statement | statement_block}: qualquer instruo Transact-SQL ou agrupamento de instrues, conforme definido com um bloco de instrues. Para definir um bloco de instrues, use as palavras-chave BEGIN e END de controle de fluxo.

    BREAK: Causa uma sada do loop WHILE mais interno. Quaisquer instrues que apaream depois da palavra-chave END, que marca o final do loop, sero executadas.

    CONTINUE: Faz com que o loop WHILE seja reiniciado, ignorando quaisquer instrues depois da palavra-chave CONTINUE.

    Se dois ou mais loops WHILE estiverem aninhados, o BREAK interno ser encerrado para o prximo loop mais externo. Todas as instrues aps o fim da primeira execuo do loop interno e o loop mais externo seguinte sero reiniciadas.

    CASE (Transact-SQL) Avalia uma lista de condies e retorna uma das vrias expresses de resultado possveis. A expresso CASE tem dois formatos:

    A expresso CASE simples compara uma expresso com um conjunto de expresses simples para determinar o resultado.

    A expresso CASE pesquisada avalia um conjunto de expresses booleanas para determinar o resultado. Os dois formatos do suporte a um argumento ELSE opcional. CASE pode ser usada em qualquer instruo ou clusula que permita uma expresso vlida. Por exemplo, voc pode usar CASE em instrues, como SELECT, UPDATE, DELETE e SET, e em clusulas, como select_list, IN, WHERE, ORDER BY e HAVING. Sintaxe Simple CASE expression: CASE input_expression WHEN when_expression THEN result_expression [ ...n ] [ ELSE else_result_expression ] END Searched CASE expression: CASE WHEN Boolean_expression THEN result_expression [ ...n ] [ ELSE else_result_expression ] END Argumentos

    input_expression: a expresso avaliada quando o formato CASE simples usado. input_expression qualquer expresso vlida.

    WHEN when_expression: uma expresso simples qual input_expression comparada quando o formato CASE simples usado. when_expression qualquer expresso vlida. Os tipos de dados de input_expression e cada when_expression devem ser iguais ou ser uma converso implcita.

  • 38 THEN result_expression: a expresso retornada quando input_expression igual a when_expression

    avaliada como TRUE ou Boolean_expression avaliada como TRUE. result expression qualquer expresso vlida.

    ELSE else_result_expression: a expresso retornada se nenhuma operao de comparao for avaliada como TRUE. Se esse argumento for omitido e nenhuma operao de comparao for avaliada como TRUE, CASE retornar NULL. else_result_expression qualquer expresso vlida. Os tipos de dados de else_result_expression e qualquer result_expression devem ser iguais ou ser uma converso implcita.

    WHEN Boolean_expression: a expresso booleana avaliada ao usar o formato CASE pesquisado. Boolean_expression qualquer expresso booleana vlida.

    Valores de retorno Expresso CASE simples: A expresso CASE simples opera comparando a primeira expresso com a expresso em cada clusula WHEN por equivalncia. Se essas expresses forem equivalentes, a expresso na clusula THEN ser retornada.

    Permite somente uma verificao de igualdade. Avalia input_expression e, na ordem especificada, avalia input_expression = when_expression para cada

    clusula WHEN. Retorna a result_expression da primeira input_expression = when_expression avaliada como TRUE. Se nenhuma input_expression = when_expression for avaliada como TRUE, o Mecanismo de Banco de

    Dados do SQL Server retornar a else_result_expression, se uma clusula ELSE for especificada, ou um valor NULL, se nenhuma clusula ELSE for especificada.

    Exemplo: USE AdventureWorks; GO SELECT ProductNumber, Category = CASE ProductLine WHEN 'R' THEN 'Road' WHEN 'M' THEN 'Mountain' WHEN 'T' THEN 'Touring' WHEN 'S' THEN 'Other sale items' ELSE 'Not for sale' END, Name FROM Production.Product ORDER BY ProductNumber; GO Expresso CASE pesquisada:

    Na ordem especificada, avalia Boolean_expression para cada clusula WHEN. Retorna a result_expression da primeira Boolean_expression avaliada como TRUE. Se nenhuma Boolean_expression for avaliada como TRUE, o Mecanismo de Banco de Dados retornar a

    else_result_expression, se uma clusula ELSE for especificada, ou um valor NULL, se nenhuma clusula ELSE for especificada.

    Exemplo: select func_nome, func_salario, case when func_salario >=0 and func_salario 500 and func_salario 2000 then 'Cargo de confiana' else 'Salrio negativo!!!!???' end as "Situao" from funcionarios

  • 39

    O SQL Server permitido somente para 10 nveis de aninhamento em expresses CASE. A expresso CASE no pode ser usada para controlar o fluxo de execuo de instrues Transact-SQL, blocos de instrues, funes definidas pelo usurio e procedimentos armazenados. Para obter uma lista dos mtodos de controle de fluxo, consulte Linguagem de controle de fluxo (Transact-SQL).

    Stored Procedures (Procedimentos Armazenados) Fontes adicionais: http://imasters.uol.com.br/artigo/7932/bancodedados/dominando_stored_procedures/

    http://www.devmedia.com.br/articles/viewcomp.asp?comp=2213

    Uma Stored Procedure (Procedimento Armazenado) ou simplesmente SP, uma coleo de instrues implementadas com linguagem T-SQL (Transact-Sql, no SQL Server 2000/2005), que, uma vez armazenadas ou salvas, ficam dentro do servidor de forma pr-compilada, aguardando que um usurio do banco de dados faa sua execuo. Geralmente, assim como VIEWS fazem com relatrios e dados estatsticos escalonveis, os SPs encapsulam tarefas repetitivas, desde um simples INSERT, passando por inseres por lote, updates e algumas outras instrues mais complexas, como, efetuar uma efetivao de saque em uma conta de um determinado cliente em uma instituio bancria ou efetivar sadas de mercadorias seguido por baixa em estoque. Elas oferecem suporte a variveis declaradas pelo prprio usurio, uso de expresses condicionais, de lao e muitos outros recursos, os quais veremos alguns mais frente. As vantagens no uso de Stored Procedures so claras:

    Modularidade: passamos a ter o procedimento divido das outras partes do software, bastando alterarmos somente as suas operaes para que se tenha as modificaes por toda a aplicao;

    Diminuio de I/O: uma vez que so passados parmetros para o servidor, chamando o procedimento

    armazenado, as operaes so executadas usando-se o processamento do servidor. No final da execuo, podem ser retornados os resultados de uma transao para o cliente, sendo assim, no h um trfego imenso e rotineiro de dados pela rede;

    Rapidez na execuo: as stored procedures, aps salvas no servidor, ficam somente aguardando, j em

    uma posio da memria cache, serem chamadas para executarem uma operao, ou seja, como esto pr-compiladas, as aes tambm j esto pr-carregadas, dependendo somente dos valores dos parmetros. Aps a primeira execuo, elas se tornam ainda mais rpidas;

  • 40 Segurana de dados: podemos tambm, ocultar a complexidade do banco de dados para usurios,

    deixando que sejam acessados somente dados pertinentes ao tipo de permisso atribuda ao usurio ou mesmo declarando se a Stored Procedure proprietria ou pblica, podendo ser tambm criptografada.

    Existem certos tipos de Stored Procedures para o SQL Server 2000 e para o SQL Server 2005, so eles:

    System Stored Procedures ou Procedimentos Armazenados do Sistema: nas duas verses do SGBD, so criados no momento da instalao e ficam armazenados no banco de dados chamado master, junto com as entidades e outros procedimentos prprios do sistema. So utilizados das mais diversas formas. Um exemplo clssico o SP_HELPINDEX, para checar os ndices de uma determinada tabela, ou o SP_REFRESHVIEW para criar uma View.

    Local Stored Procedure ou Procedimentos Armazenados locais: esses procedimentos so criados

    em bancos de dados de usurios individuais, ou seja, no SQL Server 2000 so proprietrias. J no SQL Server 2005, tem o nome de Stored Procedures Temporrias Locais, que iniciam com um sinal de # e somente a conexo que a criou poder execut-la. Ainda no SQL Server 2005, existem os Procedimentos Temporrios Globais, que podem ser utilizados de forma global, ou seja, por qualquer usurio desta conexo e iniciam com ##. Ao ser encerrada a conexo onde a SP foi criada, elas sero eliminadas automaticamente.

    Extended Stored Procedure ou Procedimentos Armazenados Extendidos: so comuns s duas

    verses do SGBD Microsoft. Executam funes externas e do sistema operacional e iniciam com xp_. Esses procedimentos so implementados como Dynamic-link Librarys (DLL), executadas fora do ambiente do SQL Server.

    User-Defined Stored Procedure ou Procedimento Armazenados Definidos pelo Usurio: estes

    so criados em bancos de dados pelo prprio usurio, como o nome j diz. So utilizados para realizar tarefas repetitivas, facilitando a manuteno e alterao, j que esto em um s ponto da aplicao/Banco de Dados.

    Alguns cuidados devem ser ressaltados, antes mesmo de comearmos a criar nossos primeiros Procedimentos Armazenados:

    Temos a nossa disposio ou disposio de tais procedimentos, um espao mximo de 128 MB, o que nos deixa bem vontade;

    Procedimentos Armazenados podem fazer referncia VIEWS e TRIGGERS, bem como tabelas temporrias;

    Caso um Stored Procedure crie uma tabela temporria local, essa tabela somente existir at o fim da execuo do procedimento;

    Somente os usurios que so membros da role de servidor SYSADMIN ou da role de Banco de Dados db_owner e db_admin tm permisso para executar o comando CREATE PROCEDURE, permisso que pode ser atribuda por membro da role SYSADMIN.

    Os comandos: CREATE DEFAULT, CREATE RULE, CREATE TRIGGER e CREATE VIEW no podem estar em meio a uma construo de Stored Procedure.

    SINTAXE BSICA:

  • 41

    Uma SP para retornar todos os registros da tabela funcionarios: create procedure Retorna_funcionarios as select * from funcionarios Claro que poderamos fazer a mesma coisa sem a necessidade de uma SP! Para execut-la: exec retorna_funcionarios Exemplo de uma SP para validar CPF: CREATE procedure validaCPF (@CPF as varchar(11) ) as BEGIN -- declarao das variveis locais declare @n int declare @soma int declare @multi int declare @digito1 int declare @digito2 int if len(rtrim(ltrim(@CPF))) 11 begin Return 0 -- sai da stored procedure caso o CPF esteja no tamanho incorreto end -- calculando o primeiro digito... set @soma = 0 set @multi = 10 set @n = 1

  • 42 WHILE (@n mdulo if @soma
  • 43 if (@retorno = 0) print 'Incorreto' else print 'Correto'

    Parmetros de Entrada e Sada O tipo de parmetro default do SQL sempre o de entrada. Para criar um parmetro de sada, utilize a palavra reservada output aps a declarao do nome do parmetro e tambm no momento da chamada (execuo) Exemplo: create procedure sp_calcula ( @valor1 int, @valor2 int, @resultado int output ) as Begin set @resultado = @valor1 + @valor2 end Para executar a SP acima, digite: declare @resultado int execute sp_calcula 5,7, @resultado output print 'Resultado: ' + cast (@resultado as varchar)

    SPs que acessam dados do banco Ex: Stored Procedure para gravar um setor na tabela setores. Caso o setor j exista, a SP retorna 0 ou 1 caso seja gravado com sucesso. create procedure sp_insereSetor( @codigo int, @descricao varchar(50) ) as begin if not exists( select setor_id from setores where setor_id = @codigo) begin insert into setores ( setor_id, setor_nome ) values (@codigo, @descricao ) return 1 -- gravado com sucesso! end else return 0 -- erro ao gravar! registro j existe. end

  • 44 Para testar a SP abaixo, digite: declare @retorno int execute @retorno = sp_insereSetor 11, 'Teste' if @retorno = 1 print 'Gravado com sucesso' else print 'Registro j existe.'

    Tabelas temporrias Voc pode criar tabelas temporrias globais e locais. Tabelas temporrias locais (# no prefixo) so visveis somente na sesso corrente, e tabelas temporrias globais (## no prefixo) so visveis para todas as sesses. O exemplo abaixo cria uma tabela temporria visvel apenas na sesso do usurio que a criou (local). create table #temporaria( codigo int, descricao varchar(30) Tabelas temporrias so automaticamente apagadas quando elas estiverem fora de escopo, ou quando for utilizado explicitamente o comando drop table:

    Uma tabela temporria local criada em uma SP apagada automaticamente quando a SP terminada. Ela pode ser referenciada por outra SP aninhada dentro da SP que a criou.

    Todas as tabelas temporrias locais so apagadas automaticamente ao fim da sesso corrente. Tabelas temporrias globais so apagadas automaticamente quando a sesso que a criou terminar e

    tambm quando todas as outras tarefas que a estavam referenciando terminarem. A SP abaixo ir retornar todos os registros da tabela funcionrios com o salrio atualizado. O campo gerente_id tambm foi removido Porm, essas alteraes sero realizadas em uma tabela temporria. A tabela original ainda conter os registros sem qualquer alterao. No seria necessrio criar uma tabela temporria para resolver este problema.... alter procedure sp_atualizaSalario as select * into #TabTemp from funcionarios --cria um tablea temporria com a mesma -- estrutura da tabela funcionarios -- atualiza o salario da seguinte forma: cada ano de vida equivale a 1% a mais no -- salrio do funcionario update #TabTemp set func_salario = func_salario * cast( '1.' + cast( DATEDIFF ( year , func_dataNasc , getdate()) as varchar) as decimal(8,2) ) -- remove a coluna gerente_id da tabela temporria alter table #TabTemp drop column gerente_id -- retorna os dados da tabela temporrioa select * from #TabTemp Para executar: execute sp_atualizaSalario

  • 45 O exemplo abaixo cria uma tabela temporria com apenas 4 campos e a preenche com os dados da tabela funcionrio. create procedure sp_funcionario_idade as -- cria uma tabela temporria create table #func_temp ( codigo int, nome varchar(30), data_nascimento datetime, idade int) -- insere os dados na tabela temporria insert into #func_temp (codigo, nome, data_nascimento, idade) select func_id, func_nome, func_datanasc, datediff( year, func_datanasc, getdate())as "Idade" from funcionarios -- seleciona os dados da tabela temporria select * from #func_temp Para execut-la: execute sp_funcionario_idade

  • 46

    Triggers (Gatilhos) Fonte adicional: http://www.devmedia.com.br/articles/viewcomp.asp?comp=1695 Uma trigger um tipo especial de procedimento armazenado, que executado sempre que h uma tentativa de modificar os dados (insert, update e delete) da tabela onde ela foi configurada..

    - Chamados Automaticamente Quando h uma tentativa de inserir, atualizar ou excluir os dados em uma tabela, e um TRIGGER tiver sido definido na tabela para essa ao especfica, ele ser executado automaticamente, no podendo nunca ser ignorado. - No podem ser chamados diretamente Ao contrrio dos procedimentos armazenados do sistema, os disparadores no podem ser chamados diretamente e no passam nem aceitam parmetros. - parte de uma transao O TRIGGER e a instruo que o aciona so tratados como uma nica transao, que poder ser revertida em qualquer ponto do procedimento, caso voc queria usar ROLLBACK, conceitos que veremos mais a frente. Orientaes bsicas quando estiver usando TRIGGER.

    As definies de TRIGGERS podem conter uma instruo ROLLBACK TRANSACTION, mesmo que no exista

    uma instruo explcita de BEGIN TRANSACTION; Se uma instruo ROLLBACK TRANSACTION for encontrada, ento toda a transao (a TRIGGER e a instruo

    que o disparou) ser revertida ou desfeita. Se uma instruo no script da TRIGGER seguir uma instruo ROLLBACK TRANSACTION, a instruo ser executada, ento, isso nos obriga a ter uma condio IF contendo uma clusula RETURN para impedir o processamento de outras instrues.

    No uma boa prtica utilizar ROLLBACK TRANSACTION dentro de suas TRIGGERS, pois isso gerar um

    retrabalho, afetando muito no desempenho de seu banco de dados, pois toda a consistncia dever ser feita quando uma transao falhar, lembrando que tanto a instruo quanto o TRIGGER formam uma nica transao. O mais indicado validar as informaes fora das transaes com TRIGGER, evitando que a transao seja desfeita.

    Para que um TRIGGER seja disparado, o usurio o qual entrou com as instrues, dever ter permisso de

    acessar tanto a entidade e conseqentemente ao TRIGGER. Usos e aplicabilidade dos TRIGGERS

    Impor uma integridade de dados mais complexa do que uma restrio CHECK; Definir mensagens de erro personalizadas; Manter dados desnormalizados; Comparar a consistncia dos dados posterior e anterior de uma instruo UPDATE;

    As TRIGGERS so usadas com enorme eficincia para impor e manter integridade referencial de baixo nvel, e no para retornar resultados de consultas. A principal vantagem que elas podem conter uma lgica de processamento complexa. Voc pode usar TRIGGERS para atualizaes e excluses em cascata atravs de tabelas relacionadas em um banco de dados, impor integridades mais complexas do que uma restrio CHECK, definir mensagens de erro personalizadas, manter dados desnormalizados e fazer comparaes dos momentos anteriores e posteriores a uma transao.

  • 47 Quando queremos efetuar transaes em cascata, por exemplo, uma TRIGGER de excluso na tabela PRODUTO do banco de dados Northwind pode excluir os registros correspondentes em outras tabelas que possuem registros com os mesmos valores de PRODUCTID excludos para que no haja quebra na integridade, como a dito popular pai pode no ter filhos, mas filhos sem um pai no existe.

    Voc pode utilizar os TRIGGERS para impor integridade referencial da seguinte maneira: Executando uma ao ou atualizaes e excluses em cascata:

    A integridade referencial pode ser definida atravs do uso das restries FOREIGN KEY e REFERENCE, com a instruo CREATE TABLE. As TRIGGERS fazem bem o trabalho de checagem de violaes e garantem que haja coerncia de acordo com a sua regra de negcios. Se voc exclui um cliente, de certo, voc ter que excluir tambm todo o seu histrico de movimentaes. No seria boa coisa se somente uma parte desta transao acontecesse.

    Criando disparadores de vrios registros:

    Quando mais de um registro atualizado, inserido ou excludo, voc deve implementar um TRIGGER para manipular vrios registros.

    CRIANDO TRIGGERS As TRIGGERS so criadas utilizando a instruo CREATE TRIGGER que especifica a tabela onde ela atuar, para que tipo de ao ela ir disparar suas aes seguido pela instruo de conferncia para disparo da ao. E meio a esses comandos, temos algumas restries para o bom funcionamento. O SQL Server no permite que as instrues a seguir, sejam utilizadas na definio de uma TRIGGER:

    ALTER DATABASE; CREATE DATABASE; DISKINIT; DISKRESIZE; DROP DATABASE; LOAD DATABASE; LOAD LOG; RECONFIGURE; REATORE DATABASE; RESTORELOG.

    COMO FUNCIONAM OS TRIGGERS Como funciona um TRIGGER INSERT; Como funciona um TRIGGER DELETE; Como funciona um TRIGGER UPDATE; Quando inclumos, exclumos ao alteramos algum registro em um banco de dados, so criadas tabelas temporrias que passam a conter os registros excludos, inseridos e tambm o antes e depois de uma atualizao. Quando voc exclui um determinado registro de uma tabela, na verdade voc estar apagando a referncia desse registro, que ficar, aps o DELETE, numa tabela temporria de nome DELETED. Uma TRIGGER implementada com uma instruo SELECT poder lhe trazer todos ou um nmero de registro que foram excludos. Assim como acontece com DELETE, tambm ocorrer com inseres em tabelas, podendo obter os dados ou o nmero de linhas afetadas buscando na tabela INSERTED. J no UPDATE ou atualizao de registros em uma tabela, temos uma variao e uma concatenao para verificar o antes e o depois.

  • 48 De fato, quando executamos uma instruo UPDATE, a engine de qualquer banco de dados tem um trabalho semelhante, primeiro exclui os dados tupla e posteriormente faz a insero do novo registro que ocupar aquela posio na tabela, ou seja, um DELETE seguido por um INSERT. Quando ento, h uma atualizao, podemos buscar o antes e o depois, pois o antes estar na tabela DELETED e o depois estar na tabela INSERTED. Nada nos impede de retornar dados das tabelas temporrias (INSERTED, DELETED) de volta s tabelas de nosso banco de dados, mas atente-se, os dados manipulados so temporrios assim como as tabelas e s estaro disponveis nesta conexo. Aps fechar, as tabelas e os dados no sero mais acessveis.

    TRIGGER INSERT De acordo com a sua vontade, uma TRIGGER por lhe enviar mensagens de erro ou sucesso, de acordo com as transaes. Estas mensagens podem ser definidas em meio a um TRIGGER utilizando condicionais IF e indicando em PRINT sua mensagem personalizada. Por exemplo, vamos criar uma tabela chamada tbl_usuario, com a qual simularemos um cadastro de usurios que voc tambm poder criar para fazer os seus testes. A cada insero de novo usurio, podemos exibir uma mensagem personalizada de sucesso na insero. EX: A trigger abaixo ser disparada sempre que um novo registro for inserido na tabela Funcionrios: create trigger trg_onInsertValue on Funcionarios for INSERT AS if (select count(*) from inserted) = 1 print 'Registro inserido com sucesso!!!' Para test-lo, basta inserir um funcionrio. Ex: insert into funcionarios (func_id, func_nome) values(100, 'xxx')

    Existem vrias outras abordagens para o uso de TRIGGERS com INSERTS, por exemplo, quando se faz um controle de entrada e sadas de produtos, podemos ter uma TRIGGER executando a baixa dos produtos no estoque (entrada) diante daqueles que foram solicitados num pedido (sada). Uma TRIGGER pode automatizar essa rotina.

    TRIGGER DELETE Podemos usar uma TRIGGER para monitorar certas excluses de registros de acordo com a sua regra de negcios e tambm para proteger a integridade dos dados em um determinado banco de dados. Alguns fatos devem ser considerados ao usar TRIGGERS DELETE: Quando um registro acrescentado tabela temporria DELETED, ele deixa de existir na tabela do banco de

    dados. Portanto, a tabela DELETED no apresentar registros em comum com as tabelas do banco de dados;

  • 49 alocado espao na memria para criar a tabela DELETED, que est sempre em cache; Um TRIGGER para uma ao DELETE no executado para a instruo TRUNCATE TABLE porque a mesma no

    registrada no log de transaes. Podemos criar um TRIGGER no permita a excluso de usurios de nossa tabela funcionarios, da seguinte forma: create trigger trg_onDeleteValue on Funcionarios for DELETE AS if (select count(*) from DELETED) >= 1 RAISERROR('Usurios no podem ser excluidos!!!', 16, 1) ROLLBACK transaction Para testar a trigger: delete from funcionarios

    TRIGGER UPDATE Partindo ento do princpio que uma instruo UPDATE se apresenta em duas etapas( delete e insert), com ela podemos verificar o antes e o depois, j que os dados estaro disponveis nas tabelas temporrias DELETED momento anterior INSERTED momento atual, logo aps o UPDATE. A qualquer momento daqui por diante, poderemos ento contemplar, sempre que executada uma instruo para atualizao de registros, o antes e o depois, o que acabamos de definir no TRIGGER para UPDATE. Vamos ento, executar a instruo para atualizar o nico registro que temos ento em nossa tabela. Vamos alterar o nome do funcionrio n 100 para YYY. Veremos ento como era o nome antes e como o nome agora! Primeiro, vamos criar a trigger de update create trigger trg_onUpdateValue on Funcionarios for UPDATE AS if (select count(*) from deleted) 0 begin select * from DELETED select * from INSERTED end Agora, vamos alterar o nome de XXX para YYY do funcionrio n. 100: update funcionarios set func_nome ='YYY' where func_id = 100

    Para apagar uma trigger: Drop trigger nome_da_trigger

  • 50

    Habilitando e Desabilitando Triggers Podemos desabilitar temporariamente uma trigger. Para desabilitar uma trigger utilizamos o comando: alter table nome_da_tabela disable trigger nome_da_trigger Ex: desabilitando a trigger de INSERT da tabela funcionrios: alter table funcionarios disable trigger trg_onInsertValue Para saber as triggers associadas a uma tabela, digite: exec sp_helpTrigger @tabname = funcionarios

    Para visualizar o cdigo fonte de uma trigger (tambm funciona com Stored Procedures), digite: exec sp_helpText trg_onInsertValue

  • 51

    Cursores (Transact-SQL) Fonte: http://msdn.microsoft.com/pt-br/library/ms180169.aspx As instrues Microsoft SQL Server produzem um conjunto de resultados completo, mas h momentos em que os resultados so processados melhor uma linha de cada vez. Abrir um cursor em um conjunto de resultados permite o processamento do conjunto de resultados uma linha por vez. Voc pode atribuir um cursor a uma varivel ou a um parmetro com um tipo de dados cursor. Operaes de cursor tm suporte nestas instrues: Os cursores estendem o resultado de processamento por:

    Permitirem o posicionamento em linhas especficas do conjunto de resultados. Recuperarem uma linha ou bloco de linhas de posies atuais em um conjunto de resultados. Oferecerem suporte s modificaes de dados nas linhas da posio atual no conjunto de resultados. Oferecerem suporte a diferentes nveis de visibilidade s mudanas feitas por outros usurios ao banco de

    dados que so apresentados no conjunto de resultados. Transact-SQL Extended Syntax DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] FOR select_statement [;] cursor_name

    o nome cursor de servidor definido Transact-SQL. cursor_name deve atender s regras para identificadores.

    SCROLL

    Especifica que todas as opes de busca (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE) esto disponveis. Se SCROLL no for especificado, NEXT ser a nica opo de busca com suporte. SCROLL no poder ser especificado se FAST_FORWARD tambm for especificado.

    READ ONLY

    Previne atualizaes feitas por este cursor. O cursor no pode ser referenciado em uma clusula WHERE CURRENT OF, em uma instruo UPDATE ou DELETE. Essa opo anula a capacidade padro de um cursor ser atualizado.

    LOCAL

    Especifica que o escopo do cursor local para o lote, procedimento armazenado, ou acionador no qual o cursor foi criado. O nome de cursor s vlido dentro desse escopo. O cursor pode ser referenciado atravs de variveis de cursor local no parmetro OUTPUT do lote, acionador ou procedimento armazenado. Um parmetro OUTPUT usado para devolver o cursor local ao lote procedimento armazenado ou acionador de chamada, que pode nomear o parmetro a uma varivel de cursor para referenciar o cursor, depois que o procedimento armazenado terminar. O cursor implicitamente desalocado quando o lote, procedimento armazenado ou acionador encerrado, a menos que o cursor tenha sido repassado como um parmetro OUTPUT. Se for repassado em um parmetro OUTPUT, o cursor ser desalocado quando a ltima varivel que referenciada for desalocada ou extrapolar o escopo.

    GLOBAL

  • 52 Especifica que o escopo do cursor global para a conexo. O nome de cursor pode ser referenciado em qualquer procedimento armazenado ou lote executado pela conexo. O cursor s desalocado implicitamente na desconexo.

    FORWARD_ONLY

    Especifica se o cursor s pode ser rolado da primeira ltima linha. FETCH NEXT a nica opo de busca com suporte. Se FORWARD_ONLY for especificado sem as palavras-chave STATIC, KEYSET ou DYNAMIC, o cursor operar como um cursor DYNAMIC. Quando FORWARD_ONLY ou SCROLL no estiverem especificados, FORWARD_ONLY ser o padro; a no ser que as palavras-chave STATIC, KEYSET ou DYNAMIC estejam especificadas. Os cursores STATIC, KEYSET e DYNAMIC seguem o padro SCROLL. Diferentemente das APIs de banco de dados, como ODBC e ADO, os cursores Transact-SQL STATIC, KEYSET e DYNAMIC oferecem suporte para FORWARD_ONLY

    STATIC

    Define um cursor que faz uma cpia temporria dos dados a serem usados por ele. Todas as solicitaes para o cursor so respondidas dessa tabela temporria em tempdb; logo, as modificaes feitas na tabelas base no so refletidas nos dados retornados de buscas feitas nesse cursor, que no permite modificaes.

    KEYSET

    Especifica que a associao e a ordem de linhas no cursor so fixas, quando o cursor aberto. O conjunto de chaves que identificam exclusivamente as linhas construdo em uma tabela no tempdb, conhecida como keyset.

    Alteraes em valores no chave nas tabelas base, realizadas pelo proprietrio do cursor ou confirmadas por outros usurios, so visveis como rolagens do proprietrio ao redor do cursor. Inseres feitas por outros usurios no so visveis (no possvel fazer inseres por um cursor de servidor Transact-SQL). Se uma linha for excluda, uma tentativa de busc-la retorna um @@FETCH_STATUS de-2. Atualizao de valores de chave externos ao cursor lembram a excluso de uma linha antiga, seguida de uma insero de uma nova linha. A linha com os novos valores no visvel, e as tentativas de se buscar a linha com os valores antigos retornam um @@FETCH_STATUS de-2. Os novos valores ficaro visveis se a atualizao for feita atravs do cursor, especificando-se a clusula WHERE CURRENT OF.

    DYNAMIC

    Define um cursor que reflete todas as mudanas de dados feitas s linhas no seu conjunto de resultados conforme voc rola o cursor. Os valores de dados, ordem e associao das linhas podem sofrer alteraes a cada busca. Cursores dinmicos no oferecem suporte para a opo de busca ABSOLUTE.

    FAST_FORWARD

    Especifica um cursor FORWARD_ONLY, READ_ONLY, com otimizaes de desempenho habilitadas. FAST_FORWARD no poder ser especificado se SCROLL ou FOR_UPDATE tambm o for.

    READ_ONLY

    Previne atualizaes feitas por este cursor. O cursor no pode ser referenciado em uma clusula WHERE CURRENT OF, em uma instruo UPDATE ou DELETE. Essa opo anula a funcionalidade padro de um cursor para ser atualizado.

    SCROLL_LOCKS

    Especifica que as atualizaes ou excluses posicionadas realizadas pelo cursor tero sucesso garantido. O SQL Server bloqueia as linhas como so lidas no cursor, para assegurar sua disponibilidade para

  • 53 modificaes posteriores. SCROLL_LOCKS no poder ser especificado se FAST_FORWARD ou STATIC tambm o forem.

    OPTIMISTIC

    Especifica que as atualizaes e excluses posicionadas realizadas pelo cursor no tero sucesso se a linha foi atualizada desde que foi lida no cursor. O SQL Server no bloqueia linhas como so lidas no cursor. Em vez disso, ele usa comparaes de valores de coluna timestamp, ou um valor de soma de verificao se a tabela no tiver nenhuma coluna timestamp, para determinar se a linha foi modificada depois de lida no cursor. Se a linha fosse modificada, a tentativa de atualizao ou excluso posicionada falharia. OPTIMISTIC no poder ser especificado se FAST_FORWARD tambm for especificado.

    select_statement

    uma instruo SELECT padro que define o conjunto de resultados de um cursor. As palavras-chave COMPUTE, COMPUTE BY, FOR BROWSE e INTO no so permitidas em select_statement , de uma declarao de cursor.

    FETCH (Transact-SQL) Aqui est descrita apenas a sintaxe deste comando. Para mais informaes, visite: http://msdn.microsoft.com/pt-br/library/ms180152.aspx Recupera uma linha especfica de um cursor de servidor Transact-SQL. A funo @@FETCH_STATUS informa o status da ltima instruo FETCH. Sintaxe FETCH [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar } ] FROM ] { { [ GLOBAL ] cursor_name } | @cursor_variable_name } [ INTO @variable_name [ ,...n ] ]

    @@FETCH_STATUS (Transact-SQL) Retorna o status do ltimo cursor que a instruo FETCH emitiu em relao a qualquer cursor atualmente aberto pela conexo. Sintaxe @@FETCH_STATUS : integer Valor de retorno Valor de retorno Descrio 0 A instruo FETCH foi bem-sucedida. -1 A instruo FETCH falhou ou a linha estava alm do conjunto de resultados. -2 A linha buscada est ausente.

  • 54

    Exemplos Um exemplo simples, onde so retornados todos os nomes de funcionrios que contenham a letra d no nome: -- variveis que sero utilizadas pelo cursor declare @func_nome varchar(50) -- declarao do cursor declare cursor_teste cursor for select func_nome from funcionarios where func_nome like '%d%' -- abertura do cursor open cursor_teste -- vai para o primeiro registro e preenche as variveis correspondentes FETCH NEXT FROM cursor_teste INTO @func_nome while @@fetch_Status = 0 -- enquanto houver registros, faa Begin -- imprime os dados das variveis print 'Nome: ' + @func_nome -- vai para o prximo registro e preenche as variveis correspondentes FETCH NEXT FROM cursor_teste INTO @func_nome end close cursor_Teste -- fecha o cursor deallocate cursor_teste -- desaloca o cursor da memria Nome: Eduardo Silva Nome: Anderson Silva Nome: Ingrid Silva Nome: Daniela Nome: Daniel Nome: Valdir Silva Vamos incluir um pouco de lgica no exemplo acima: O cursor abaixo imprime o cdigo e o nome e uma situao salarial de todos os funcionrios que contenham a letra d no nome. -- variveis que sero utilizadas pelo cursor declare @func_id int declare @func_nome varchar(50) declare @func_salario money -- varivel auxiliar declare @status varchar(15) -- declarao do cursor declare cursor_teste cursor for select func_id, func_nome, func_salario from funcionarios where func_nome like '%d%' -- abertura do cursor open cursor_teste -- vai para o primeiro registro e preenche as variveis correspondentes FETCH NEXT FROM cursor_teste INTO @func_id, @func_nome, @func_salario

  • 55 while @@fetch_Status = 0 -- enquanto houver registros, faa Begin if @func_salario < 500 set @status = 'Ganha pouco' else if @func_salario < 1000 set @status = 'Ganha +-' else set @status = 'Ganha bem!' -- imprime os dados das variveis print 'Cdigo ' + cast( @func_id as varchar) + ' Nome: ' + @func_nome + ' Status: ' + @status -- vai para o prximo registro e preenche as variveis correspondentes FETCH NEXT FROM cursor_teste INTO @func_id, @func_nome, @func_salario end close cursor_Teste -- fecha o cursor deallocate cursor_teste -- desaloca o cursor da memria Cdigo 6 Nome: Eduardo Silva Status: Ganha pouco Cdigo 7 Nome: Anderson Silva Status: Ganha +- Cdigo 11 Nome: Ingrid Silva Status: Ganha pouco Cdigo 14 Nome: Daniela Status: Ganha bem! Cdigo 15 Nome: Daniel Status: Ganha +- Cdigo 16 Nome: Valdir Silva Status: Ganha +- O exemplo abaixo faz a exibio dos dados na ordem inversa: Observe a opo SCROLL na declarao do cursor! declare @func_id int declare @func_nome varchar(50) declare cursor_teste SCROLL cursor for select func_id, func_nome from funcionarios open cursor_teste FETCH LAST FROM cursor_teste INTO @func_id, @func_nome while @@fetch_Status = 0 Begin print cast(@func_id as varchar(5)) + ' ' + @func_nome FETCH PRIOR FROM cursor_teste INTO @func_id, @func_nome end close cursor_Teste deallocate cursor_teste 17 Kleber Silva 16 Valdir Silva 15 Daniel 14 Daniela 13 Bruna Silva 12 Bruno Silva 11 Ingrid Silva 10 Jos 9 Joo 8 Fbio 7 Anderson Silva 6 Eduardo Silva 5 Nestor Silva 4 Antonio

  • 56 3 Carla Silva 2 Ana 1 Maria Silva O exemplo abaixo mostra como alterar os dados de um cursor, usando o comando update com a opo current of: A opo current of cursor_name na clusula WHERE de um comando Update serve para atualizar o registro atual em cursor_name sem a necessidade de se especificar a chave da tabela. declare @func_id int declare @func_nome varchar(50) declare cursor_teste cursor for select func_id, func_nome from funcionarios open cursor_teste FETCH NEXT FROM cursor_teste INTO @func_id, @func_nome while @@fetch_Status = 0 Begin if charindex('k', @func_nome) != 0 begin set @func_nome = @func_nome + ' Souza' - se tiver a letra k no nome update funcionarios set func_nome= @func_nome where current of cursor_teste end print cast(@func_id as varchar(5)) + ' ' + @func_nome FETCH NEXT FROM cursor_teste INTO @func_id, @func_nome end close cursor_Teste deallocate cursor_teste 1 Maria Silva 2 Ana 3 Carla Silva 4 Antonio 5 Nestor Silva 6 Eduardo Silva 7 Anderson Silva 8 Fbio 9 Joo 10 Jos 11 Ingrid Silva 12 Bruno Silva 13 Bruna Silva 14 Daniela 15 Daniel 16 Valdir Silva (1 row(s) affected) 17 Kleber Silva Souza

  • 57

    Funes definidas pelo usurio (FUNCTIONS) http://msdn.microsoft.com/pt-br/library/ms186755.aspx Este tema possui muitos detalhes que no sero abordados em aula, porm, podem ser consultados no link acima. Assim como as funes em linguagens de programao, as funes definidas pelo usurio no Microsoft SQL Server so rotinas que aceitam parmetros, executam uma ao, como um clculo complexo e retornam o resultado dessa ao como um valor. O valor de retorno pode ser um nico valor escalar ou um conjunto de resultados.

    Benefcios da funo definida pelo usurio Os benefcios de usar funes definidas pelo usurio em SQL Server so:

    Elas permitem progra