1

我需要将 Oracle SQL 语句转换为存储过程,因此权限较低的用户可以访问某些数据字段:

SELECT
    info_field, data_field
FROM
    table_one
WHERE
    some_id = '<id>' -- I need this <id> to be the procedure's parameter
UNION ALL

SELECT
    info_field, data_field
FROM
    table_two
WHERE
    some_id = '<id>'
UNION ALL

SELECT
    info_field, data_field
FROM
    table_three
WHERE
    some_id = '<id>'
UNION ALL

...

鉴于我不是 SP 专家,我一直无法找到一个好的解决方案来遍历所有相关的表(大约 12 个)。

任何想法都会有所帮助。非常感谢!

4

3 回答 3

4

如果您只想限制用户的访问权限,您可以创建一个视图并授予他们选择视图而不是表的权限:

CREATE VIEW info_and_data AS
    SELECT info_field, data_field    
    FROM   table_one
    UNION ALL
    SELECT info_field, data_field    
    FROM   table_two
    UNION ALL
    SELECT info_field, data_field    
    FROM   table_three
    ...

然后用户可以键入:

SELECT info_field, data_field
FROM   info_and_data
WHERE  some_id = <id>
于 2008-11-21T14:28:06.887 回答
2

除了我在下面的建议之外,还有其他方法可以实现您的目标,但我会警告不要拆分真正属于一个表的数据只是为了实现将来可能会更改的数据访问策略。

限制用户看到哪些表列的最简单的解决方案是通过这些表的视图。使用显示或隐藏特定列的不同视图,并将这些视图的访问权限授予不同的用户/角色。

如果您事先不知道可能允许用户查看哪些列组合,那么您可以使用动态 sql:您根据用户的访问权限在存储过程中组装 SQL 语句(从其他一些为保存此信息而创建的表),这意味着您只在语句的 SELECT 部分中包含正确的列。有关更多信息,请参阅Orace的此文档 。

如果您使用的是 Oracle 10g,那么您可能会发现这篇Oracle 文章很有趣。它介绍了虚拟专用数据库(简称 VPD)的主题,您可以在其中隐藏某些行、列或什至单个列值,具体取决于访问表的人员。

于 2008-11-21T14:52:37.757 回答
1

是否期望在所有这些表中,只有一个与给定 ID 匹配?

如果否:您需要说明当有多个匹配项时您想要做什么。

如果是:您只需执行相同的 SQL 查询,将结果选择到一个变量中,然后返回。

它看起来像这样:

PROCEDURE get_fields( the_id  NUMBER,
                      info_field_out  OUT  table_one.info_field%TYPE,
                      data_field_out  OUT  table_one.data_field%TYPE
                    )
  IS
  BEGIN
    SELECT info_field, data_field
      INTO info_field_out, data_field_out
      FROM (
        ... put your full SQL query here, using 'the_id' as the value to match against ..
      );

  EXCEPTION

    WHEN no_data_found THEN
      -- What do you want to do here?  Set the outputs to NULL?  Raise an error?

    WHEN too_many_rows THEN
      -- Is this an invalid condition?

  END;
于 2008-11-21T14:07:06.773 回答