当NEW.field为NULL时,PostgreSQL不会触发

时间:2016-09-21 09:13:16

标签: postgresql triggers

我的客户表上有以下触发器,因此我可以跟踪客户名称是否随时间变化以及该名称的先前版本是什么。

CREATE OR REPLACE FUNCTION fn_customer_changes_log_history() RETURNS trigger as 
$BODY$
    BEGIN
       IF (NEW.name <> OLD.name)  
    THEN
        INSERT INTO tbl_customers_history(customer_id, name, action)
        VALUES(OLD.id, OLD.name, 'UPDATE');
    END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

CREATE TRIGGER tr_customer_changes_log_history
BEFORE UPDATE ON tbl_customers
FOR EACH ROW
EXECUTE PROCEDURE fn_customer_changes_log_history();

但是当我在NEW.name = NULL和OLD.name =“Customer 1”时执行UPDATE时,不会触发此触发器?它仅在NEW.name在此处具有实际字符串值时触发。

为什么? NULL和“Customer 1”不相等所以它应该触发?

3 个答案:

答案 0 :(得分:2)

使用

IF (NEW.name IS DISTINCT FROM OLD.name)

而不是

IF (NEW.name <> OLD.name)

答案 1 :(得分:1)

尝试将条件更改为

IF COALESCE((NEW.name <> OLD.name), true)

问题在于,如果NEW.fieldNULL,那么无论NEW.name <> OLD.name的值是什么,NULL的评估结果为OLD.name。在条件中,NULL始终被视为false。

更正确的答案是

IF COALESCE((NEW.name <> OLD.name), true) AND NOT (NEW.name IS NULL AND OLD.name IS NULL)
NEW.nameOLD.name都是NULL时,

要处理这种情况,以便在这种情况下不会将它们视为相等。

答案 2 :(得分:0)

<!DOCTYPE html> <html> <body> <p id="demo"></p> <script> var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { myFunction(this); } }; xhttp.open("GET", "db_from_excel.xml", true); xhttp.send(); function myFunction(xml) { var xmlDoc = xml.responseXML; document.getElementById("demo").innerHTML = xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue; } </script> </body> 始终评估为NULL <> 'anything'。就像FALSENULL = 'anything'

一样

您需要NULL > 5来修正比较:

coalesce