はじめに
SQL Serverのビューは、SQLステートメントの結果セットに基づく仮想テーブルのような構造です。表面的には、ビューは行と列の署名構造を持つテーブルに似ています。ただし、これらの行と列は、ビューを定義するクエリで参照されるテーブルから取得されます。
ビューを使用して、作成目的のコンクリート柱に焦点を合わせます。ビューは、セキュリティ上の理由からも役立つ場合があります。これらは、特定のユーザーに表示したくない基になるテーブルの列を除外します。ビューは、WHERE句が行をフィルタリングするように列をフィルタリングします。
ビューのもう1つの理由は、単純さです。これらは、いくつかの異なるテーブルの列を集約し、単一のテーブルのように見える一般的な外観を作成します。
ビューの種類
基本的なユーザー定義ビューは簡単に作成できます。このプロセスは、1つ以上のテーブルを参照するクエリの作成に似ています。
- インデックス付きビューは、テーブルのように実体化または保存されたビューです。インデックス付きビューは、多くの行を集約するクエリのパフォーマンスを向上させることができます。ただし、基になるテーブルが頻繁に更新される場合は適切ではありません。
- パーティションビューは、リンクサーバーを使用して、ローカル(同じインスタンス内)または多数のテーブルから水平方向にパーティション化されたデータを結合します。
- システムビューは、SQLServerがカタログメタデータを公開するために使用する一般的な構造です。システムビューは、パフォーマンスのトラブルシューティングやSQLServerインスタンスの調査のために1つのクエリを実行する構造のほとんどです。
1つのテーブルからのビューの作成
リスト1の例を見てください。最初のステートメントは、テーブル Purchaseing.PurchaseOrdersのすべてのレコードを返します。 (1a)、2番目のクエリは少数の列(1b)のみを返します。
2番目のクエリを使用して、(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 ;
2つのテーブルからのビューの作成
JOINを使用すると、関係のある2つ以上のテーブルからデータを取得できます。ビューを使用すると、そのようなデータへのアクセスを簡素化できます。
リスト2(2a)は、Purchasing.PurchaseOrdersとPurchasing.PurchaseOrderLinesの間のJOINを示しています。この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を実行し、データベースにまたがるビューを作成できます。同じSQLServerインスタンス内のデータベース間でデータを分散する特定のアプリケーションに役立ちます。
リスト3は、リスト2と同様のケースを示していますが、違いがあります。別のデータベースからJOINクエリに3番目のテーブルを追加します。両方のデータベースのテーブル間に実際の関係が存在しないため、LEFTOUTERJOINを使用する必要があることに注意してください。ここでは、さまざまなデータベースにまたがるVIEWの作成を説明するためにのみ使用します。
同じ名前の2つの異なるテーブルの列があるため、CREATEVIEWステートメントにエイリアスを導入しました。このような場合、これらの列を区別する必要があります。
-- 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 のように、最後の3列は空であることに注意してください。 テーブルに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
4つの部分からなる名前を使用して外部テーブルをアドレス指定する方法に注目してください:
-- 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;
ビューに関数を含める
ビューは基本的にクエリであるため、通常のクエリで行うほとんどすべてのビューに適用できます。関数、WHERE句、CASE式、エイリアスなどを含めることができます。
ただし、「TOP 100ハック」を使用する場合を除き、ORDERBY句は使用できません。リスト6から9は、ビューでのこれらの句の使用法を示しています。
-- 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オプションを有効にする必要があります。
インデックスを付けるためのビューを作成するときは、WITHSCHEMABINDING句を使用する必要があります。この句は、ビューを基になるオブジェクトに厳密に関連付けます。したがって、そのようなオブジェクトをドロップすることはできません。
-- 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を使用して多くのテーブルに依存するビューを実現する方法を示しました。また、関数とインデックス付きビューを含む複雑なビューについても説明しました。
参照
- ビュー
- インデックス付きビュー
- SQLServerでインデックス付きビューを作成する