2016-03-01 34 views
1

施加我已經定義以下面的方式柱:默認值不PostgreSQL中使用聚結並INET功能

UserIP INET NOT NULL DEFAULT COALESCE(inet_client_addr(), inet_server_addr()) 

目的是存儲用戶IP每當所述查詢從所述客戶端上運行或服務器端。

如果我在連接兩側運行下面的查詢,它的工作原理:

SELECT COALESCE(inet_client_addr(), inet_server_addr()) 

它提供在服務器端的客戶端和服務器的IP用戶的IP。

只要我從客戶端運行插入,一切都很好。但是當我從服務器上運行它時,我認爲這個字段的約束違反,假設它是NULL。

ERROR: null value in column "userip" violates not-null constraint 
DETAIL: Failing row contains (36552583, [...] null (null is returned for userip), [...]) 

COALESCE函數似乎被忽略。

我錯過了什麼?我怎麼能實現它?

更新

我也有此表被觸發更新觸發:

CREATE TRIGGER update_datap2_user 
    BEFORE UPDATE 
    ON scientific.datap2 
    FOR EACH ROW 
    EXECUTE PROCEDURE scientific.updateuser(); 

凡觸發功能如下:

CREATE OR REPLACE FUNCTION scientific.updateuser() 
    RETURNS trigger AS 
$BODY$ 
BEGIN 
    IF ROW(NEW.*) IS DISTINCT FROM ROW(OLD.*) THEN 
     NEW.Updated = now()::timestamp; 
     NEW.UserName = current_user; 
     NEW.UserIP = COALESCE(inet_client_addr(), inet_server_addr()); 
     RETURN NEW; 
    ELSE 
     RETURN OLD; 
    END IF; 
END; 
$BODY$ 
    LANGUAGE plpgsql 

回答

1

,除非有一個錯字(在問題中),UPDATE觸發器不應該干擾服務器端的INSERT查詢,所以這是一個複雜的問題o窗戶。

COALESCE函數中可能應該有更多的回退函數(127.0.0.1/0.0.0.0),因爲看起來選擇的兩個選項不構成Universe。

例如,當我在postgres服務器上運行bash中的psql這個SQL時,我得到了兩個函數調用的NULL

postgres=# select inet_client_addr(); 
inet_client_addr 
------------------ 

(1 row) 

postgres=# select inet_server_addr(); 
inet_server_addr 
------------------ 

(1 row) 

postgres=# 

您也可以寧可除去NOT NULL約束的側面(並因此移除上面給出的回退),因爲有效他們是壞的數據。我寧願有空單元格,而不是在我所有的SQL中永久性地過濾魔法文本。

此外,從doc,All these functions return NULL if the current connection is via a Unix-domain socket.