如何根据数据库用户和表的内容返回行?

时间:2019-11-30 19:38:49

标签: oracle stored-functions

我有一张下表:

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)在此表上执行select语句,则只会得到3 LEO 4
  2. sys_dba无论如何都会得到所有结果。

我已授予Scott在由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;
/

2 个答案:

答案 0 :(得分:1)

根据您之前的问题和您发布的信息,我对问题的理解是这样的:如果您在整个表上将select授予了任何用户,则它可以提取全部行。您必须进一步限制值。

一种选择-我们正在谈论该功能-是在case子句中使用where

这是一个例子。

样本数据:

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
  • 的行
  • 返回结果

所以:

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>

答案 1 :(得分:1)

我建议像这样为每个用户创建一个视图

create view THE_VIEW as select * from TABLE where NAME = user

然后仅授予对视图的访问权限。
现在,用户尝试对表执行哪种查询都没有关系,她只会返回一行。
当然,DBA用户可以访问所有表数据。