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

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 用户可以访问所有的表数据。

【讨论】:

以上是关于如何根据数据库用户和表的内容返回行?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL常见问题的解决,root用户密码忘记,不是内部或外部命令,修改数据库和表的字符编码,命令行客户端的字符集问题

如何使用数据库和表的枚举来验证请求

Oracle数据库实验--表空间和表的管理

Oracle数据库实验--表空间和表的管理

MySQL修改数据表名和表字段命令行

Mysql数据库表的迁移和表的复制