如何根据数据库用户和表的内容返回行?
Posted
技术标签:
【中文标题】如何根据数据库用户和表的内容返回行?【英文标题】:How to return rows based on the database user and the table's contents? 【发布时间】:2019-11-30 19:38:49 【问题描述】:我有一张下表:
id name score
1 SYS 4
2 RHWTT 5
3 LEO 4
4 MOD3_ADMIN 5
5 VPD674 4
6 SCOTT 5
7 HR 4
8 OE 5
9 PM 4
10 IX 5
11 SH 4
12 BI 5
13 IXSNEAKY 4
14 DVF 5
我想在 Oracle SQL 中创建一个策略函数来确保以下几点:
-
如果用户(Leo)在该表上执行选择语句,它只会得到
3 LEO 4
。
sys_dba 无论如何都会得到所有结果。
我已授予 Leo 在 Scott 创建的这张桌子上的选择权限。
我在编写这个复杂的 PL/SQL 函数时遇到了困难。我尝试了以下方法,它指出了编译错误。另外,我认为它没有做我打算做的事情:
CREATE FUNCTION no_show_all (
p_schema IN NUMBER(5),
p_object IN VARCHAR2
)
RETURN
AS
BEGIN
RETURN 'select avg(score) from scott.rating';
END;
/
【问题讨论】:
嗯?对不起,但你的功能没有任何意义。所以你想限制根据 oracle 用户名选择哪些记录? 是的,完全正确。 sys_dba 获取所有记录。 如果您至少有版本 11(¿release 2?,您可能需要查看“标签安全性”。 @Abecee - 我想你的意思是Virtual Private Database(因为标签安全是企业版的额外收费)。但即使是 VPD 也需要 EE,并且在标准版中不可用,尽管有趣的是它在 Oracle 18c XE 中得到支持。 @APC:实际上,我确实考虑过标签安全性。似乎确实解决了这种情况。但这只是与技术相关的评论 - 忽略了任何许可问题。 【参考方案1】:根据您之前发布的问题和信息,我是这样理解这个问题的:如果您将整个表上的select
授予任何用户,那么它就能够从中获取 all 行它。您必须进一步限制值。
一种选择——正如我们所说的函数——是在where
子句中使用case
。
这是一个例子。
样本数据:
SQL> create table rating as
2 select 1 id, 'sys' name, 4 score from dual union all
3 select 3, 'leo' , 3 from dual union all
4 select 6, 'scott' , 5 from dual union all
5 select 7, 'hr' , 2 from dual;
Table created.
功能:
它接受用户名作为参数(注意字母大小写!在我的示例中,所有内容都是小写的。在您的情况下,也许您必须使用upper
函数或类似的东西)
case
说:如果 par_user
等于 sys
,让它获取所有行。否则,仅获取 name 列的值等于 par_user
的行
返回结果
所以:
SQL> create or replace function f_rating (par_user in varchar2)
2 return number
3 is
4 retval number;
5 begin
6 select avg(score)
7 into retval
8 from rating
9 where name = case when par_user = 'sys' then name
10 else par_user
11 end;
12 return retval;
13 end;
14 /
Function created.
让我们试试吧:
SQL> select f_rating('sys') rating_sys,
2 f_rating('hr') rating_hr
3 from dual;
RATING_SYS RATING_HR
---------- ----------
3,5 2
SQL>
【讨论】:
对我来说,这似乎限制了基于函数参数而不是用户执行它的结果。除此之外,OP 似乎(至少对我而言)要求对普通ˋSELECTˋ 有效的解决方案。请问我错过了什么? 你错过了我写的第一句话,@Abecee。此问题与同一人之前发布的问题有关。 之前的问题似乎是***.com/questions/59118281/… - 这是关于实施安全策略的问题……没关系。【参考方案2】:我建议为每个用户创建一个视图,像这样
create view THE_VIEW as select * from TABLE where NAME = user
然后仅授予对视图的访问权限。 现在,用户尝试在您的表上执行什么样的查询并不重要,她只会得到一行。 当然 DBA 用户可以访问所有的表数据。
【讨论】:
以上是关于如何根据数据库用户和表的内容返回行?的主要内容,如果未能解决你的问题,请参考以下文章