SQL Server 2005で VIEW の定義方法や使用方法を掲載します。
動作確認は SQL Server 2005 Developer Edition で行っています。
1. VIEW を定義する
VIEW を定義し、変更、削除、検索するサンプルを掲載します。テーブル定義と同様にCREATE VIEW を使用して作成。ALTER文で変更、DROPで削除を行います。VIEW定義でENCRYPTION オプションを使用するとVIEW定義を暗号化できます。
-- VIEW を定義する
IF OBJECT_ID('dbo.vArticles') IS NOT NULL
DROP VIEW dbo.vArticles
GO
CREATE VIEW dbo.vArticles
AS
-- VIEW を定義する
SELECT a.ArticleID
,a.Title
,a.Abstract
,(SELECT COUNT(*) FROM dbo.Comment c WHERE c.ArticleID = a.ArticleID) NumOfComments
FROM dbo.Article a
GO
-- VIEW にクエリを出す
select *
from dbo.vArticles
order by NumOfComments desc
-- VIEW を変更する
ALTER VIEW dbo.vArticles
AS
-- VIEW を定義する
SELECT a.ArticleID
,a.Title
,a.Abstract
,a.ReleaseDate
,(SELECT COUNT(*) FROM dbo.Comment c WHERE c.ArticleID = a.ArticleID) NumOfComments
FROM dbo.Article a
GO
-- VIEW を削除する
DROP VIEW dbo.vArticles
2. VIEWのメタデータを取得する
VIEWの定義情報はsys.sql_modulesを使用します。スキーマやカラム情報はsys.schemas, sys.columns を使用します。依存するオブジェクトを使用する場合は、 sys.sql_dependencies カタログビューを使用します。
-- VIEWの定義を表示する
select definition
from sys.sql_modules
where object_id = object_id('dbo.vArticles')
-- VIEWのスキーマ情報を表示する
select s.name [schema], v.name [view]
from sys.views v
inner join sys.schemas s
on v.schema_id = s.schema_id
where v.object_id = OBJECT_ID('dbo.vArticles')
-- カラム情報を表示する
select v.name [view], c.name [column]
from sys.views v
inner join sys.columns c
on c.object_id = v.object_id
where v.object_id = OBJECT_ID('dbo.vArticles')
-- VIEWが依存するオブジェクトを列挙する
select v.name [view], OBJECT_NAME(referenced_major_id) ReferencedObject
from sys.sql_dependencies d
inner join sys.views v
on d.object_id = v.object_id
where d.object_id = OBJECT_ID('dbo.vArticles')
-- VIEW が参照しているオブジェクトが更新された場合に
-- VIEWのメタデータを更新する
EXEC sp_refreshview 'dbo.vArticles'
3. INDEX付きVIEWを定義する
ビューの作成時にWITH SCHEMABINDINGオプションを使用することで、インデックス化VIEWを作成することができます。Enterprise Edition では、クエリオプティマイザがインデックスを考慮してVIEWに対する実行プランを作成します。Standard Edition などでは自動的にオプティマイザはVIEWのインデックスを使用しないので手動でNOEXPANDテーブルヒントを指定することでVIEWのインデックスを使用するようにできます。
INDEX付きのVIEWを使用することで、集計間巣を多様しているVIEWで、元となるテーブルが頻繁に更新が発生しない場合パフォーマンスなどの場合にパフォーマンスを向上させることができる可能性があります。
IF OBJECT_ID('dbo.vArticles') IS NOT NULL
DROP VIEW dbo.vArticles
GO
CREATE VIEW dbo.vArticles
WITH SCHEMABINDING
AS
-- インデックスVIEW用にSCHEMABINDINGを
-- 設定してビューを定義する
SELECT c.CategoryID, c.Title, SUM(a.Votes) Votes, COUNT_BIG(*) NumOfArticles
FROM dbo.Article a
INNER JOIN dbo.Category c
ON a.CategoryID = c.CategoryID
GROUP BY c.CategoryID, c.Title
GO
-- VIEWにクラスタ化インデックスを定義する
-- サブクエリが含まれている場合、OUTER結合が
-- 含まれる場合インデックスを作成できない
-- などの制限があるので注意.
CREATE UNIQUE CLUSTERED INDEX PK_vArticles
ON dbo.vArticles (CategoryID)
GO
CREATE NONCLUSTERED INDEX IX_vArticles
ON dbo.vArticles (Votes,NumOfArticles)
GO
-- インデックスを削除する
DROP INDEX dbo.vArticles.IX_vArticles
GO
VIEWに対してインデックスを設定する場合、OUTER JOINやサブクエリを使用できないなど、VIEW定義のSELECT文に制限が発生するので注意が必要です。
4.まとめ
説明は以上です。動作確認をしていないので記事には掲載していませんが、VIEWにはこのほかにもパーティションビューという、異なるSQL インスタンスで分散されたVIEWを定義することもできます。BOOKS ONLINEなどで、パーティション ビューや分散パーティション ビューで調べてください。
誤り指摘点などがある場合はご連絡ください。