您好我正在使用sqldeveloper连接到oracle数据库。
我的senario是我的数据库中有一个客户表,其中包含一个名为start_date
的日期字段,其中包含用户注册日期的日期和名为is_member
的“布尔”字段。每个成员资格仅持续一年,因此如果is_member
SYSDATE > start_date + 1year
,则is_member
为假。
我想在用户调用select语句之前检查用户是否仍然是成员(如果没有,则更改is_member
)。这可能吗?
如果没有人有任何关于如何使{{1}}字段保持最新的想法?您是否可以每天调用一次触发器来查看成员资格是否已过期?
先谢谢! =]
答案 0 :(得分:5)
不要使用表格列存储相关数据,请使用视图:
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
视图列将始终包含最新数据。
答案 1 :(得分:4)
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
然后,您的代码将只查询视图而不是查询基表。
答案 2 :(得分:1)
这是应用程序执行检查而不是触发器的作业。 Triiger不会激活SELECT。
至于保持现场最新,有两种可能性。首先设立夜间工作,以灭活任何已经过期的会员。或者将结构更改为存储membershipenddate而不是isactive,并在应用程序检查中使用它来查看该成员是否处于活动状态。
答案 3 :(得分:0)
您可以向表和架构添加策略并添加所需的代码。
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;
答案 4 :(得分:0)
您可以定义每天运行的作业并更新is_member字段。