0
CREATE OR REPLACE FUNCTION update()
  RETURNS TRIGGER 
  LANGUAGE PLPGSQL
  AS
$$
BEGIN
    with name_array as (select jsonb_array_elements(inputs #> '{lists}')  AS lists
    from random.model
                             )
                             select name_array.lists #>> '{name}' as name,
                                    name_array.lists #>> '{value}' as value
                                    from name_array;

    IF NEW.value   <> OLD.value THEN
         INSERT INTO random.model_tracker(userid,modelid,datetime,oldjsoninput,newjsoninput,action)
         Values (old.user_id,old.id,now(),
                 '{"lists": [{"name": "OLD.name"}, {"value": "OLD.value"}]}'
                 ,'{"lists": [{"name": "NEW.name"},{"value": "NEW.value"}]}'
                 ,'UPDATE');
    END IF;

    RETURN NEW;
END;
$$

Trigger

CREATE TRIGGER update AFTER UPDATE ON random.model FOR EACH ROW EXECUTE PROCEDURE update();

When i am running inner query, it produces outputs as text for name and value. This function gets created however when i update values on the table i am getting this error:

ERROR: query has no destination for result data HINT: If you want to discard the results of a SELECT, use PERFORM instead. CONTEXT: PL/pgSQL function update() line 6 at SQL statement SQL state: 42601

Luke
  • 1
  • 2
  • Welcome to the SO community. The community will help with your issues, but there are certain expectations on you. Please take a few minuets to take the [Tour](https://stackoverflow.com/tour) and review [ask]. Then update your question to include sample data, table definition (ddl scripts), the expected results of that data, all as text - **no images**. Further clearly describe what you are attempting and where you are having issues. Finally saying your function is *throwing an error* is completely useless. You must post the entire error message. – Belayer Jan 18 '23 at 18:16
  • Could be the trigger and not the trigger function. Can you post the trigger also?The definitions of WHEN , AFTER BEFORE , FOR EACH ROW is very important to solve the problem. – mwalter Jan 18 '23 at 18:56
  • @Belayer I have updated the post with error message as well. Function gets created but error appears when record is updated on the table. Posted error description as well. – Luke Jan 18 '23 at 20:05
  • @mwalter I have posted the trigger too above – Luke Jan 18 '23 at 20:06
  • Inside of a function or procedure you cannot make a select withouth giving the result to a variable. DECLARE rRecord RECORD ; BEGIN WITH q AS( SELECT 'aa' a ) SELECT q.a INTO rRecord ; INSERT INTO table rRecord.a; END; – mwalter Jan 19 '23 at 02:02

1 Answers1

0

any select inside of a function need to be placed inside of a variable, that was the error message. made another version of the json :

CREATE OR REPLACE FUNCTION update()
  RETURNS TRIGGER 
  LANGUAGE PLPGSQL
  AS
$$
BEGIN
 
    IF NEW.value   <> OLD.value THEN
         INSERT INTO random.model_tracker(userid,modelid,datetime,oldjsoninput,newjsoninput,action)
         Values (old.user_id,old.id,now(),
                 (SELECT * FROM (WITH lists (lists ) AS (
 WITH q ( name , value ) AS
 ( SELECT OLD.name , OLD.value )  SELECT array_to_json( ARRAY[row_to_json(q)] ) FROM q 
)SELECT row_to_json(list.*) FROM lists
)) , 
(SELECT * FROM (
 WITH lists (lists ) AS (
 WITH q ( name , value ) AS
 ( SELECT NEW.name , NEW.value )  SELECT array_to_json( ARRAY[row_to_json(q)] ) FROM q 
)SELECT row_to_json(list.*) FROM lists
))   ,'UPDATE');
    END IF;

    RETURN NEW;
END;
$$
mwalter
  • 102
  • 5
  • Thanks for your help, i tried this but still throwing an error. Now, error message is different. Here is an error messsage: ERROR: record "new" has no field "value" CONTEXT: SQL statement "SELECT NEW.value <> OLD.value" PL/pgSQL function update() line 4 at IF SQL state: 42703 – Luke Jan 19 '23 at 15:17
  • @Luke the referenced table in the trigger doesnt have the column "value" – mwalter Jan 19 '23 at 19:08
  • there is an "input" column in the referenced table which has data type jsonb. This input column has the field "value" which i am able to retrieve but it doesn't work in trigger. – Luke Jan 30 '23 at 18:00
  • try json->'arrayinjson'->>'value' PLpython3u is very strong to manipulate jsons with ease and can be used as trigger function. A Easy way to manipulate json in plpgsql is using composite types to handle the json structure : select * FROM json_populate_record(null::compositetype , json) INTO RECORDvariable; Arrays of this kind could be manipulate as SELECT (unnest(jsonarray)).* INTO RECORDvariable, assuming that even the json structure from the array is properly described. – mwalter Jan 31 '23 at 13:13