Introduktion
En vy i SQL Server är en virtuell tabellliknande struktur baserad på resultatuppsättningen av en SQL-sats. På ytan liknar en vy en tabell med signaturstrukturen av rader och kolumner. Dessa rader och kolumner kommer dock från tabeller som refereras till i frågan, som definierar vyn.
Vi använder Views för att fokusera på de konkreta kolumnerna för de syften de är skapade för. Visningar kan också tjäna av säkerhetsskäl. De filtrerar bort kolumner i de underliggande tabellerna som man inte vill göra synliga för vissa användare. Visar filterkolumner som en WHERE-sats filtrerar rader.
En annan anledning till Views är enkelheten. De samlar kolumner från flera olika tabeller och skapar ett allmänt utseende som ser ut som en enda tabell.
Typer av visningar
Grundläggande användardefinierade vyer är lätta att skapa. Processen liknar att skriva frågor som refererar till en eller flera tabeller.
- Indexerade vyer är de som har materialiserats eller lagrats som en tabell. Indexerade vyer kan förbättra prestandan för frågor som samlar många rader. De är dock inte lämpliga om underliggande tabeller uppdateras ofta.
- Partitionerade vyer sammanfogar horisontellt partitionerade data från tabeller lokalt (inom samma instans) eller över många, med hjälp av länkade servrar.
- Systemvyer är de vanliga strukturerna som SQL Server använder för att exponera katalogens metadata. Systemvyer är de flesta av de strukturer man frågar efter för att felsöka prestanda eller undersöka en SQL Server-instans.
Skapa en vy från ett bord
Ta en titt på exemplet i Lista 1. Den första satsen returnerar ALLA poster i tabellen Purchasing.PurchaseOrders (1a), medan den andra frågan endast returnerar ett fåtal kolumner (1b).
Med den andra frågan kan vi skapa en vy som returnerar samma resultatuppsättning som (1b). När vi gör detta kan vi fråga en vy för att få önskad utdata. Därför förenklar vi frågan för en slutanvändare.
-- 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 ;
Skapa en vy från två tabeller
Med JOINs kan vi hämta data från två eller flera tabeller som har en relation. Genom att använda Views kan vi förenkla åtkomsten till sådan data.
Lista 2 (2a) visar en JOIN mellan Purchasing.PurchaseOrders och Purchasing.PurchaseOrderLines. Vi kan skapa en vy från denna JOIN, och den gör att vi kan hämta samma data med hjälp av en fråga, som visas i (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;
Skapa en vy över databaser
Genom att använda flerdelat namngivning kan vi referera till tabeller i en annan databas. Därför kan vi göra JOINs över databaserna och skapa vyer som spänner över databaser. Det är användbart för vissa applikationer som sprider sina data över databaser i samma SQL Server-instans.
Lista 3 visar ett liknande fall som listning 2, men med en skillnad:vi lägger till en tredje tabell till JOIN-frågan från en annan databas. Lägg märke till att vi måste använda en LEFT OUTER JOIN eftersom det inte finns någon verklig relation mellan tabellerna i båda databaserna. Här använder vi det bara för att illustrera att skapa en VIEW som spänner över olika databaser.
Vi har introducerat ett alias i CREATE VIEW-satsen, eftersom vi har kolumner från två olika tabeller med samma namn. Vi måste särskilja dessa kolumner i sådana fall.
-- 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;
Ta en titt på figur 1. Den visar resultatet av exekvering av Listing 3(3c). Observera att de tre sista kolumnerna är tomma, eftersom TSQLV4.Sales.Orders Tabellen har inga rader som matchar JOIN-villkoret.
Skapa en vy över instanser
Vi kan förlänga det sista påståendet genom att introducera en tabell som helt och hållet lever i en annan instans.
För att uppnå detta måste vi först skapa en länkad server. Vi gör det med koden som liknar den som visas i Lista 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
Lägg märke till hur vi adresserar den externa tabellen med ett fyrdelat namn:
-- 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;
Inkludera funktioner i vyer
Eftersom vyer i huvudsak är frågor, kan vi tillämpa på dem nästan allt vi gör med vanliga frågor. Vi kan inkludera funktioner, WHERE-satser, CASE-uttryck, alias, etc.
ORDER BY-klausulen är dock inte tillåten, förutom att du använder "TOP 100-hacket". Listorna 6 till 9 illustrerar användningen av dessa klausuler i 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
Indexerade vyer
Vi hänvisade till Indexerade vyer tidigare i artikeln. Indexerade vyer kan förbättra prestandan, förutom de fall där underliggande tabeller är skrivintensiva. SQL Server kräver att vissa SET-alternativ är aktiverade innan du skapar indexerade vyer eller utför vissa operationer på dem.
WITH SCHEMABINDING-satsen ska användas när du skapar en vy för att sätta ett index på den. Denna sats associerar vyn strikt med de underliggande objekten. Sådana objekt kan alltså inte släppas.
-- 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);
Slutsats
I den här artikeln har vi undersökt synpunkter på någon detaljnivå. Vi täckte kortfattat typer av vyer och gav flera exempel på användardefinierade vyer och hur vi använde JOINs för att realisera vyer som beror på många tabeller. Vi täckte också komplexa vyer som inkluderar funktioner såväl som indexerade vyer.
Referenser
- Visningar
- Indexerade vyer
- Skapa indexerade vyer i SQL Server