consultas sql

18
Desenvolvido por: Alexandre G. Silva Pág. 1 de 18 TOTVS – ES 04/09/2010 Consultas SQL Server 1 - MANIPULAÇÃO DE DADOS SELECT select_list [ INTO new_table_name ] FROM table_list [ WHERE search_conditions ] [ GROUP BY group_by_list ] [ HAVING search_conditions ] [ ORDER BY order_list [ ASC | DESC ] ] select_list Descreve as colunas do conjunto de resultados. É uma lista de expressões separadas por vírgulas. Cada expressão define o formato (tipo de dados e tamanho) e a fonte dos dados para a coluna do conjunto de resultados. Cada expressão de lista de seleção é tipicamente uma referência a uma coluna na tabela de origem ou exibição de onde os dados provêm, mas pode ser qualquer outra expressão, como uma constante ou uma função Transact-SQL. O uso da expressão * em uma lista de seleção especifica que todas as colunas da tabela de origem são retornadas. INTO new_table_name Especifica que o conjunto de resultados é usado para criar uma nova tabela. new_table_name especifica o nome da tabela nova. FROM table_list Contém uma lista das tabelas das quais os dados do conjunto de resultados são recuperados. Essas fontes podem ser: Tabelas base no servidor local que executa o SQL Server. Exibições na instância local do SQL Server. O SQL Server resolve internamente uma referência de exibição para referências nas tabelas base que compõem a exibição. Tabelas vinculadas. São tabelas em fontes de dados OLE DB que podem ser acessadas pelo SQL Server. Isso é referido como consulta distribuída. Fontes de dados OLE DB podem ser acessadas no SQL Server vinculando-as como servidor vinculado ou referenciando a fonte de dados em uma função OPENROWSET ou OPENQUERY. A cláusula FROM também pode conter especificações de junção. Isso define o caminho específico que o SQL Server deverá usar para navegar de uma tabela para outra. A cláusula FROM também é usada nas instruções DELETE e UPDATE para definir as tabelas que são modificadas. WHERE search_conditions A cláusula WHERE é um filtro que define as condições que cada linha das tabelas de origem deve atender para qualificar-se para a cláusula SELECT. Apenas linhas que atendem às condições colaboram com dados para o conjunto de resultados. Dados de linhas que não atendem às condições não são usados.

Upload: alexandre-silva

Post on 09-Jul-2015

14.800 views

Category:

Technology


2 download

DESCRIPTION

Material de apoio que reune uma selação de conteúdos interessantes, referente ao Microsoft SQL Server.

TRANSCRIPT

Page 1: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 1 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

1 - MANIPULAÇÃO DE DADOS

SELECT select_list

[ INTO new_table_name ]

FROM table_list

[ WHERE search_conditions ]

[ GROUP BY group_by_list ]

[ HAVING search_conditions ]

[ ORDER BY order_list [ ASC | DESC ] ]

select_list

Descreve as colunas do conjunto de resultados. É uma lista de expressões separadas por vírgulas.

Cada expressão define o formato (tipo de dados e tamanho) e a fonte dos dados para a coluna do

conjunto de resultados. Cada expressão de lista de seleção é tipicamente uma referência a uma

coluna na tabela de origem ou exibição de onde os dados provêm, mas pode ser qualquer outra

expressão, como uma constante ou uma função Transact-SQL. O uso da expressão * em uma lista de seleção especifica que todas as colunas da tabela de origem são retornadas.

INTO new_table_name

Especifica que o conjunto de resultados é usado para criar uma nova tabela. new_table_name

especifica o nome da tabela nova.

FROM table_list

Contém uma lista das tabelas das quais os dados do conjunto de resultados são recuperados. Essas fontes podem ser:

Tabelas base no servidor local que executa o SQL Server.

Exibições na instância local do SQL Server. O SQL Server resolve internamente uma referência de

exibição para referências nas tabelas base que compõem a exibição.

Tabelas vinculadas. São tabelas em fontes de dados OLE DB que podem ser acessadas pelo SQL

Server. Isso é referido como consulta distribuída. Fontes de dados OLE DB podem ser acessadas no

SQL Server vinculando-as como servidor vinculado ou referenciando a fonte de dados em uma

função OPENROWSET ou OPENQUERY.

A cláusula FROM também pode conter especificações de junção. Isso define o caminho específico que o SQL Server deverá usar para navegar de uma tabela para outra.

A cláusula FROM também é usada nas instruções DELETE e UPDATE para definir as tabelas que são modificadas.

WHERE search_conditions

A cláusula WHERE é um filtro que define as condições que cada linha das tabelas de origem deve

atender para qualificar-se para a cláusula SELECT. Apenas linhas que atendem às condições

colaboram com dados para o conjunto de resultados. Dados de linhas que não atendem às condições não são usados.

Page 2: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 2 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

A cláusula WHERE também é usada nas instruções DELETE e UPDATE para definir as linhas nas tabelas de destino que são modificadas.

GROUP BY group_by_list

A cláusula GROUP BY divide o conjunto de resultados em grupos baseados nos valores das colunas

do group_by_list. Por exemplo, a tabela AdventureWorks Sales.SalesOrderHeader tem dez

valores em TerritoryID. Uma cláusula GROUP BY TerritoryID divide o conjunto de resultados em

10 grupos, um para cada valor de TerritoryID.

HAVING search_conditions

A cláusula HAVING é um filtro adicional que é aplicado ao conjunto de resultados. Logicamente, a

cláusula HAVING filtra linhas do conjunto de resultados intermediário construído com a aplicação de

quaisquer cláusulas FROM, WHERE ou GROUP BY na instrução SELECT. As cláusulas HAVING são

tipicamente usadas com uma cláusula GROUP BY, embora uma cláusula GROUP BY não seja necessária antes de uma cláusula HAVING.

ORDER BY order_list[ ASC | DESC ]

A cláusula ORDER BY define a ordem na qual são classificadas as linhas no conjunto de resultados.

order_list especifica as colunas do conjunto de resultados que compõem a lista de classificação. As

palavras-chaves ASC e DESC são usadas para especificar se as linhas são classificadas em seqüência

ascendente ou descendente.

ORDER BY é importante porque a teoria relacional especifica que não se pode pressupor que as

linhas de um conjunto de resultados tenham qualquer seqüência, a menos que ORDER BY seja

especificado. ORDER BY deve ser usado em qualquer instrução SELECT para a qual a ordem das linhas do conjunto de resultados seja importante.

As cláusulas de uma declaração SELECT devem ser especificadas na ordem adequada.

Cada referência a um objeto do banco de dados deve ser inequívoca. A ambigüidade pode vir das seguintes fontes:

Pode haver vários objetos que têm o mesmo nome em um sistema. Por exemplo, Schema1 e

Schema2 podem ter uma tabela nomeada TableX. Para resolver a ambigüidade e especificar o

objeto TableX possuído por Schema1, qualifique o nome de tabela pelo menos com o nome do esquema:

Exemplo:

SELECT *

FROM Schema1.TableX

O banco de dados no qual o objeto reside pode nem sempre ser o banco de dados atual quando a

instrução SELECT é executada. Para ter certeza de que o objeto correto sempre é usado,

independentemente da configuração do banco de dados atual, qualifique o nome de objeto com o banco de dados e o esquema:

Exemplo:

SELECT *

FROM AdventureWorks.Purchasing.ShipMethod

Page 3: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 3 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

As tabelas e exibições especificadas na cláusula FROM podem ter nomes de coluna duplicados.

Freqüentemente, chaves estrangeiras terão o mesmo nome de coluna que sua chave primária

relacionada. Para resolver a ambigüidade entre nomes duplicados, o nome de coluna deve ser

qualificado com o nome da tabela ou nome de exibição:

Exemplo:

SELECT DISTINCT Sales.Customer.CustomerID, Sales.Store.Name

FROM Sales.Customer JOIN Sales.Store ON

( Sales.Customer.CustomerID = Sales.Store.CustomerID)

WHERE Sales.Customer.TerritoryID = 1

Essa sintaxe fica muito grande quando os nomes de tabela e de exibição tiverem que ser

qualificados completamente. Você pode resolver esse problema atribuindo um nome de correlação,

também conhecido como uma variável de intervalo ou alias, à tabela, usando a palavra-chave AS na

cláusula FROM. O nome de tabela ou de exibição completamente qualificado tem de ser especificado

apenas na cláusula FROM. Todas as outras referências a tabelas ou exibições podem então usar o

nome de correlação. Aplicar nomes de correlação e qualificar as tabelas completamente na amostra

anterior cria esta instrução SELECT:

Exemplo:

SELECT DISTINCT c.CustomerID, s.Name

FROM Sales.Customer AS c

JOIN

Sales.Store AS s

ON ( c.CustomerID = s.CustomerID)

WHERE c.TerritoryID = 1 Para obter mais informações sobre qualificação de objeto, consulte Identificadores.

Nos Manuais Online do SQL Server, muitos exemplos de Transact-SQL estão simplificados por não se

usarem nomes qualificados. Embora esses elementos não estejam incluídos nos exemplos, a fim de

facilitar a legibilidade, recomendamos que você use nomes qualificados em instruções Transact-SQL em sistemas de produção.

Page 4: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 4 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

Funções de agregação.

FUNÇÃO DESCRIÇÃO

MIN() Menor valor do conjunto de valores passados como parâmetro.

MAX() Maior valor do conjunto de valores passados como parâmetro.

AVG() Média normal do conjunto de valores passados como parâmetro.

SUM() Soma do conjunto de valores passados como parâmetro.

COUNT() Contador do tipo de valores passados como parâmetro.

Operadores lógicos.

OPERADOR DESCRIÇÃO

= Igualdade

<> Desigualdade

> Maior que

< Menor que

>= Maior ou igual a

<= Menor ou igual a

!> Não maoir que

!< Não menor que

!= Não igual

Fonte de pesquisa: http://go.microsoft.com/fwlink/?LinkID=127251

Page 5: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 5 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

2 - TRABALHANDO COM MÚLTIPLAS TABELAS

As condições de junção podem ser especificadas nas cláusulas FROM ou WHERE, sendo

recomendado que sejam especificadas na cláusula FROM. As cláusulas WHERE e HAVING também

podem conter critérios de pesquisa para filtrar ainda mais as linhas selecionadas pelas condições de junção.

As junções podem ser categorizadas como:

Junções internas (a operação de junção típica como a que usa algum operador de comparação como

= ou <>). Esses incluem junções naturais e junções por igualdade.

As junções internas usam um operador de comparação para relacionar duas tabelas com base nos

valores em colunas comuns de cada tabela. Por exemplo, ao recuperar todas as linhas em que o

número de identificação do aluno é o mesmo em ambas as tabelas alunos e cursos.

Junções externas. As junções externas pode ser uma junção externa esquerda, direita ou junção

externa completa.

As junções externas são especificadas com um dos seguintes conjuntos de palavras-chave quando

elas são especificadas na cláusula FROM:

LEFT JOIN ou LEFT OUTER JOIN

O conjunto de resultados de uma junção externa inclui todas as linhas de uma tabela esquerda

especificadas na cláusula LEFT OUTER, não somente aquelas nas quais as colunas unidas se

correspondem. Quando uma linha na tabela esquerda não possui linhas correspondentes na tabela

direita, a linha associada ao conjunto de resultados conterá valores nulos para todas as colunas da

lista de seleção vindos da tabela direita.

RIGHT JOIN ou RIGHT OUTER JOIN

Uma junção externa direita é o oposto de uma junção externa esquerda. São retornadas todas as

linhas da tabela direita. São retornados valores nulos para a tabela esquerda sempre que uma

tabela direita não possuir alguma linha de correspondência na tabela esquerda.

FULL JOIN ou FULL OUTER JOIN

Uma junção externa completa retorna todas as linhas em ambas as tabelas direita e esquerda.

Sempre que uma linha não tiver correspondência com a outra tabela, as colunas da lista de seleção

da outra tabela conterão valores nulos. Quando houver correspondência entre as tabelas, todas as

linhas do conjunto de resultados conterão valores de dados de tabelas base.

CROSS JOIN

Uma junção cruzada sem uma cláusula WHERE produz o produto cartesiano das tabelas envolvidas

na junção. O tamanho do conjunto de resultados do produto cartesiano é o número de linhas na

primeira tabela multiplicado pelo número de linhas na segunda tabela. O exemplo a seguir mostra

junção cruzada Transact-SQL.

Page 6: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 6 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

Exemplo:

USE AdventureWorks;

GO

SELECT p.SalesPersonID, t.Name AS Territory

FROM Sales.SalesPerson p

CROSS JOIN Sales.SalesTerritory t

ORDER BY p.SalesPersonID;

O conjunto de resultados contém 170 linhas (SalesPerson tem 17 linhas e SalesTerritory tem 10; 17

multiplicado por 10 é igual a 170).

Porém, se uma cláusula WHERE for adicionada, a junção cruzada se comportará como uma junção

interna. Por exemplo, a consulta Transact-SQL a seguir produz o mesmo conjunto de resultados.

Exemplo:

USE AdventureWorks;

GO

SELECT p.SalesPersonID, t.Name AS Territory

FROM Sales.SalesPerson p

CROSS JOIN Sales.SalesTerritory t

WHERE p.TerritoryID = t.TerritoryID

ORDER BY p.SalesPersonID;

-- Or

USE AdventureWorks;

GO

SELECT p.SalesPersonID, t.Name AS Territory

FROM Sales.SalesPerson p

INNER JOIN Sales.SalesTerritory t

ON p.TerritoryID = t.TerritoryID

ORDER BY p.SalesPersonID;

Fonte: http://go.microsoft.com/fwlink/?LinkID=127303

Page 7: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 7 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

3 - EXERCÍCIOS

1 - Selecione os nomes, em ordem alfabética, de todos os funcionários da Matriz (filial 1), bem como

o código da filial.

2 - Selecione o código do tipo de movimento, o nome, o valor bruto, numero do movimento e data

de emissão.

3 - Selecione a quantidade de ordem de compras agrupando pelo mês de emissão.

4 - Selecione a soma dos lançamentos financeiros a receber que estão em aberto agrupados por

fornecedor.

5 - Faça uma listagem de produtos contendo o código do produto, nome, unidade de controle,

unidade de venda, unidade de compra de todos os produtos da tabela de produtos. Ordenar os

produtos por código.

6 – Listagem de produtos que foram movimentados no mês de abril de 2005 no movimento de

ordem de compras, trazer o código do produto, nome fantasia, numero do movimento, data de

emissão e valor liquido.

7 – Liste os produtos que tiveram ordem de compra cujo o valor total do item seja maior que

1000(mil), trazer como informação: numero do movimento, numero de sequência, código do

produto, valor total.

8 – listar todas as ordens de compra que não estiverem canceladas e foram emitidas no mês de

fevereiro de 2006, trazendo o numero da ordem de compra, o valor bruto, valor liquido, subtotal.

Page 8: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 8 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

4 – TRABALHANDO COM FUNÇÕES

Funções escalares

As funções escalares definidas pelo usuário retornam um único valor de dados do tipo definido na

cláusula RETURNS. Para uma função escalar embutida, não há nenhum corpo de função; o valor

escalar é o resultado de uma única instrução. Para uma função escalar com várias instruções, o

corpo da função, definido em um bloco BEGIN…END, contém uma série de instruções do Transact-

SQL que retornam o valor único. O tipo de retorno pode ser em qualquer tipo de dados, exceto texto, ntext, imagem, cursor e carimbo de data/hora.

Funções com valor de tabela

As funções com valor de tabela definidas pelo usuário retornam um tipo de dados de tabela. Para

uma função com valor de tabela embutida, não há corpo de função; a tabela é o conjunto de resultados de uma única instrução SELECT.

Para uma função com valor de tabela com várias instruções, o corpo de função, definido em um

bloco BEGIN... END, contém uma série de instruções do Transact-SQL que criam e inserem linhas na tabela que será retornada.

Funções internas

As funções internas são fornecidas pelo SQL Server para ajudar você a executar uma variedade de

operações. Elas não podem ser modificadas. Você pode usar funções internas em instruções do Transact-SQL para:

Acessar informações de tabelas do sistema SQL Server sem acessar os tabelas do sistema

diretamente. Executar tarefas comuns como SUM, GETDATE ou IDENTITY.

Funções internas retornam os tipos de dados escalar ou de tabela. Por exemplo, @@ERROR retorna

0 se a última instrução do Transact-SQL tiver sido executada com êxito. Se a instrução gerou um

erro, @@ERROR retorna o número do erro. E a função SUM(parameter) retorna a soma de todos os valores do parâmetro.

Abaixo uma tabela contendo algumas funções internas que podem ser bastante úteis

Função Descrição

APP_NAME Retorna o nome do aplicativo para a sessão atual se definido pelo aplicativo

Expressão CASE Avalia uma lista de condições e retorna uma das várias expressões de

resultado possíveis.

CAST e CONVERT Converte uma expressão de um tipo de dados para outro.

Page 9: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 9 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

COALESCE Retorna a primeira expressão não nula entre seus argumentos.

COLLATIONPROPERTY Retorna a propriedade do agrupamento especificado.

COLUMNS_UPDATED Retorna um padrão de bit varbinary que indica as colunas de uma tabela

ou exibição que foram inseridas ou atualizadas.

CURRENT_TIMESTAMP Retorna o carimbo de data e hora do sistema do banco de dados atual como

um valor datetime sem o deslocamento de fuso horário do banco de dados.

CURRENT_USER Retorna o nome do usuário atual.

DATALENGTH Retorna o número de bytes usado para representar qualquer expressão. É

bem similar a função LEN()

Funções escalares

As funções escalares definidas pelo usuário retornam um valor único de dados do tipo definido na

cláusula RETURNS. Para uma função escalar embutida, não há um corpo de função; o valor escalar é

o resultado de uma única instrução. Para uma função escalar de várias instruções, o corpo da

função, definido em um bloco BEGIN...END, contém uma série de instruções Transact-SQL, que

retornam o valor único. O tipo de retorno pode ser qualquer tipo de dados, exceto text, ntext,

image, cursore timestamp.

Os exemplos a seguir criam uma função escalar de várias instruções. A função pega um valor de

entrada, um ProductID, e retorna um único valor de dados, a quantidade agregada do produto especificado no inventário.

Exemplo:

USE AdventureWorks2008R2;

GO

IF OBJECT_ID (N'dbo.ufnGetInventoryStock', N'FN') IS NOT NULL

DROP FUNCTION ufnGetInventoryStock;

GO

CREATE FUNCTION dbo.ufnGetInventoryStock(@ProductID int)

RETURNS int

AS

-- Returns the stock level for the product.

BEGIN

DECLARE @ret int;

SELECT @ret = SUM(p.Quantity)

FROM Production.ProductInventory p

WHERE p.ProductID = @ProductID

AND p.LocationID = '6';

IF (@ret IS NULL)

Page 10: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 10 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

SET @ret = 0;

RETURN @ret;

END;

GO

O exemplo a seguir usa a função ufnGetInventoryStock, para retornar a quantidade atual do

inventário dos produtos que têm um ProductModelIDentre 75 e 80.

Exemplo:

USE AdventureWorks2008R2;

GO

SELECT ProductModelID, Name, dbo.ufnGetInventoryStock(ProductID)AS CurrentSupply

FROM Production.Product

WHERE ProductModelID BETWEEN 75 and 80;

GO

Funções com valor de tabela

As funções com valor de tabela definidas pelo usuário retornam um tipo de dados table. Para uma

função com valor de tabela embutida, não há um corpo de função; a tabela é o conjunto de resultados de uma única instrução SELECT.

O exemplo a seguir cria uma função com valor de tabela embutida. A função pega um parâmetro de

entrada, um ID cliente (loja), e retorna as colunas ProductID, Name e a agregação das vendas do

ano, até a data atual, como YTD Total para cada produto vendido para a loja.

Exemplo:

USE AdventureWorks2008R2;

GO

IF OBJECT_ID (N'Sales.ufn_SalesByStore', N'IF') IS NOT NULL

DROP FUNCTION Sales.ufn_SalesByStore;

GO

CREATE FUNCTION Sales.ufn_SalesByStore (@storeid int)

RETURNS TABLE

AS

RETURN

(

SELECT P.ProductID, P.Name, SUM(SD.LineTotal) AS 'Total'

FROM Production.Product AS P

JOIN Sales.SalesOrderDetail AS SD ON SD.ProductID = P.ProductID

JOIN Sales.SalesOrderHeader AS SH ON SH.SalesOrderID = SD.SalesOrderID

JOIN Sales.Customer AS C ON SH.CustomerID = C.CustomerID

WHERE C.StoreID = @storeid

GROUP BY P.ProductID, P.Name

);

GO

O exemplo a seguir invoca a função e especifica a ID do cliente 602.

Page 11: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 11 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

Exemplo:

SELECT * FROM Sales.ufn_SalesByStore (602);

Para uma função com valor de tabela de várias instruções, o corpo da função definido em um bloco

BEGIN...END contém uma série de instruções Transact-SQL, que criam e inserem linhas na tabela que será retornada.

O exemplo a seguir cria uma função com valor de tabela. A função toma um único parâmetro de

entrada, um EmployeeID e retorna uma lista de todos os funcionários que reportam direta ou

indiretamente ao funcionário especificado. A função que especifica a ID do funcionário 109 é

invocada em seguida.

Exemplo:

USE AdventureWorks2008R2;

GO

IF OBJECT_ID (N'dbo.ufn_FindReports', N'TF') IS NOT NULL

DROP FUNCTION dbo.ufn_FindReports;

GO

CREATE FUNCTION dbo.ufn_FindReports (@InEmpID INTEGER)

RETURNS @retFindReports TABLE

(

EmployeeID int primary key NOT NULL,

FirstName nvarchar(255) NOT NULL,

LastName nvarchar(255) NOT NULL,

JobTitle nvarchar(50) NOT NULL,

RecursionLevel int NOT NULL

)

--Returns a result set that lists all the employees who report to the

--specific employee directly or indirectly.*/

AS

BEGIN

WITH EMP_cte(EmployeeID, OrganizationNode, FirstName, LastName, JobTitle, RecursionLevel) --

CTE name and columns

AS (

SELECT e.BusinessEntityID, e.OrganizationNode, p.FirstName, p.LastName, e.JobTitle, 0 -- Get

the initial list of Employees for Manager n

FROM HumanResources.Employee e

INNER JOIN Person.Person p

ON p.BusinessEntityID = e.BusinessEntityID

WHERE e.BusinessEntityID = @InEmpID

UNION ALL

SELECT e.BusinessEntityID, e.OrganizationNode, p.FirstName, p.LastName, e.JobTitle,

RecursionLevel + 1 -- Join recursive member to anchor

FROM HumanResources.Employee e

INNER JOIN EMP_cte

ON e.OrganizationNode.GetAncestor(1) = EMP_cte.OrganizationNode

INNER JOIN Person.Person p

ON p.BusinessEntityID = e.BusinessEntityID

)

-- copy the required columns to the result of the function

INSERT @retFindReports

Page 12: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 12 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel

FROM EMP_cte

RETURN

END;

GO

-- Example invocation

SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel

FROM dbo.ufn_FindReports(1);

GO

Fonte: http://msdn.microsoft.com/en-us/library/ms177499.aspx

Page 13: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 13 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

5 – TRABALHANDO COM PROCEDIMENTOS

Você pode criar procedimentos armazenados usando a instrução CREATE PROCEDURE Transact-SQL.

Antes de criar um procedimento armazenado, considere que:

As instruções CREATE PROCEDURE não podem ser combinadas com outras instruções SQL

em um único lote.

Para criar procedimentos, você deve ter a permissão CREATE PROCEDURE no banco de dados

e a permissão ALTER no esquema no qual o procedimento está sendo criado. Para

procedimentos armazenados CLR, você deve possuir assembly referenciado em

<método_especificador> ou ter a permissão REFERENCES nesse assembly.

Os procedimentos armazenados são objetos no escopo do esquema e seus nomes devem

seguir as regras para identificadores.

Você só pode criar um procedimento armazenado no banco de dados atual.

Ao criar um procedimento armazenado, você deve especificar:

Qualquer parâmetro de entrada e saída para o procedimento de chamada ou lote.

As instruções de programação que executam operações no banco de dados, inclusive de

chamada de outros procedimentos.

O valor de status retornado ao procedimento ou lote de chamada para indicar sucesso ou

falha (e o motivo da falha).

Qualquer instrução de tratamento de erros necessária para detectar e tratar erros potenciais.

As funções de tratamento de erros como ERROR_LINE e ERROR_PROCEDURE podem ser

especificadas no procedimento armazenado. Para obter mais informações, consulte Usando

TRY...CATCH em Transact-SQL.

Nomeando procedimentos armazenados

Recomendamos que você não crie qualquer procedimento armazenado usando sp_ como um

prefixo. SQL Server usa o prefixo sp_ para designar procedimentos armazenados do sistema. O

nome escolhido pode estar em conflito com algum procedimento de sistema futuro. Se seu aplicativo

usar referências de nome qualificado fora do esquema e seu nome de procedimento conflitar com

um nome de procedimento do sistema, seu aplicativo falhará, pois o nome será associado ao procedimento do sistema, não ao seu.

Um procedimento armazenado definido pelo usuário que possui o mesmo nome como um

procedimento armazenado do sistema que seja não qualificado ou estiver no esquema dbo nunca

será executado; em vez disso será executado sempre o procedimento armazenado do sistema. O

exemplo a seguir demonstra esse comportamento.

Exemplo:

USE AdventureWorks;

Page 14: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 14 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

GO

CREATE PROCEDURE dbo.sp_who

AS

SELECT FirstName, LastName FROM Person.Contact;

GO

EXEC sp_who;

EXEC dbo.sp_who;

GO

DROP PROCEDURE dbo.sp_who;

GO

Usar um qualificador de esquema explícito também proporciona uma pequena vantagem de

desempenho. A resolução de nome será ligeiramente mais rápida se o Mecanismo de Banco de

Dados não tiver que pesquisar vários esquemas para localizar o procedimento. Para obter mais

informações, consulte Executando um procedimento armazenado.

Procedimentos armazenados temporários

Os procedimentos armazenados temporários privativos e globais, de maneira análoga às tabelas

temporárias, podem ser criados com os prefixos # e ## adicionados ao nome do procedimento. #

denota um procedimento armazenado temporário local; ## denota um procedimento armazenado temporário global. Esses procedimentos não existem após SQL Server ser desligado.

Os procedimentos armazenados temporários são úteis na conexão com versões anteriores de SQL

Server que não oferecem suporte ao reuso de plano de execução para instruções ou lotes Transact-

SQL. Os aplicativos que se conectam ao SQL Server 2000 e versões posteriores devem usar o

procedimento armazenado do sistema sp_executesql em vez de procedimentos armazenados

temporários. Apenas a conexão que criou um procedimento temporário local poderá executá-lo e o procedimento será automaticamente excluído quando a conexão for fechada.

Qualquer conexão pode executar um procedimento armazenado temporário global. Um

procedimento armazenado temporário global existe até que a conexão usada pelo usuário que criou

o procedimento seja fechada e qualquer versão do procedimento sendo executada por qualquer

outra conexão seja concluída. Depois que a conexão usada para criar o procedimento for fechada,

nenhuma execução adicional do procedimento armazenado temporário global será permitida.

Apenas a conclusão das conexões que já começaram a executar o procedimento armazenado será

permitida.

Se um procedimento armazenado não precedido por # ou ## for criado diretamente no banco de

dados tempdb, o procedimento armazenado será excluído automaticamente quando SQL Server for

desligado, pois tempdb será recriado cada vez em que SQL Server for iniciado. Os procedimentos

criados diretamente em tempdb existirão mesmo depois que a criação da conexão estiver terminada.

Observação:

O uso intenso de procedimentos armazenados temporários pode criar contenção nas tabelas do

sistema em tempdb e afetar o desempenho adversamente. É recomendado usar

sp_executesql. sp_executesql não armazena dados nas tabelas do sistema, evitando o

problema.

Os procedimentos armazenados CLR não podem ser criados como procedimentos armazenados

temporários.

Page 15: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 15 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

Exemplos

A. Usando um procedimento simples com um SELECT complexo

O procedimento armazenado a seguir retorna todos os funcionários (com os nomes e sobrenomes

fornecidos), cargos e nomes de departamento em uma exibição. Esse procedimento armazenado

não usa nenhum parâmetro.

Exemplo:

USE AdventureWorks;

GO

IF OBJECT_ID ( 'HumanResources.uspGetAllEmployees', 'P' ) IS NOT NULL

DROP PROCEDURE HumanResources.uspGetAllEmployees;

GO

CREATE PROCEDURE HumanResources.uspGetAllEmployees

AS

SET NOCOUNT ON;

SELECT LastName, FirstName, JobTitle, Department

FROM HumanResources.vEmployeeDepartment;

GO O procedimento armazenado uspGetEmployees pode ser executado das seguintes maneiras:

Exemplo:

EXECUTE HumanResources.uspGetAllEmployees;

GO

-- Or

EXEC HumanResources.uspGetAllEmployees;

GO

-- Or, if this procedure is the first statement within a batch:

HumanResources.uspGetAllEmployees;

B. Usando um procedimento simples com parâmetros

O procedimento armazenado a seguir retorna somente o funcionário especificado (com nome e

sobrenome fornecidos), cargo e nome de departamento em uma exibição. Esse procedimento armazenado aceita correspondências exatas para os parâmetros passados.

Exemplo:

USE AdventureWorks;

GO

IF OBJECT_ID ( 'HumanResources.uspGetEmployees', 'P' ) IS NOT NULL

DROP PROCEDURE HumanResources.uspGetEmployees;

GO

CREATE PROCEDURE HumanResources.uspGetEmployees

@LastName nvarchar(50),

@FirstName nvarchar(50)

AS

SET NOCOUNT ON;

SELECT FirstName, LastName, JobTitle, Department

FROM HumanResources.vEmployeeDepartment

WHERE FirstName = @FirstName AND LastName = @LastName;

GO

Page 16: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 16 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

O procedimento armazenado uspGetEmployees pode ser executado das seguintes maneiras:

Exemplo:

EXECUTE HumanResources.uspGetEmployees N'Ackerman', N'Pilar';

-- Or

EXEC HumanResources.uspGetEmployees @LastName = N'Ackerman', @FirstName = N'Pilar';

GO

-- Or

EXECUTE HumanResources.uspGetEmployees @FirstName = N'Pilar', @LastName = N'Ackerman';

GO

-- Or, if this procedure is the first statement within a batch:

HumanResources.uspGetEmployees N'Ackerman', N'Pilar';

C. Usando um procedimento simples com parâmetros de curinga

O procedimento armazenado a seguir retorna somente os funcionários especificados (com os nomes

e sobrenomes fornecidos), cargos e departamentos em uma exibição. O padrão desse procedimento

armazenado corresponde aos parâmetros passados ou, quando não fornecidos, usa o padrão predefinido (sobrenomes que começam com a letra D).

Exemplo:

USE AdventureWorks;

GO

IF OBJECT_ID ( 'HumanResources.uspGetEmployees2', 'P' ) IS NOT NULL

DROP PROCEDURE HumanResources.uspGetEmployees2;

GO

CREATE PROCEDURE HumanResources.uspGetEmployees2

@LastName nvarchar(50) = N'D%',

@FirstName nvarchar(50) = N'%'

AS

SET NOCOUNT ON;

SELECT FirstName, LastName, JobTitle, Department

FROM HumanResources.vEmployeeDepartment

WHERE FirstName LIKE @FirstName AND LastName LIKE @LastName;

GO

O procedimento armazenado uspGetEmployees2 pode ser executado em muitas combinações. Apenas algumas combinações são mostradas aqui:

Exemplo:

EXECUTE HumanResources.uspGetEmployees2;

-- Or

EXECUTE HumanResources.uspGetEmployees2 N'Wi%';

-- Or

EXECUTE HumanResources.uspGetEmployees2 @FirstName = N'%';

-- Or

EXECUTE HumanResources.uspGetEmployees2 N'[CK]ars[OE]n';

-- Or

EXECUTE HumanResources.uspGetEmployees2 N'Hesse', N'Stefen';

-- Or

EXECUTE HumanResources.uspGetEmployees2 N'H%', N'S%';

Page 17: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 17 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

D. Usando parâmetros OUTPUT

O exemplo a seguir cria o procedimento armazenado uspGetList, que retorna uma lista dos produtos

com preços que não excedem um valor especificado. O exemplo mostra o uso de várias instruções

SELECT e vários parâmetros OUTPUT. Os parâmetros OUTPUT permitem que um procedimento

externo, um lote ou mais de uma instrução Transact-SQL acessem um valor definido durante a execução do procedimento.

Exemplo:

USE AdventureWorks;

GO

IF OBJECT_ID ( 'Production.uspGetList', 'P' ) IS NOT NULL

DROP PROCEDURE Production.uspGetList;

GO

CREATE PROCEDURE Production.uspGetList @Product varchar(40)

, @MaxPrice money

, @ComparePrice money OUTPUT

, @ListPrice money OUT

AS

SET NOCOUNT ON;

SELECT p.[Name] AS Product, p.ListPrice AS 'List Price'

FROM Production.Product AS p

JOIN Production.ProductSubcategory AS s

ON p.ProductSubcategoryID = s.ProductSubcategoryID

WHERE s.[Name] LIKE @Product AND p.ListPrice < @MaxPrice;

-- Populate the output variable @ListPprice.

SET @ListPrice = (SELECT MAX(p.ListPrice)

FROM Production.Product AS p

JOIN Production.ProductSubcategory AS s

ON p.ProductSubcategoryID = s.ProductSubcategoryID

WHERE s.[Name] LIKE @Product AND p.ListPrice < @MaxPrice);

-- Populate the output variable @compareprice.

SET @ComparePrice = @MaxPrice;

GO

Execute uspGetList para retornar uma lista de produtos (bicicletas) da Adventure Works que custam

menos que $ 700. Os parâmetros OUTPUT @Cost e @ComparePrices são usados com linguagem

de controle de fluxo para retornar uma mensagem na janela Mensagens.

Observação:

A variável OUTPUT deve ser definida durante a criação do procedimento como também durante o

uso da variável. O nome do parâmetro e da variável não precisam ser correspondentes;

entretanto, o tipo de dados e o posicionamento do parâmetro devem corresponder (a menos que

@ListPrice = variable seja usado).

Exemplo:

DECLARE @ComparePrice money, @Cost money

EXECUTE Production.uspGetList '%Bikes%', 700,

@ComparePrice OUT,

Page 18: Consultas SQL

Desenvolvido por: Alexandre G. Silva Pág. 18 de 18 TOTVS – ES 04/09/2010

Consultas SQL Server

@Cost OUTPUT

IF @Cost <= @ComparePrice

BEGIN

PRINT 'These products can be purchased for less than

$'+RTRIM(CAST(@ComparePrice AS varchar(20)))+'.'

END

ELSE

PRINT 'The prices for all products in this category exceed

$'+ RTRIM(CAST(@ComparePrice AS varchar(20)))+'.' Eis o conjunto parcial dos resultados:

Exemplo:

Product List Price

-------------------------------------------------- ------------------

Road-750 Black, 58 539.99

Mountain-500 Silver, 40 564.99

Mountain-500 Silver, 42 564.99

...

Road-750 Black, 48 539.99

Road-750 Black, 52 539.99

(14 row(s) affected)

These items can be purchased for less than $700.00.

Fonte: http://technet.microsoft.com/en-us/library/ms190669(SQL.100).aspx