如何根据数据库用户和 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 中创建一个策略函数来确保以下事项:

  1. 如果用户 (Leo) 在此 table 上执行 select 语句,它只会得到 3 LEO 4
  2. 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 数据。