【问题标题】:Is there a BEFORE SELECT trigger in pl/sql?pl/sql 中是否有 BEFORE SELECT 触发器?
【发布时间】:2012-03-09 01:28:26
【问题描述】:

您好,我正在使用连接到 oracle 数据库的 sqldeveloper。

我的情况是我的数据库中有一个客户表,其中包含一个名为 start_date 的日期字段,其中包含用户注册的日期和一个名为 is_member 的“布尔”字段。每个会员资格仅持续一年,因此如果SYSDATE > start_date + 1yearis_member 为假。

我想在用户调用 select 语句之前检查用户是否仍然是成员(如果不是,则更改 is_member)。这可能吗?

如果没有,是否有人对如何使is_member 字段保持最新有任何想法?你能做一个每天调用一次的触发器来查看会员是否过期?

提前感谢! =]

【问题讨论】:

    标签: sql oracle plsql triggers


    【解决方案1】:

    不要使用表列存储依赖数据,使用视图:

    CREATE OR REPLACE VIEW customer_v AS
    SELECT c.*, 
           CASE WHEN SYSDATE > add_months(c.start_date, 12) 
              THEN 'FALSE' 
              ELSE 'TRUE' 
           END is_member
      FROM customer c
    

    is_member 视图列将始终包含最新数据。

    【讨论】:

    • 这对续订会员资格的人有何帮助?
    • @HLGEM:所描述的业务规则可能是对实际业务规则的过度简化。然而,在这种特定情况下,我们可以假设 start_date 在客户更新其会员资格时更新。
    • 当他们更新他们的会员资格时 start_date 将被更新。
    • 我会存储结束日期和开始日期。当他们续订时,您会更新结束日期。
    • @geekman92,你可以有一个renewal_date,但我更喜欢一张桌子renewals,在member_idrenewal_date 上是独一无二的
    【解决方案2】:

    这是应用程序进行检查而不是触发器的工作。 Triiger 不会在 SELECT 上触发。

    就使该领域保持最新而言,有两种可能性。首先设置一个夜间作业,以停用任何会员资格已过期的成员。或者将您的结构更改为存储membershipenddate 而不是isactive,并在应用程序中使用它来检查成员是否处于活动状态。

    【讨论】:

      【解决方案3】:

      在 PL/SQL 中没有 BEFORE SELECT 触发器这样的东西。

      听起来is_member 根本不应该是表中的列,而应该是在视图中计算的东西。类似的东西

      CREATE OR REPLACE VIEW view_name
      AS
        SELECT <<list_of_columns>>
               (CASE WHEN sysdate > add_months(start_date, 12)
                     THEN 'Y'
                     ELSE 'N'
                 END) is_member
          FROM your_table
      

      然后您的代码将简单地查询视图而不是查询基表。

      【讨论】:

        【解决方案4】:

        您可以向表和架构添加策略并添加所需的代码。

        http://docs.oracle.com/cd/B28359_01/network.111/b28531/vpd.htm#CIHCAACD

        CREATE OR REPLACE FUNCTION auth_orders( 
        schema_var IN VARCHAR2,
        table_var  IN VARCHAR2)
        RETURN VARCHAR2
        IS
        return_val VARCHAR2 (400);
        BEGIN
        return_val := 'SALES_REP_ID = 159';
        RETURN return_val;
        END auth_orders;
        
        
        BEGIN
        DBMS_RLS.ADD_POLICY (
        object_schema    => 'oe',
        object_name      => 'orders',
        policy_name      => 'orders_policy',
        function_schema  => 'sys',
        policy_function  => 'auth_orders',
        statement_types  => 'select, insert, update, delete'
        );
        END;
        

        【讨论】:

          【解决方案5】:

          您可以定义一个每天运行的作业并更新 is_member 字段。

          【讨论】:

            猜你喜欢
            • 2013-03-25
            • 1970-01-01
            • 1970-01-01
            • 2011-08-06
            • 2010-09-17
            • 1970-01-01
            • 1970-01-01
            • 2021-11-03
            • 2018-04-01
            相关资源
            最近更新 更多