Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Viste in SQL Server

Introduzione

Una vista in SQL Server è una struttura virtuale simile a una tabella basata sul set di risultati di un'istruzione SQL. In superficie, una vista è simile a una tabella con la struttura della firma di righe e colonne. Tuttavia, queste righe e colonne provengono da tabelle a cui si fa riferimento nella query, che definisce la vista.

Usiamo le viste per concentrarci sulle colonne concrete per gli scopi per cui sono state create. Le visualizzazioni possono servire anche per motivi di sicurezza. Filtrano le colonne nelle tabelle sottostanti che non si vogliono rendere visibili a determinati utenti. Visualizza le colonne dei filtri come una clausola WHERE filtra le righe.

Un altro motivo per Views è la semplicità. Aggregano colonne di diverse tabelle e creano un aspetto generale simile a un'unica tabella.

Tipi di visualizzazioni

Le visualizzazioni di base definite dall'utente sono facili da creare. Il processo è simile alla scrittura di query che fanno riferimento a una o più tabelle.

  • Le viste indicizzate sono quelle che sono state materializzate o archiviate come una tabella. Le viste indicizzate possono migliorare le prestazioni delle query che aggregano molte righe. Tuttavia, non sono adatti se le tabelle sottostanti vengono aggiornate frequentemente.
  • Le viste partizionate uniscono dati partizionati orizzontalmente da tabelle in locale (all'interno della stessa istanza) o in più, utilizzando server collegati.
  • Le visualizzazioni di sistema sono le strutture comuni utilizzate da SQL Server per esporre i metadati del catalogo. Le visualizzazioni di sistema sono la maggior parte di quelle strutture che si interrogano per la risoluzione dei problemi delle prestazioni o per l'analisi di un'istanza di SQL Server.

Creazione di una vista da una tabella

Dai un'occhiata all'esempio nel Listato 1. La prima istruzione restituisce TUTTI i record nella tabella Purchasing.PurchaseOrders (1a), mentre la seconda query restituisce solo poche colonne (1b).

Usando la seconda query, possiamo creare una vista che restituisce lo stesso set di risultati di (1b). Quando lo facciamo, possiamo interrogare una vista per ottenere l'output desiderato. Pertanto, semplifichiamo la query per un utente finale.

-- 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 ;

Creazione di una vista da due tabelle

Utilizzando JOIN, possiamo recuperare i dati da due o più tabelle che hanno una relazione. Utilizzando Views, possiamo semplificare l'accesso a tali dati.

Il Listato 2 (2a) mostra un JOIN tra Purchasing.PurchaseOrders e Purchasing.PurchaseOrderLines. Possiamo creare una vista da questo JOIN e ci consentirà di recuperare gli stessi dati utilizzando una query, come mostrato in (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;

Creazione di una vista sui database

Usando la denominazione in più parti, possiamo fare riferimento a tabelle in un database diverso. Pertanto, possiamo eseguire JOIN tra i database e creare viste che si estendono su database. È utile per alcune applicazioni che diffondono i propri dati tra i database nella stessa istanza di SQL Server.

Il Listato 3 mostra un caso simile al Listato 2, ma con una differenza:aggiungiamo una terza tabella alla query JOIN da un database diverso. Si noti che dobbiamo usare un LEFT OUTER JOIN poiché non esiste alcuna relazione reale tra le tabelle in entrambi i database. Qui lo usiamo solo per illustrare la creazione di una VIEW che si estende su database diversi.

Abbiamo introdotto un alias nell'istruzione CREATE VIEW, poiché abbiamo colonne di due tabelle diverse con lo stesso nome. Dobbiamo distinguere queste colonne in questi casi.

  -- 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;

Dai un'occhiata alla Figura 1. Mostra il risultato dell'esecuzione del Listato 3(3c). Nota che le ultime tre colonne sono vuote, come TSQLV4.Sales.Orders la tabella non ha righe corrispondenti alla condizione JOIN.

Creazione di una vista tra le istanze

Possiamo estendere l'ultima affermazione introducendo una tabella che risiede interamente in un'altra istanza.

Per raggiungere questo obiettivo, dobbiamo prima creare un server collegato. Lo facciamo con il codice simile a quello mostrato nel Listato 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

Nota come indirizziamo la tabella esterna usando un nome in quattro parti:

-- 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;

Inclusione di funzioni nelle viste

Poiché le visualizzazioni sono essenzialmente query, possiamo applicarle quasi tutto ciò che facciamo con le query regolari. Possiamo includere funzioni, clausole WHERE, espressioni CASE, alias, ecc.

Tuttavia, la clausola ORDER BY non è consentita, a meno che tu non utilizzi il "TOP 100 hack". Gli elenchi da 6 a 9 illustrano l'utilizzo di tali clausole in Visualizzazioni.

-- 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

Viste indicizzate

Abbiamo fatto riferimento alle viste indicizzate in precedenza nell'articolo. Le viste indicizzate possono migliorare le prestazioni, ad eccezione dei casi in cui le tabelle sottostanti richiedono un uso intensivo della scrittura. SQL Server richiede determinate opzioni SET abilitate prima di creare viste indicizzate o eseguire determinate operazioni su di esse.

La clausola WITH SCHEMABINDING deve essere utilizzata durante la creazione di una vista per inserire un indice su di essa. Questa clausola associa rigorosamente la vista agli oggetti sottostanti. Pertanto, tali oggetti non possono essere lasciati cadere.

-- 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);

Conclusione

In questo articolo, abbiamo esaminato le visualizzazioni a un certo livello di dettaglio. Abbiamo trattato brevemente i tipi di viste e fornito diversi esempi di viste definite dall'utente e come abbiamo utilizzato le JOIN per realizzare viste che dipendono da molte tabelle. Abbiamo anche trattato viste complesse che includono funzioni e viste indicizzate.

Riferimenti

  1. Viste
  2. Viste indicizzate
  3. Crea viste indicizzate in SQL Server