我在使用EXISTS或PERFORM函数时发现行是否存在问题

时间:2018-09-15 18:00:23

标签: postgresql

我发现了几个使用EXISTS和PERFORM的示例,但是没有一个可以满足我的要求。以下是我所拥有的并且有效,返回{"success" : true, "balance" : "500.00"}  :

CREATE TEMPORARY TABLE IF NOT EXISTS accounts (id text, balance text);
INSERT INTO accounts(id, balance) VALUES ('123', '500.00');

CREATE OR REPLACE FUNCTION pg_temp.get_balance(id text)
RETURNS json AS
$$
SELECT json_build_object('success', true, 'balance', balance)
FROM
    (
        SELECT balance FROM accounts WHERE id = id
    ) _;
$$
LANGUAGE 'sql' VOLATILE;

SELECT pg_temp.get_balance('123');

当然,有时会有一个帐户-例如SELECT pg_temp.get_balance('456');-不存在。然后,我想得到某事。像{"success" : false}。有人可以给我提示该怎么做吗?

3 个答案:

答案 0 :(得分:0)

您可以使用:

CREATE OR REPLACE FUNCTION pg_temp.get_balance(_id text)
RETURNS json AS
$$
SELECT json_build_object('success', _.balance IS NULL, 'balance', balance)
FROM (SELECT 1) s
LEFT JOIN LATERAL (SELECT balance FROM accounts WHERE id = _id) _ ON TRUE;
$$
LANGUAGE 'sql' VOLATILE;

db<>fiddle demo


请注意,您的示例由于以下原因而无法正常工作

SELECT balance FROM accounts WHERE id = id -- always true
=> 
SELECT balance FROM accounts WHERE id = _id (changed parameter name)

答案 1 :(得分:0)

一种方法是

CREATE OR REPLACE FUNCTION pg_temp.get_balance(_id text)
RETURNS json AS
$$
select '{"success" : false}'::json where not exists(select 1 from accounts where id = _id)
union all
select json_build_object('success', true, 'balance', balance) FROM accounts WHERE id = _id
$$
LANGUAGE 'sql' VOLATILE;

答案 2 :(得分:0)

使用一个小技巧:

with accounts (id, balance) as (values(123, 500.00))
select * from (select) as dummy left join accounts on (id = 123);

即使右表中没有数据,它也允许返回至少一行。请注意,过滤条件应在join on部分而不是where子句中。

然后您可以将结果转换为JSON

with accounts (id, balance) as (values(123, 500.00))
select json_build_object('success', id is not null, 'balance', balance)
from (select) as dummy left join accounts on (id = 123);

如果您不希望使用“余额”键(如果请求的帐户不存在),则可以使用case语句:

with accounts (id, balance) as (values(123, 500.00))
select
    case
        when id is null then json_build_object('success', false)
        else json_build_object('success', true, 'balance', balance)
    end
from (select) as dummy left join accounts on (id = 456);