Introdução
Uma exibição no SQL Server é uma estrutura semelhante a uma tabela virtual baseada no conjunto de resultados de uma instrução SQL. Na superfície, uma exibição é semelhante a uma tabela com a estrutura de assinatura de linhas e colunas. No entanto, essas linhas e colunas vêm de tabelas referenciadas na consulta, que define a exibição.
Usamos Views para focar nos pilares de concreto para os propósitos para os quais foram criados. As visualizações também podem servir por motivos de segurança. Eles filtram as colunas nas tabelas subjacentes que não se deseja tornar visíveis para determinados usuários. Exibe colunas de filtro como uma cláusula WHERE filtra linhas.
Outra razão para Views é a simplicidade. Eles agregam colunas de várias tabelas diferentes e criam uma aparência geral que se parece com uma única tabela.
Tipos de visualizações
As visualizações básicas definidas pelo usuário são fáceis de criar. O processo é semelhante a escrever consultas que fazem referência a uma ou mais tabelas.
- As visualizações indexadas são aquelas que foram materializadas ou armazenadas como uma tabela. Visualizações indexadas podem melhorar o desempenho de consultas que agregam muitas linhas. No entanto, eles não são adequados se as tabelas subjacentes forem atualizadas com frequência.
- As visualizações particionadas unem dados particionados horizontalmente de tabelas localmente (dentro da mesma instância) ou em várias, usando servidores vinculados.
- As exibições do sistema são as estruturas comuns que o SQL Server usa para expor os metadados do catálogo. As exibições do sistema são a maioria dessas estruturas consultadas para solucionar problemas de desempenho ou investigar uma instância do SQL Server.
Criando uma visualização de uma tabela
Dê uma olhada no exemplo na Listagem 1. A primeira instrução retorna TODOS os registros na tabela Purchasing.PurchaseOrders (1a), enquanto a segunda consulta retorna apenas algumas colunas (1b).
Usando a segunda consulta, podemos criar uma View que retorna o mesmo conjunto de resultados que (1b). Quando fazemos isso, podemos consultar uma View para obter a saída desejada. Assim, simplificamos a consulta para um usuário final.
-- Listing 1: Creating a Basic User-Defined View
-- 1a
SELECT * FROM
Purchasing.PurchaseOrders;
-- 1b
SELECT
PurchaseOrderID
, SupplierID
, OrderDate
, ExpectedDeliveryDate
FROM Purchasing.PurchaseOrders;
-- 1c
CREATE VIEW Purchasing.QuickOrders
AS
SELECT
PurchaseOrderID
, SupplierID
, OrderDate
, ExpectedDeliveryDate
FROM Purchasing.PurchaseOrders;
-- 1d
SELECT * FROM Purchasing.QuickOrders ;
Criando uma visualização a partir de duas tabelas
Usando JOINs, podemos recuperar dados de duas ou mais tabelas que possuem um relacionamento. Usando Views, podemos simplificar o acesso a esses dados.
A Listagem 2 (2a) mostra um JOIN entre Purchasing.PurchaseOrders e Purchasing.PurchaseOrderLines. Podemos criar uma View a partir deste JOIN, e isso nos permitirá recuperar os mesmos dados usando uma consulta, conforme mostrado em (2c).
-- Listing 2: Creating a View from Two Tables
-- 2a
SELECT
po.PurchaseOrderID
, po.SupplierID
, po.OrderDate
, po.ExpectedDeliveryDate
, pol.Description
, pol.ExpectedUnitPricePerOuter
FROM Purchasing.PurchaseOrders po
INNER JOIN Purchasing.PurchaseOrderLines pol
ON po.PurchaseOrderID=pol.PurchaseOrderID;
-- 2b
CREATE VIEW Purchasing.DetailedOrders
AS
SELECT
po.PurchaseOrderID
, po.SupplierID
, po.OrderDate
, po.ExpectedDeliveryDate
, pol.Description
, pol.ExpectedUnitPricePerOuter
FROM Purchasing.PurchaseOrders po
INNER JOIN Purchasing.PurchaseOrderLines pol
ON po.PurchaseOrderID=pol.PurchaseOrderID;
-- 2c
SELECT * FROM Purchasing.DetailedOrders;
Criando uma exibição em bancos de dados
Usando a nomenclatura de várias partes, podemos referenciar tabelas em um banco de dados diferente. Portanto, podemos fazer JOINs nos bancos de dados e criar Views que abrangem bancos de dados. É útil para determinados aplicativos que distribuem seus dados entre bancos de dados na mesma instância do SQL Server.
A Listagem 3 mostra um caso semelhante à Listagem 2, mas com uma diferença:adicionamos uma terceira tabela à consulta JOIN de um banco de dados diferente. Observe que temos que usar um LEFT OUTER JOIN já que não existe nenhum relacionamento real entre as tabelas em ambos os bancos de dados. Aqui, usamos apenas para ilustrar a criação de uma VIEW que abrange diferentes bancos de dados.
Introduzimos um alias na instrução CREATE VIEW, pois temos colunas de duas tabelas diferentes com o mesmo nome. Devemos distinguir essas colunas em tais casos.
-- Listing 3: Creating a View Across Databases
-- 3a
SELECT
po.PurchaseOrderID
,po.SupplierID
,po.OrderDate
,po.ExpectedDeliveryDate
,pol.Description
,pol.ExpectedUnitPricePerOuter
,so.orderid
,so.custid
,so.orderdate
FROM Purchasing.PurchaseOrders po
INNER JOIN Purchasing.PurchaseOrderLines pol
ON po.PurchaseOrderID=pol.PurchaseOrderID
LEFT OUTER JOIN TSQLV4.Sales.Orders so
ON po.PurchaseOrderID=so.orderid;
-- 3b
CREATE VIEW Purchasing.DetailedOrdersDistributed
AS
SELECT
po.PurchaseOrderID
,po.SupplierID
,po.OrderDate
,po.ExpectedDeliveryDate
,pol.Description
,pol.ExpectedUnitPricePerOuter
,so.orderid
,so.custid
,so.orderdate AS OrdersOrderDate
FROM Purchasing.PurchaseOrders po
INNER JOIN Purchasing.PurchaseOrderLines pol
ON po.PurchaseOrderID=pol.PurchaseOrderID
LEFT OUTER JOIN TSQLV4.Sales.Orders so
ON po.PurchaseOrderID=so.orderid;
-- 3c
SELECT * FROM Purchasing.DetailedOrdersDistributed;
Dê uma olhada na Figura 1. Ela mostra o resultado da execução da Listagem 3(3c). Observe que as três últimas colunas estão vazias, pois TSQLV4.Sales.Orders A tabela não tem nenhuma linha que corresponda à condição JOIN.
Criando uma visualização entre instâncias
Podemos estender a última declaração introduzindo uma tabela que vive inteiramente em outra instância.
Para conseguir isso, devemos primeiro criar um Servidor Vinculado. Fazemos isso com o código semelhante ao mostrado na Listagem 4.
-- Listing 4: Linked Server
USE [master]
GO
EXEC master.dbo.sp_addlinkedserver @server = N'IGIRI01\SQLEXPRESS', @srvproduct=N'SQL Server'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'IGIRI01\SQLEXPRESS',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
GO
Observe como abordamos a tabela externa usando um nome de quatro partes:
-- Listing 5: Creating a View Across Instances
-- 5a
CREATE VIEW Purchasing.DetailedOrdersExternal
AS
SELECT
po.PurchaseOrderID
,po.SupplierID
,po.OrderDate
,po.ExpectedDeliveryDate
,pol.Description
,pol.ExpectedUnitPricePerOuter
,ipol.StockItemID
,ipol.LastEditedWhen
FROM Purchasing.PurchaseOrders po
INNER JOIN Purchasing.PurchaseOrderLines pol
ON po.PurchaseOrderID=pol.PurchaseOrderID
INNER JOIN [IGIRI01\SQLEXPRESS].[WWI].[Purchasing].[PurchaseOrderLines] ipol
ON po.PurchaseOrderID=ipol.PurchaseOrderID;
-- 5b
SELECT * FROM Purchasing.DetailedOrdersExternal;
Incluindo funções nas visualizações
Como as visualizações são essencialmente consultas, podemos aplicar a elas quase tudo o que fazemos com consultas regulares. Podemos incluir funções, cláusulas WHERE, expressões CASE, aliases, etc.
No entanto, a cláusula ORDER BY não é permitida, exceto que você usa o “TOP 100 hack”. As Listagens 6 a 9 ilustram o uso dessas cláusulas em Views.
-- Listing 6: Creating a View with a Function
CREATE VIEW Purchasing.DetailedOrdersComplex
AS
SELECT
ipol.PurchaseOrderID
,ipol.Description
,ipol.ExpectedUnitPricePerOuter
,ipol.StockItemID
,CONVERT(VARCHAR, LastEditedWhen, 113) AS LastEditedLongDate
FROM [IGIRI01\SQLEXPRESS].[WWI].[Purchasing].[PurchaseOrderLines] ipol
-- Listing 7: Creating a View with a WHERE Clause
CREATE VIEW Purchasing.DetailedOrdersComplexFilt
AS
SELECT
ipol.PurchaseOrderID
,ipol.Description
,ipol.ExpectedUnitPricePerOuter
,ipol.StockItemID
,CONVERT(VARCHAR, LastEditedWhen, 113) AS LastEditedLongDate
FROM [IGIRI01\SQLEXPRESS].[WWI].[Purchasing].[PurchaseOrderLines] ipol
WHERE ipol.PurchaseOrderID<10;
-- Listing 8: Creating a View a TOP Clause
CREATE VIEW Purchasing.DetailedOrdersComplexTop
AS
SELECT TOP 10
ipol.PurchaseOrderID
,ipol.Description
,ipol.ExpectedUnitPricePerOuter
,ipol.StockItemID
,CONVERT(VARCHAR, LastEditedWhen, 113) AS LastEditedLongDate
FROM [IGIRI01\SQLEXPRESS].[WWI].[Purchasing].[PurchaseOrderLines] ipol
-- Listing 9: Creating a View with a CASE Expression
CREATE VIEW Purchasing.DetailedOrdersComplexTop
AS
SELECT TOP 10
CASE
ipol.PurchaseOrderID
WHEN 1 THEN 'First Order'
WHEN 2 THEN 'Second Order'
END PurchaseOrder
,ipol.Description
,ipol.ExpectedUnitPricePerOuter
,ipol.StockItemID
,CONVERT(VARCHAR, LastEditedWhen, 113) AS LastEditedLongDate
FROM [IGIRI01\SQLEXPRESS].[WWI].[Purchasing].[PurchaseOrderLines] ipol
Visualizações Indexadas
Referimo-nos a Visualizações Indexadas anteriormente neste artigo. As exibições indexadas podem melhorar o desempenho, exceto nos casos em que as tabelas subjacentes exigem muita gravação. O SQL Server requer determinadas opções de SET habilitadas antes de criar exibições indexadas ou executar determinadas operações nelas.
A cláusula WITH SCHEMABINDING deve ser usada ao criar uma View para colocar um índice nela. Esta cláusula associa a View estritamente aos objetos subjacentes. Assim, tais objetos não podem ser descartados.
-- Listing 10: Creating an Indexed View
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT, QUOTED_IDENTIFIER, ANSI_NULLS ON;
CREATE VIEW Purchasing.DetailedOrdersIndexed
WITH SCHEMABINDING
AS
SELECT
po.PurchaseOrderID
,po.SupplierID
,po.OrderDate
,po.ExpectedDeliveryDate
FROM Purchasing.PurchaseOrders po;
CREATE UNIQUE CLUSTERED INDEX IX_ID
ON Purchasing.DetailedOrdersIndexed (PurchaseOrderID);
Conclusão
Neste artigo, examinamos as visualizações em algum nível de detalhe. Cobrimos brevemente os tipos de Views e demos vários exemplos de views definidas pelo usuário e como usamos JOINs para realizar views que dependem de muitas tabelas. Também abordamos visualizações complexas que incluem funções e visualizações indexadas.
Referências
- Visualizações
- Visualizações Indexadas
- Criar exibições indexadas no SQL Server