У меня проблемы с использованием EXISTS или PERFORM в функции, чтобы узнать, существует строка или нет - PullRequest
0 голосов
/ 15 сентября 2018

Я нашел несколько примеров с 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 голосов
/ 15 сентября 2018

В одну сторону

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;
0 голосов
/ 15 сентября 2018

Используя один маленький трюк:

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);
0 голосов
/ 15 сентября 2018

Вы можете использовать:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...