PostgreSQL - zwracanie wyników w JSON i instrukcja IF..ELSE

0

Witam,
męczę się z następującym problemem - wykonuję jakiegoś prostego SELECTa do bazy i chcę zwrócić wynik w formacie JSON (od bodajże wersji postgreSQL 9.3 jest to dostępne..). To wszystko działa w porządku. Sprawa komplikuje się jak chcę wykorzystać warunek IF..ELSE, gdyż w przypadku procedury składowanej, w której wykorzystuje się funkcję row_to_json() zwracającą JSONa wymagane jest użycie języka SQL. Natomiast w przypadku polecenia IF..ELSE wymagane jest użycie PL/pgSQL, z tym że wtedy nie działają mi funkcje związane z JSONem.. -.-

Ogólnie patowa sytuacja.. Chyba, że można jakoś na około dojść do ostatecznego celu tego zapytania. Na ten moment to wygląda tak:

CREATE OR REPLACE FUNCTION "schema1"."somefunction"(serialnumber character varying)
  RETURNS json AS
  $BODY$
        SELECT row_to_json(t) FROM (
            SELECT "col1","col2","col3","col4"
            FROM "schema1"."tab1"
            WHERE (SELECT "d1" FROM "schema1"."Dtab" WHERE "SN" = serialnumber) = ANY("col5_array")
        ) t;
$BODY$
  LANGUAGE SQL ;

W 'normalnych' procedurach składowanych wykorzystywałem wyrażenie IF EXISTS (SELECT (1) FROM ...) no, ale w opisanym wyżej przypadku to nie chce funkcjonować..

Ogólnie efekt końcowy jaki chciałbym osiągnąć to do tego kodu co jest wyżej zrobić warunek, że jeżeli nie znajdzie wyników dla danego *serialnumber *to ma wyrzucić pewne 'stałe' dane, np coś takiego:

   SELECT '{"data": "not found"}'::json;

Może ktoś z Was miał okazje robić coś podobnego..
pzdr,
M

ps. Kombinowałem coś z warunkiem CASE WHEN, ale ostatecznie nie otrzymałem pożądanych efektów.

2
select row_to_json(x) FROM
(
  select 
    case when (select count(*) from  price where article_id = 458 and contractor_id = 91763) = -1 then 
      0 
    else
      (select price from  price where article_id = 458 and contractor_id = 91763) end 
) x

zamień sobie to do swoich warunków. Generalnie za -1 podstawiasz to co ma zwrócić jeśli nie będzie danych tylko, że typ musi być taki sam jak typ zwracany przez "dolne" zapytanie

0

@abrakadaber - po pierwsze dzięki za odpowiedź. Chciałbym jednak kontynuować, gdyż ja chcę zwrócić więcej niż dane z jednej kolumny, a w takim przypadku jedyne co mi zadziałało to praktycznie powielenie całego warunku CASE WHEN :

SELECT row_to_json(x) FROM
(
  SELECT 
    CASE WHEN (SELECT nam eFROM  price WHERE article_id = 458 AND contractor_id = 91763) = null THEN 
      'empty'
    ELSE
      (SELECT name FROM  price WHERE article_id = 458 AND contractor_id = 91763) END,

    CASE WHEN (SELECT price FROM  price WHERE article_id = 458 AND contractor_id = 91763) = -1 THEN 
      0 
    ELSE
      (SELECT priceFROM  price WHERE article_id = 458 AND contractor_id = 91763) END,

   CASE WHEN
   ...
   END
) x

Pytania są więc dwa:

  1. Czy można to jakoś uprościć ? Ja ogólnie będę chciał zwracać w tym przypadku 4 kolumny, ale to i tak wydaje mi się 'dość skomplikowane przedsięwzięcie' z tyloma select'ami i where'mai.
  2. Coś nie wyświetlają mi się domyślnie wstawione przeze mnie wartości. Np. jak mam typ varchar to chciałbym uzyskać słowo empty, ale za każdym razem, we wszystkich kolumnach mam nulldla nieznalezionego wyniku.
0
SELECT row_to_json(x) FROM
(
  SELECT 
    Coalesce(name,'empty'),
    CASE WHEN price  = -1 THEN  0 else price END,
...
FROM  price WHERE article_id = 458 AND contractor_id = 91763
) x
1
CREATE TABLE test (
  id serial,
  col1 varchar(10),
  col2 varchar(20),
  col3 timestamp default current_timestamp);
  
insert into test(col1, col2) values ('val11', 'val12');
insert into test(col1, col2) values ('val21', 'val22');
insert into test(col1, col2) values ('val31', 'val32');
insert into test(col1, col2) values ('val41', 'val42');
insert into test(col1, col2) values ('val51', 'val52');
insert into test(col1, col2) values ('val61', 'val62');

select * from test;

SELECT row_to_json(x) FROM
(
  select col1, col2, col3 from
    (select 1 lp, col1, col2, col3 from test where id = 13
    union
    select 2, 'empty', 'empty', null
    order by 1
    limit 1) y
) x

Wynik selecta
scr1.png
wynik z id, którego nie ma
scr2.png
wynik z id, które jest
scr3.png

1 użytkowników online, w tym zalogowanych: 0, gości: 1