【问题标题】:building a trigger function to process json data with postgres使用 postgres 构建一个触发器函数来处理 json 数据
【发布时间】:2016-01-14 15:51:22
【问题描述】:

我在构建 pl/pgsql 函数来处理 json 数组时遇到了困难。

我从客户端收到的数据是用户对问题的回答列表,我存储在我的表体验中一个名为“数据”的 json 类型字段中。

[
{"completed":false},
{"completed":false},
{"completed":false},
{"completed":true,"score":1,"answerList":["1"],"QuestionId":75,"startTime":"2016-01-09T16:40:06.153Z","clickNb":1,"endTime":"2016-01-09T16:40:07.844Z"},
{"completed":true,"score":1,"answerList":["1"],"QuestionId":76,"startTime":"2016-01-09T16:40:08.487Z","clickNb":1,"endTime":"2016-01-09T16:40:12.482Z"},
{"completed":true,"score":1,"answerList":["1"],"QuestionId":77,"startTime":"2016-01-09T16:40:13.042Z","clickNb":1,"endTime":"2016-01-09T16:40:17.689Z"}
]

我想构建一个触发函数来将所有分数相加并将结果保存在一个名为 accuracy_score 的字段中。这是我到目前为止所构建的:

CREATE OR REPLACE FUNCTION calculate_accuracy() RETURNS TRIGGER AS $$
DECLARE 
    dataarray json;

BEGIN
    dataarray := json_array_elements(New.data);
    UPDATE experiences SET accuracy_score = subquery.score 
    FROM (SELECT SUM(dataarray->>'score') from dataarray) AS subquery 
    WHERE challenge_id = New.challenge_id;

    RETURN NULL;
END;
$$ LANGUAGE plpgsql;


CREATE TRIGGER calculate_accuracy
AFTER INSERT ON experiences
FOR EACH ROW EXECUTE PROCEDURE calculate_accuracy();

当我尝试运行它时收到以下错误消息:

错误:查询“SELECT json_array_elements(New.data)”返回多行 上下文:PL/pgSQL 函数 calculate_accuracy() 分配时的第 6 行

我不知道如何解决这个问题。在这方面提供更多的帮助!

【问题讨论】:

    标签: json postgresql plpgsql


    【解决方案1】:

    如果要更改插入行中的值,请使用 BEFORE TRIGGER 并在触发器函数中更改记录 NEW:

    CREATE OR REPLACE FUNCTION calculate_accuracy() RETURNS TRIGGER AS $$
    BEGIN
        NEW.accuracy_score = (
            SELECT sum((e->>'score')::int)
            FROM json_array_elements(NEW.data) e);
        RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
    
    CREATE TRIGGER calculate_accuracy
    BEFORE INSERT ON experiences
    FOR EACH ROW EXECUTE PROCEDURE calculate_accuracy();
    

    测试:

    insert into experiences (challange_id, data)
    values
    (1, 
    '[
    {"completed":false},
    {"completed":false},
    {"completed":false},
    {"completed":true,"score":1,"answerList":["1"],"QuestionId":75,"startTime":"2016-01-09T16:40:06.153Z","clickNb":1,"endTime":"2016-01-09T16:40:07.844Z"},
    {"completed":true,"score":1,"answerList":["1"],"QuestionId":76,"startTime":"2016-01-09T16:40:08.487Z","clickNb":1,"endTime":"2016-01-09T16:40:12.482Z"},
    {"completed":true,"score":1,"answerList":["1"],"QuestionId":77,"startTime":"2016-01-09T16:40:13.042Z","clickNb":1,"endTime":"2016-01-09T16:40:17.689Z"}
    ]'::json)
    returning challange_id, accuracy_score;
    
     challange_id | accuracy_score 
    --------------+----------------
                1 |              3
    (1 row) 
    

    【讨论】:

      猜你喜欢
      • 2022-01-25
      • 1970-01-01
      • 2023-04-07
      • 2019-05-14
      • 2014-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多