sql >> Database >  >> RDS >> Sqlserver

Weergaven in SQL Server

Inleiding

Een view in SQL Server is een virtuele tabelachtige structuur gebaseerd op de resultatenset van een SQL-statement. Op het eerste gezicht lijkt een weergave op een tabel met de kenmerkende structuur van rijen en kolommen. Deze rijen en kolommen komen echter uit tabellen waarnaar wordt verwezen in de query, die de weergave definieert.

We gebruiken Views om ons te concentreren op de betonnen kolommen voor de doeleinden waarvoor ze zijn gemaakt. Weergaven kunnen ook dienen om veiligheidsredenen. Ze filteren kolommen uit de onderliggende tabellen die men niet zichtbaar wil maken voor bepaalde gebruikers. Bekijkt filterkolommen zoals een WHERE-clausule filtert rijen.

Een andere reden voor Views is eenvoud. Ze aggregeren kolommen uit verschillende tabellen en creëren een algemene weergave die eruitziet als een enkele tabel.

Typen weergaven

Door de gebruiker gedefinieerde basisweergaven zijn eenvoudig te maken. Het proces is vergelijkbaar met het schrijven van query's die verwijzen naar een of meer tabellen.

  • Geïndexeerde weergaven zijn weergaven die tot stand zijn gekomen of zijn opgeslagen als een tabel. Geïndexeerde weergaven kunnen de prestaties verbeteren van query's die veel rijen samenvoegen. Ze zijn echter niet geschikt als onderliggende tabellen regelmatig worden bijgewerkt.
  • Gepartitioneerde weergaven voegen horizontaal gepartitioneerde gegevens uit tabellen lokaal (binnen dezelfde instantie) of meerdere samen, met behulp van gekoppelde servers.
  • Systeemweergaven zijn de algemene structuren die SQL Server gebruikt om de metagegevens van de catalogus weer te geven. Systeemweergaven zijn de meeste van die structuren die één vraag stellen voor het oplossen van problemen met de prestaties of het onderzoeken van een SQL Server-instantie.

Een weergave maken vanaf één tafel

Bekijk het voorbeeld in Listing 1. De eerste instructie retourneert ALLE records in de tabel Purchasing.PurchaseOrders (1a), terwijl de tweede zoekopdracht slechts een paar kolommen retourneert (1b).

Met behulp van de tweede query kunnen we een weergave maken die dezelfde resultatenset retourneert als (1b). Wanneer we dit doen, kunnen we een View opvragen om de gewenste output te krijgen. Zo vereenvoudigen we de zoekopdracht voor een eindgebruiker.

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

Een weergave maken vanuit twee tabellen

Met JOIN's kunnen we gegevens ophalen uit twee of meer tabellen die een relatie hebben. Met Views kunnen we de toegang tot dergelijke gegevens vereenvoudigen.

Lijst 2 (2a) toont een JOIN tussen Purchasing.PurchaseOrders en Purchasing.PurchaseOrderLines. We kunnen een weergave maken van deze JOIN en het stelt ons in staat om dezelfde gegevens op te halen met een zoekopdracht, zoals weergegeven 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;

Een overzicht van databases maken

Met behulp van meerdelige naamgeving kunnen we verwijzen naar tabellen in een andere database. Daarom kunnen we JOIN's over de databases doen en weergaven maken die databases overspannen. Het is handig voor bepaalde toepassingen die hun gegevens over databases in dezelfde SQL Server-instantie verspreiden.

Listing 3 toont een soortgelijk geval als Listing 2, maar met een verschil:we voegen een derde tabel toe aan de JOIN-query vanuit een andere database. Merk op dat we een LEFT OUTER JOIN moeten gebruiken omdat er geen echte relatie bestaat tussen de tabellen in beide databases. Hier gebruiken we het alleen om het maken van een VIEW te illustreren dat verschillende databases omvat.

We hebben een alias geïntroduceerd in de CREATE VIEW-instructie, omdat we kolommen hebben uit twee verschillende tabellen met dezelfde naam. In dergelijke gevallen moeten we die kolommen onderscheiden.

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

Kijk eens naar figuur 1. Het toont het resultaat van het uitvoeren van Listing 3(3c). Merk op dat de laatste drie kolommen leeg zijn, aangezien de TSQLV4.Sales.Orders tabel heeft geen rijen die overeenkomen met de JOIN-voorwaarde.

Een weergave voor meerdere instanties maken

We kunnen de laatste verklaring uitbreiden door een tabel te introduceren die volledig in een andere instantie leeft.

Om dit te bereiken, moeten we eerst een Linked Server maken. We doen het met de code die lijkt op die in Listing 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

Merk op hoe we de externe tabel aanspreken met een vierdelige naam:

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

Functies opnemen in weergaven

Aangezien Views in wezen zoekopdrachten zijn, kunnen we er bijna alles op toepassen wat we doen met gewone zoekopdrachten. We kunnen functies, WHERE-clausules, CASE-expressies, aliassen, enz. opnemen.

De ORDER BY-clausule is echter niet toegestaan, behalve dat u de "TOP 100-hack" gebruikt. Lijsten 6 tot 9 illustreren het gebruik van die clausules in 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

Geïndexeerde weergaven

We verwezen eerder in het artikel naar geïndexeerde weergaven. Geïndexeerde weergaven kunnen de prestaties verbeteren, behalve in de gevallen waarin onderliggende tabellen schrijfintensief zijn. SQL Server vereist dat bepaalde SET-opties zijn ingeschakeld voordat geïndexeerde weergaven kunnen worden gemaakt of er bepaalde bewerkingen op kunnen worden uitgevoerd.

De clausule WITH SCHEMABINDING moet worden gebruikt bij het maken van een weergave om er een index op te plaatsen. Deze clausule associeert de View strikt met de onderliggende objecten. Dergelijke objecten kunnen dus niet worden verwijderd.

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

Conclusie

In dit artikel hebben we standpunten op een bepaald detailniveau onderzocht. We hebben kort de soorten weergaven besproken en verschillende voorbeelden gegeven van door de gebruiker gedefinieerde weergaven en hoe we JOIN's hebben gebruikt om weergaven te realiseren die afhankelijk zijn van veel tabellen. We hebben ook complexe weergaven behandeld die zowel functies als geïndexeerde weergaven bevatten.

Referenties

  1. Beelden
  2. Geïndexeerde weergaven
  3. Geïndexeerde weergaven maken in SQL Server

  1. Kan tekenreekswaarde 1,2 niet doorgeven als invoer voor een orakel-query

  2. 12c VARCHAR2(32767)

  3. 4 belangrijke databasebewakingsactiviteiten die elke DBA moet weten

  4. Tabel dupliceren in MySQL