SQL触发器禁止删除超过2周的数据

时间:2014-12-20 20:42:41

标签: postgresql date triggers timestamp

我需要帮助创建一个触发器,禁止用户删除超过2周的数据。 我目前的代码:

CREATE OR REPLACE FUNCTION f_delete_data() RETURNS trigger AS $$
BEGIN
 RAISE EXCEPTION 'Cant delete data which is newer than 2 weeks.';
 RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trig_delete_data BEFORE DELETE ON Results
 FOR EACH ROW WHEN (OLD.Date < DATE_SUB(NOW(), INTERVAL 14 DAY)) EXECUTE PROCEDURE
f_delete_data();

此代码表示在14或接近14时出现语法错误 为什么date_sub(..,interval 14 day)无效?

我正在使用PostgreSQL 9.3.0。

2 个答案:

答案 0 :(得分:2)

  

为什么date_sub(..,intercval 14天)不起作用?

$$ LANGUAGE plpgsql;表示你正在使用postgres,但DATE_SUB是一个MySQL特有的函数,在postgres中不可用。

尝试用此

替换DATE_SUB

(OLD.Date < NOW() - INTERVAL '14 DAYS')

答案 1 :(得分:1)

除了明显的错误(Postgres中没有DATE_SUB)之外,你的逻辑也向后倾斜。如果您想保护date列中的值少于2周的行:“2周以上”,则必须还原比较运算符。

CREATE TRIGGER trig_delete_data
BEFORE DELETE ON results
FOR EACH ROW
WHEN (OLD.date < DATE_SUB(NOW(), INTERVAL 14 DAY))
WHEN (OLD.date < now() - interval '14 days')
WHEN (OLD.date > now() - interval '14 days')
EXECUTE PROCEDURE f_delete_data();

f_delete_data() 的名字应该是f_protect_new_data()

或者,如果您的列是实际的date,就像错误选择的列名所示,进一步简化:

WHEN (OLD.date >= CURRENT_DATE - 14)

The manual on CURRENT_DATE & friends.
在这种情况下使用 >= ,根据您的定义,从今天起的第14天仍然是非法的。绑定在逻辑上与timestamp处理有点不同。

为什么“选择不当”? “date”是Postgres中的reserved word in standard SQL和基本类型名称。如果该列实际上包含timestamp,而不是date,那么它就会产生误导。