如何根据数据库用户和 table 的内容 return 行?
How to return rows based on the database user and the table's contents?
我有一个关注table:
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) 在此 table 上执行 select 语句,它只会得到
3 LEO 4
。
- sys_dba无论如何都会得到所有结果。
我已授予 Leo select 对 Scott 创建的 table 的权限。
我在编写这个复杂的 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;
/
根据您之前的问题和您发布的信息,我是这样理解这个问题的:如果您将 select
总体上 table 授予任何用户,则它能够获取 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
,让它获取所有行。否则,只获取名称列的值等于 par_user
的行
- return结果
所以:
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>
我建议像这样为每个用户创建一个视图
create view THE_VIEW as select * from TABLE where NAME = user
然后仅授予对视图的访问权限。
现在,无论用户尝试对您的 table 执行何种查询,她都只会返回一行。
当然,DBA 用户可以访问所有 table 数据。
我有一个关注table:
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) 在此 table 上执行 select 语句,它只会得到
3 LEO 4
。 - sys_dba无论如何都会得到所有结果。
我已授予 Leo select 对 Scott 创建的 table 的权限。
我在编写这个复杂的 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;
/
根据您之前的问题和您发布的信息,我是这样理解这个问题的:如果您将 select
总体上 table 授予任何用户,则它能够获取 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
,让它获取所有行。否则,只获取名称列的值等于par_user
的行
- return结果
所以:
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>
我建议像这样为每个用户创建一个视图
create view THE_VIEW as select * from TABLE where NAME = user
然后仅授予对视图的访问权限。
现在,无论用户尝试对您的 table 执行何种查询,她都只会返回一行。
当然,DBA 用户可以访问所有 table 数据。