我按以下方式定义了一个列:
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
最佳答案
除非有错字(在问题中),否则 UPDATE 触发器不应干扰服务器端的 INSERT 查询,因此这是不可能的。
您可能应该在 COALESCE
函数中有更多回退 (127.0.0.1/0.0.0.0
),因为似乎所选的两个选项不构成宇宙.
例如当我在 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 , 如果当前连接是通过 Unix 域套接字,则所有这些函数都返回 NULL。
关于postgresql - 在使用 COALESCE 和 inet 函数的 PostgreSQL 中不应用默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35728613/