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

PostgreSQL - zwracanie wyników w JSON i instrukcja IF..ELSE
MI
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 8 lat
  • Postów:110
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:

Kopiuj
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:

Kopiuj
   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.

abrakadaber
abrakadaber
  • Rejestracja:ponad 12 lat
  • Ostatnio:8 miesięcy
  • Postów:6610
2
Kopiuj
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


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
MI
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 8 lat
  • Postów:110
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 :

Kopiuj
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.
Marcin.Miga
Nulle porównujemy przez IS NULL, a nie = NULL
Marcin.Miga
  • Rejestracja:prawie 17 lat
  • Ostatnio:2 dni
  • Postów:2792
0
Kopiuj
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
edytowany 2x, ostatnio: Marcin.Miga
abrakadaber
abrakadaber
to nie przejdzie bo jak nie będzie rekordu to i coalesce nie zadziała :)
abrakadaber
abrakadaber
  • Rejestracja:ponad 12 lat
  • Ostatnio:8 miesięcy
  • Postów:6610
1
Kopiuj
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


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
MI
Sympatyczny trick ;)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.