Въведение
Изгледът в SQL Server е структура, подобна на виртуална таблица, базирана на набора от резултати на SQL израз. На повърхността изгледът е подобен на таблица със сигнатурна структура на редове и колони. Тези редове и колони обаче идват от таблици, посочени в заявката, която дефинира изгледа.
Ние използваме Views, за да се фокусираме върху конкретните колони за целите, за които са създадени. Прегледите може да служат и от съображения за сигурност. Те филтрират колони в основните таблици, които човек не иска да направи видими за определени потребители. Преглед на филтриращи колони като клауза WHERE филтрира редове.
Друга причина за Views е простотата. Те обединяват колони от няколко различни таблици и създават общ вид, който изглежда като една таблица.
Типове изгледи
Основните потребителски дефинирани изгледи са лесни за създаване. Процесът е подобен на писане на заявки, които препращат към една или повече таблици.
- Индексираните изгледи са тези, които са материализирани или съхранени като таблица. Индексираните изгледи могат да подобрят производителността на заявки, които обединяват много редове. Те обаче не са подходящи, ако основните таблици се актуализират често.
- Разделените изгледи обединяват хоризонтално разделени данни от таблици локално (в рамките на един екземпляр) или в много, като използват свързани сървъри.
- Системните изгледи са често срещаните структури, които SQL Server използва, за да разкрие метаданните на каталога. Системните изгледи са повечето от онези структури, за които се изисква търсене за отстраняване на неизправности в производителността или изследване на екземпляр на SQL Server.
Създаване на изглед от една маса
Разгледайте примера в листинг 1. Първият израз връща ВСИЧКИ записи в таблицата Purchasing.PurchaseOrders (1a), докато втората заявка връща само няколко колони (1b).
Използвайки втората заявка, можем да създадем изглед, който връща същия набор от резултати като (1b). Когато направим това, можем да отправим заявка към изглед, за да получим желания изход. По този начин ние опростяваме заявката за краен потребител.
-- 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 ;
Създаване на изглед от две маси
Използвайки JOIN, можем да извлечем данни от две или повече таблици, които имат връзка. Използвайки Views, можем да опростим достъпа до такива данни.
Списък 2 (2a) показва JOIN между Purchasing.PurchaseOrders и Purchasing.PurchaseOrderLines. Можем да създадем изглед от това JOIN и това ще ни позволи да извлечем същите данни с помощта на заявка, както е показано в (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;
Създаване на изглед в различни бази данни
Използвайки многочастно именуване, можем да препращаме таблици в различна база данни. Следователно можем да правим JOIN в базите данни и да създаваме изгледи, които обхващат бази данни. Полезно е за определени приложения, които разпространяват своите данни в бази данни в същия екземпляр на SQL Server.
Списък 3 показва подобен случай като листинг 2, но с разлика:добавяме трета таблица към JOIN заявката от друга база данни. Забележете, че трябва да използваме LEFT OUTER JOIN, тъй като не съществува реална връзка между таблиците и в двете бази данни. Тук го използваме само за да илюстрираме създаването на ИЗГЛЕД, който обхваща различни бази данни.
Въведохме псевдоним в израза CREATE VIEW, тъй като имаме колони от две различни таблици със същото име. В такива случаи трябва да разграничим тези колони.
-- 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;
Вижте Фигура 1. Тя показва резултата от изпълнението на листинг 3(3c). Имайте предвид, че последните три колони са празни, тъй като TSQLV4.Sales.Orders таблицата няма редове, отговарящи на условието JOIN.
Създаване на изглед между екземпляри
Можем да разширим последното изявление, като представим таблица, която живее изцяло в друг екземпляр.
За да постигнем това, първо трябва да създадем свързан сървър. Правим го с кода, подобен на този, показан в листинг 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
Забележете как адресираме външната таблица, използвайки име от четири части:
-- 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;
Включване на функции в изгледи
Тъй като Views по същество са заявки, можем да приложим към тях почти всичко, което правим с обикновени заявки. Можем да включим функции, WHERE клаузи, CASE изрази, псевдоними и т.н.
Клаузата ORDER BY обаче не е разрешена, освен че използвате „ТОП 100 хак“. Списъци от 6 до 9 илюстрират използването на тези клаузи във 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
Индексирани изгледи
По-рано в статията споменахме индексирани изгледи. Индексираните изгледи могат да подобрят производителността, с изключение на случаите, когато основните таблици изискват интензивно писане. SQL Server изисква активирани определени опции SET, преди да създадете индексирани изгледи или да извършите определени операции върху тях.
Клаузата WITH SCHEMABINDING трябва да се използва при създаване на изглед за поставяне на индекс върху него. Тази клауза асоциира изгледа стриктно с основните обекти. По този начин такива обекти не могат да бъдат изпускани.
-- 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);
Заключение
В тази статия разгледахме изгледите на известно ниво на детайлност. Накратко разгледахме видовете изгледи и дадохме няколко примера за потребителски дефинирани изгледи и как използвахме JOIN, за да реализираме изгледи, които зависят от много таблици. Ние също така обхванахме сложни изгледи, които включват функции, както и индексирани изгледи.
Препратки
- Прегледи
- Индексирани изгледи
- Създаване на индексирани изгледи в SQL Server