COALESCE 在 Postgres 12 SQL 存储函数中似乎没有触发

问题描述

使用 Postgres 12.x,我遇到了一个奇怪的问题。出于某种原因,我没有让 COALESCE 在存储的 sql 函数中工作。意思是,我得到 NULL 而不是我的第一个非空值。

我怀疑我错过了一些明显的东西,但我看不到它。任何人都可以发现问题是什么?我已经构建了一个重现该问题的独立示例。

谢谢

测试设置

BEGIN;

------------------------------------
-- Define table
------------------------------------

DROP TABLE IF EXISTS lookup_table CASCADE;

CREATE TABLE IF NOT EXISTS lookup_table (
    id    uuid    NOT NULL DEFAULT NULL,-- Values are geneated by an outside system.
    name_ citext  NOT NULL DEFAULT NULL
);

------------------------------------
-- Seed
------------------------------------
INSERT INTO lookup_table (id,name_) 
     VALUES  ('6ea225f3-9819-49eb-bdb8-f3ae23af6337','John'),('ae2282c6-ca9b-413f-b182-a1ca69fc3c78','Alice'),('7ee1ce1b-4efc-426c-a6f8-5b2375cb357e','Magrite'),('71c3d96a-3ac7-454e-bfff-e5551428c017','Arjun');

------------------------------------
-- Define the lookup fnction
------------------------------------
CREATE OR REPLACE FUNCTION lookup_function (id_in uuid)
     RETURNS citext AS

$BODY$

-- For some reason,COALESCE doesn't work here,but does outside of a function. Weird.
-- Tried with CTE,same same.
SELECT COALESCE (name_,'') FROM lookup_table WHERE id = id_in;

$BODY$
  LANGUAGE sql;

------------------------------------
-- Test it out
------------------------------------
SELECT 'Alice' AS description,lookup_function ('ae2282c6-ca9b-413f-b182-a1ca69fc3c78') AS result
       UNION ALL
       
SELECT 'Should return an empty string,returns NULL instead'           AS description,lookup_function ('00000000-0000-0000-0000-000000000000') AS result

标准通话

为了进行比较,下面是一个运行正常的 SELECT 中的标准调用

select coalesce (name_,'') 
  from lookup_table
 where id = '00000000-0000-0000-0000-000000000000';
 -- Returns an empty string,not NULL.

但是,在 sql 函数中,此表达式返回 NULL

CTE 尝试

这是我尝试使用 CTE 在函数中提供帮助的尝试,但我仍然返回 NULL

------------------------------------
-- Define the lookup fnction
------------------------------------
CREATE OR REPLACE FUNCTION lookup_function (id_in uuid)
     RETURNS citext AS

$BODY$

WITH lookup_result AS (
   select name_ from lookup_table where id = id_in 
 )
 
SELECT CASE WHEN name_ IS NULL THEN ''
            ELSE name_ END
       FROM lookup_result

$BODY$
  LANGUAGE sql;

解决方法

查找函数不会从其中的 select 语句返回任何内容,因为 where 子句失败。因此,从不执行合并。 默认返回空值。

您可以将选择重写为:
select coalesce((SELECT name_ FROM lookup_table WHERE id = id_in),'');

,

合并会将 name_ 的 NULL 值转换为空字符串。但是您没有该列的 NULL 值,您有零行。这将在稍后阶段转换为 NULL,此时合并无法处理它。

也许你想要这个:

CREATE OR REPLACE FUNCTION lookup_function (id_in uuid)
     RETURNS citext AS                                                   
$BODY$                                                         
SELECT COALESCE (name_,'') FROM (values (id_in))f(x) left join lookup_table on id = x;    
$BODY$
  LANGUAGE SQL;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...