如果未找到值,如何 return 来自函数的值

How to return a value from a function if no value is found

我正在尝试 return 0.0 如果以下函数没有 return 任何东西:

CREATE OR REPLACE FUNCTION get_height(firstn VARCHAR, lastn VARCHAR)
  RETURNS FLOAT AS
$$
DECLARE
    height FLOAT = 0.0;
BEGIN
    SELECT into height AVG(((p.h_feet * 12) + p.h_inches) * 2.54)
    FROM player p
    WHERE p.firstname = firstn AND p.lastname = lastn; 

    RETURN height;
END;
$$ LANGUAGE plpgsql;

我尝试搜索它,发现 COALESCE 不起作用。有人知道如何解决这个问题吗?

Table结构:

 create table player(
                     firstname text
                    ,lastname text
                    ,h_feet INT
                    ,h_inches INT
                    );

示例数据:

  insert into player values ('Jimmy','Howard',6,2);

return coalesce(height, 0::decimal(10,2)); 应该可以解决问题

这是我使用的脚本。如您所见,我 运行 PostgreSQL 9.4.1。 我使用 HeidiSQL 来启动查询。 你确定你正确地更新了你的功能吗? 我刚刚注意到您在评论中使用了不同的函数 ('player_height') 而不是原始 post 中的 'get_height'。

select version();
-- PostgreSQL 9.4.1, compiled by Visual C++ build 1800, 64-bit

delimiter //

CREATE OR REPLACE FUNCTION get_height(firstn VARCHAR, lastn VARCHAR)         
RETURNS FLOAT AS $$
DECLARE
height FLOAT = 0.0;
BEGIN
    SELECT into height AVG(((p.h_feet * 12) + p.h_inches) * 2.54)
    FROM players p
    WHERE p.firstname = firstn AND p.lastname = lastn; 
        return coalesce(height, 0.0);
END;
$$ LANGUAGE plpgsql;

delimiter;

CREATE TABLE players (
     firstname varchar(40),
     lastname  varchar(40),
     h_feet int,
     h_inches int);


insert into players values ('Jimmy', 'Howard', 6, 2);

select * from get_height('Jimmy', 'Howard');
-- gives 187.96

select * from get_height('Random', 'Guy');
-- gives 0

说明

问题的根源在于"not anything"的模糊定义。

if the following function does not return anything

NULL不是什么,只是不知道它到底是什么。 "Nothing" 就 SQL 而言将是 无行 :根本没有 returned。当找不到行时通常会发生这种情况。但是当使用 聚合函数 时,这不会发生,因为 per documentation:

... these functions return a null value when no rows are selected.

avg() returns NULL 当没有找到行时(所以不是 "nothing")。作为结果,您得到一行带有 NULL 值的行 - 覆盖 您演示的代码中的初始值。

解决方案

将结果包装在 COALESCE 中。演示一个更简单的 SQL 函数:

CREATE OR REPLACE FUNCTION get_height_sql(firstn varchar, lastn varchar)
  RETURNS float AS
$func$
   SELECT COALESCE(AVG(((p.h_feet * 12) + p.h_inches) * 2.54)::float, 0)
   FROM   player p
   WHERE  p.firstname = firstn
   AND    p.lastname = lastn
$func$  LANGUAGE sql STABLE;

SQL Fiddle.

同样可以用在plpgsql函数中。此函数可以是 STABLE,可能有助于在较大查询的上下文中提高性能。

其他情况

如果您实际上可以从查询中得到没有行,一个简单的COALESCE 会失败,因为它从未执行过。

对于单值结果,您可以像这样包装整个查询:

SELECT COALESCE((SELECT some_float FROM ... WHERE ... LIMIT 1), 0) AS result
  • How to display a default value when no match found in a query?

PL/pgSQL 能够在实际 return 从函数中进行检查之前进行检查。这也适用于具有一列或多列的多行。有一个 example in the manual 演示了 FOUND:

的用法
...
RETURN QUERY SELECT foo, bar ...;

IF NOT FOUND THEN
    RETURN QUERY VALUES ('foo_default'::text, 'bar_default'::text);
END IF;
...

相关:

  • Return setof record (virtual table) from function
  • PostgreSQL - Check foreign key exists when doing a SELECT

要始终return恰好一行,您还可以使用纯SQL:

SELECT foo, bar FROM tbl
UNION ALL
SELECT 'foo_default', 'bar_default'
LIMIT 1;

如果第一个 SELECT return 没有行,第二个 SELECT return 有默认行。

尝试not found条件

SELECT ... into ...
FROM ...
WHERE ...; 

if not found then
  RETURN 0;
end if;