Sql-Server

無法針對具有屏蔽列的表創建索引視圖

  • April 29, 2020

我正在嘗試在引用帶有屏蔽列的表的視圖上創建索引(SQL Server 2016)。被屏蔽的列不是該表中唯一的列,也沒有在視圖中使用。

create unique clustered index [IX_Name]
on dbo.vw_ViewName(SomeUniqueId)

我收到此錯誤:

無法創建視圖“dbo.vw_ViewName”上的索引,因為該視圖正在引用帶有屏蔽列的表“dbo.TableName”。

在另一個未啟用屏蔽的環境中,索引創建成功。

我瀏覽了大約四頁的Google搜尋結果,並沒有找到任何合理的錯誤描述。我將不勝感激有關錯誤的任何知識轉移以及為什麼無法創建此類索引。

下面是一些重現問題的 SQL:

drop view if exists dbo.vw_Aggregate
drop table if exists dbo.MainTable, dbo.SecondaryTable
go

create table dbo.MainTable
(
   MainTableId uniqueidentifier primary key,
   SomeExternalId uniqueidentifier,
   SecondaryTableId uniqueidentifier
)
go

create table dbo.SecondaryTable
(
   SecondaryTableId uniqueidentifier primary key,
   CreatedOn datetime,
   Amount decimal(19, 8),
   -- the below column produces error,
   -- if commented out - there is no error
   [Description] nvarchar(max) masked with (function = 'default()'),
   Dummy int
)
go

create view dbo.vw_Aggregate with schemabinding
as
   select AggregateId = m.MainTableId,
          m.SomeExternalId,
          s.CreatedOn,
          s.Amount
   from dbo.MainTable m
   inner join dbo.SecondaryTable s on s.SecondaryTableId = m.SecondaryTableId
go

create unique clustered index [IX_dbo.vw_Aggregate(AggregateId)]
on dbo.vw_Aggregate(AggregateId)
go

據我所知,這是不支持的,在這種情況下你只能使用表。

正如在下面的文章中發現的那樣,它使用了與動態數據屏蔽不同的****行級安全性,但它可能相互關聯。

https://www.mssqltips.com/sqlservertip/4005/sql-server-2016-row-level-security-limitations-performance-and-troubleshooting/作者:Aaron Bertrand:

索引視圖

行級安全性與具有索引視圖的表不兼容。如果您嘗試針對具有安全策略的表創建索引視圖,您將收到以下錯誤:

消息 33266,級別 16 無法創建視圖“視圖”上的索引,因為該視圖正在引用安全策略引用的表“表”。

不,你不能用雞蛋和雞蛋來解決它;如果表被索引視圖引用,則無法應用安全策略:

消息 33265,級別 16 安全策略“策略”不能在表“表”上具有謂詞,因為該表被索引視圖“視圖”引用。

注意:如果嘗試將安全策略應用於由分區視圖引用的表,您可能會遇到相同類型的問題。

由於動態數據屏蔽和行級安全性是在同一版本中發布的,因此這些限制可能是相互關聯的。

錯誤

該錯誤還清楚地表明,不允許在連結到帶有屏蔽列的表的視圖上建立索引。然而,在文件中找不到任何關於它的資訊。

所以我的猜測是它不被支持。

引用自:https://dba.stackexchange.com/questions/196477