0

我正在尝试在 PostgreSQL 中编写一个函数,该函数在插入 Cloudant 文档时通过侦听 Cloudant 来接收记录(我想让它成为一个 lambda,但现在它是一个节点进程)。

我正在获取 Cloudant id 和完整文档并将其插入到case_raw表中,其中包含以下列:char(32)id和 json type raw_json

CREATE TABLE report_db.case_raw
(
    doc_id character(32) NOT NULL PRIMARY KEY,
    raw_json jsonb NOT NULL
)

从 Cloudant 到 Postgres 的努力是为了让我可以对来自边缘设备的 JSON 形式的数据进行复杂的连接等。

这是 Cloudant 文档的示例,我id在 id 列中使用了相同的示例,它将被插入到raw_json.

{
    "name": {
        "id": "4e1e3425ef49b3b028683a5cb06ca585",
        "doc": {
            "_id": "4e1e3425ef49b3b028683a5cb06ca585",
            "_rev": "1-feae33bee0b773c7d130b1dd6fb42869",
            "doc_type": "standard",
            "location": {
                "carrier": "AT&T",
                "mobileCountryCode": 123,
                "mobileNetworkCode": 456
            }
        }
    }
}

现在,我想创建一个触发器,为每一行调用一个函数ON INSERT

但是,我马上就要挂断电话了。我已经尝试了所有我能想到的方法,包括:WITH、嵌套 SELECT、to_json、强制转换 ::json,我敢打赌这很简单,但为什么我不能(似乎)不使用 JSON 运算符?

例如,我可以直接查询记录并从该记录中获取我想要的数据(以两种不同的方式获得相同的东西):

SELECT * FROM case_raw WHERE raw_json->'name'->'doc'->'location'->>'carrier' = 'AT&T';

SELECT * FROM case_raw WHERE raw_json @> '{"name":{"doc": {"location": { "carrier": "AT&T"}}}}'

但是,对于我的生活,我无法进入 JSON。我已经阅读了至少 20 篇文章、PG 文档、PG 教程,但没有找到任何可以推动我前进的东西。非常感谢任何见解。在这里,我大大减少了使用with等的尝试。PGAdmin 在->'name'.

CREATE OR REPLACE FUNCTION parse_raw ()
RETURNS trigger AS '
BEGIN
  -- We have a lot more values to insert, but PG does not seem to like the syntax of the following:
  INSERT INTO report_db.location_master VALUES (NEW.raw_json->'name'->'doc'->'location'->>'carrier');
  RETURN NEW;
END' LANGUAGE 'plpgsql';

-- setup on before insert trigger to parse into tables
CREATE TRIGGER parse_raw_trigger
BEFORE INSERT ON report_db.case_raw
FOR EACH ROW
EXECUTE PROCEDURE parse_raw();
4

1 回答 1

1

您正在将字符串嵌入字符串中。所以对于嵌入'name'的单引号需要转义。所以你基本上有' ... 'name' ... which 不是一个有效的字符串常量。它应该是' ... ''name'' ...'

为了更容易,通常的方法是用美元引号包裹整个函数体(字符串)

在 INSERT 语句中始终限定目标列也是一种很好的编码习惯。

CREATE OR REPLACE FUNCTION parse_raw ()
RETURNS trigger AS 
$body$ --<< replaces the '
BEGIN
 -- We have a lot more values to insert, but PG does not seem to like the syntax of the following:
 INSERT INTO report_db.location_master (carrier) VALUES (NEW.raw_json->'name'->'doc'->'location'->>'carrier');
 RETURN NEW;
END;
$body$ --<< replaces the '
LANGUAGE plpgsql;
于 2020-11-18T06:58:38.443 回答