简体   繁体   English

pl / sql中是否有BEFORE SELECT触发器?

[英]Is there a BEFORE SELECT trigger in pl/sql?

Hi I am using sqldeveloper conected to an oracle database. 您好我使用sqldeveloper连接到oracle数据库。

My senario is I have a customer table in my database with a date field called start_date which holds the date of the day the user signed up and a "boolean" field called is_member . 我的senario是我的数据库中有一个客户表,其中包含一个名为start_date的日期字段,其中包含用户注册日期和一个名为is_member的“布尔”字段。 Each membership only lasts one year so is_member is false if SYSDATE > start_date + 1year . 每个成员资格仅持续一年,因此如果SYSDATE > start_date + 1year年,则is_member为false。

I would like to do a check to see if a user is still a member (and change is_member if not) before the user calls a select statement. 我想在用户调用select语句之前检查用户是否仍然是成员(如果没有,则更改is_member )。 Is this possible? 这可能吗?

If not has anyone got any ideas on how else to keep the is_member field up to date? 如果没有人有任何想法如何保持is_member字段是最新的? Can you do a trigger that is called once a day to see if the membership has expiered? 你可以做一个每天调用一次的触发器来查看会员资格是否已经过期?

Thanks in advace! 谢谢你的推荐! =] =]

Don't use a table column to store dependent data, use a view: 不要使用表列来存储依赖数据,使用视图:

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

The is_member view column will always contain up-to-date data. is_member视图列将始终包含最新数据。

There is no such thing as a BEFORE SELECT trigger in PL/SQL. PL / SQL中没有BEFORE SELECT触发器。

It sounds like is_member should not be a column in a table at all but should be something that is computed in a view. 听起来像is_member根本不应该是表中的列,而应该是在视图中计算的东西。 Something like 就像是

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

Your code would then simply query the view rather than querying the base table. 然后,您的代码将只查询视图而不是查询基表。

This is a job for the application to do the checking not a trigger. 这是应用程序执行检查而不是触发器的作业。 Triiger do not fire on SELECT. Triiger不会激活SELECT。

As far as keeping the field up-to-date, there are two possibilities. 至于保持该领域的最新状态,有两种可能性。 First set up a nightly job to inactivate any members whose meberships have expired. 首先设立夜间工作,以灭活任何已经过期的会员。 Or change your struture to store membershipenddate rather than isactive and use that in the application check to see if the member is active. 或者将结构更改为存储membershipenddate而不是isactive,并在应用程序检查中使用它来查看该成员是否处于活动状态。

You can add a Policy to your table and schema and Add the code that you want. 您可以向表和架构添加策略并添加所需的代码。

http://docs.oracle.com/cd/B28359_01/network.111/b28531/vpd.htm#CIHCAACD 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;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM