在 Northwind 範例資料庫中,查詢「某訂單的完整明細(雇員、產品、價格、運送商、收貨地址)」需聯結 5 張表:Orders、Employees、Order Details、Products、Shippers。每次查詢都寫冗長的 JOIN 不僅易出錯,維護成本極高。
CREATE VIEW v_OrderDetails
AS
SELECT o.OrderID,
e.LastName + e.FirstName AS EmployeeName,
p.ProductName,
od.UnitPrice,
od.Quantity,
od.Discount,
s.CompanyName AS ShipperName,
o.ShipName,
o.ShipAddress,
o.ShipCity,
o.OrderDate,
o.ShippedDate
FROM Orders o
JOIN [Order Details] od ON o.OrderID = od.OrderID
JOIN Employees e ON o.EmployeeID = e.EmployeeID
JOIN Products p ON od.ProductID = p.ProductID
JOIN Shippers s ON o.ShipVia = s.ShipperID;
-- 查詢單一訂單明細
SELECT * FROM v_OrderDetails WHERE OrderID = 10248;
-- 統計各運送商處理訂單數
SELECT ShipperName, COUNT(*) AS OrderCount
FROM v_OrderDetails
GROUP BY ShipperName;
| 特性 | 說明 |
|---|---|
| 虛擬資料表 | 不儲存實體資料,每次查詢即時執行底層 SQL(除非建立索引視圖)。 |
| 安全性隔離 | 可只授權視圖存取,隱藏基底表結構與敏感欄位(如薪資、成本)。 |
| 簡化應用開發 | 應用程式只需對應單一實體,減少 ORM 映射複雜度。 |
| 可更新性 | 符合條件(單一基底表、無聚合/GROUP BY/DISTINCT、含主鍵)的視圖可直接 INSERT/UPDATE/DELETE。 |
| 巢狀視圖 | 視圖可參考其他視圖,但層級過深影響除錯與效能,建議 ≤ 2 層。 |
-- 必須加上 SCHEMABINDING
CREATE VIEW v_OrderSummary
WITH SCHEMABINDING
AS
SELECT o.CustomerID,
COUNT_BIG(*) AS OrderCount,
SUM(od.UnitPrice * od.Quantity * (1 - od.Discount)) AS TotalAmount
FROM dbo.Orders o
JOIN dbo.[Order Details] od ON o.OrderID = od.OrderID
GROUP BY o.CustomerID;
-- 建立唯一叢集索引 → 視圖變為物質化
CREATE UNIQUE CLUSTERED INDEX IX_v_OrderSummary_Cust
ON v_OrderSummary (CustomerID);
索引視圖在 Enterprise Edition 會被查詢最佳化器自動匹配使用(即使查詢未直接引用視圖),大幅加速聚合報表查詢。
v_ 前綴區分視圖與資料表。SELECT *,明確列出欄位防止結構變更導致錯誤。sp_helptext 'v_OrderDetails' 快速檢視定義。