sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur man ändrar eller tar bort ett specifikt JSON-objekt från JSON-arrayen lagrad i jsonb-kolumntypen i PostgreSQL med where-sats?

Båda problemen kräver att de (modifierade) JSON-elementen återskapas och aggregeras. För båda problemen skulle jag skapa en funktion för att göra det lättare att använda.

create function remove_element(p_value jsonb, p_to_remove jsonb)
  returns jsonb
as
$$
  select jsonb_agg(t.element order by t.idx)  
  from jsonb_array_elements(p_value) with ordinality as t(element, idx)
  where not t.element @> p_to_remove;
$$
language sql
immutable;

Funktionen kan användas så här, t.ex. i en UPDATE-sats:

update the_table
  set the_column = remove_element(the_column, '{"ModuleId": 1}')
where ...

För det andra problemet kommer en liknande funktion till hands.

create function change_value(p_value jsonb, p_what jsonb, p_new jsonb)
  returns jsonb
as
$$
  select jsonb_agg(
         case
           when t.element @> p_what then t.element||p_new
           else t.element
         end order by t.idx)  
  from jsonb_array_elements(p_value) with ordinality as t(element, idx);
$$
language sql
immutable;

|| operatören kommer att skriva över en befintlig nyckel, så detta ersätter effektivt det gamla namnet med det nya namnet.

Du kan använda det så här:

update the_table
  set the_column = change_value(the_column, '{"ModuleId": 1}', '{"ModuleName": "CBA"}')
where ...;

Jag tror att det är lite mer flexibelt att skicka JSON-värdena än att hårdkoda nycklarna, vilket gör användningen av funktionen mycket begränsad. Den första funktionen kan också användas för att ta bort arrayelement genom att jämföra flera nycklar.

Om du inte vill skapa funktionerna, ersätt funktionsanropet med select från funktionerna.



  1. order by rand() får problem för stora inlägg

  2. Vitlista IP-adressintervall med cPanel

  3. PHP-sökskript för mySQL-databas, endast 3 bokstäver fungerar

  4. Postgres:Begränsning med endast kryss på INSERT