Oracle静态行级安全(RLS)疑问:循环中数据变更的谓词及函数执行情况
嘿,我来帮你把这个困惑点理清楚!针对你提到的STATIC类型RLS策略结合循环修改数据的场景,咱们拆解成两个核心问题来解答:
1. 循环执行期间修改数据,谓词会发生变化吗?
不会。STATIC类型的RLS策略最核心的特点就是:谓词是在整个查询(或会话级别的查询上下文)启动时计算一次,之后就固定下来,不会随后续的数据变更而改变。
哪怕你的RLS函数Fun_temp是查询同一张Temp表生成谓词,但因为策略是STATIC,它只会在循环开始前(准确说是第一次访问Temp表时)执行函数并生成谓词,后续循环里不管你怎么修改Temp表的数据,这个已经生成的谓词都不会更新。
举个简单的例子:假设初始Temp表中用户A能看到ID=1、2的行,STATIC策略生成的谓词是id IN (1,2)。哪怕你在循环里把ID=3的行的权限改成用户A可见,后续循环迭代访问Temp表时,依然只会筛选出ID=1、2的行,不会包含ID=3。
2. RLS函数会在循环的每次迭代中执行吗?
同样不会。STATIC策略的RLS函数只会被调用一次——就是在第一次触发RLS检查的时候(通常是查询的初始化阶段),之后生成的谓词会被缓存起来,循环的每一次迭代都会直接复用这个缓存的结果,不会再去执行Fun_temp函数。
补充:如果是DYNAMIC策略会怎样?
如果你的策略类型换成DYNAMIC,那情况就完全不同了:每次访问Temp表(包括循环的每一次迭代)都会重新执行Fun_temp函数生成谓词,这时候循环中修改的数据就会影响后续的谓词结果。但你用的是STATIC,所以不需要考虑这种情况。
总结一下:STATIC策略的RLS是“一劳永逸”式的计算,循环中的数据变更不会触发谓词更新,函数也不会重复执行。
内容的提问来源于stack exchange,提问作者Stay Curious

