読者です 読者をやめる 読者になる 読者になる

Row-Level-Security BLOCK PREDICATE のメモ

行レベルのセキュリティ
いつの間にか 日本語MSDN提供されてました。
追加/更新操作の制限は、トランザクション単位ではなくクエリ単位だよというメモ。

create table [dbo].[Table] (
  [Id] int
)
go
create schema [rls]
go
create function [rls].[TablePredicate](@Id int)
  returns table
  as return select 1 as [Result] where @Id <> 1
go
create security policy [rls].[TablePolicy]
  add block predicate [rls].[TablePredicate]([Id]) on [dbo].[Table] after insert

Id = 1 は INSERT 出来ない制限を掛けたときに、

begin tran 
insert into [dbo].[Table] ([Id]) values (1)
update [dbo].[Table] set [Id] = 2 where [Id] = 1
commit

はエラーになります。
トランザクションとしては、結果的に Id = 1 の列は追加されていませんが普通の動きですね。*1

クエリ全文

create table [dbo].[Table] (
  [Id] int
)
go
create schema [rls]
go
create function [rls].[TablePredicate](@Id int)
  returns table
  with schemabinding
  as return select 1 as [Result] where @Id <> 1
go
create security policy [rls].[TablePolicy]
  add block predicate [rls].[TablePredicate]([Id]) on [dbo].[Table] after insert
go

begin tran 
insert into [dbo].[Table] ([Id]) values (1)
update [dbo].[Table] set [Id] = 2 where [Id] = 1
commit
go

drop security policy [rls].[TablePolicy]
go
drop function [rls].[TablePredicate]
go
drop schema [rls]
go
drop table [dbo].[Table]
go

*1:分離レベル低いと SELECT から見えちゃうし...