INSERT JSON 到两个表和 return 序列号

INSERT JSON into two tables and return serial ID

我正在尝试将新记录 INSERT 写入 Postgres 9.6 数据库,并获取新插入记录的 ID 并将其传递给不同的 table 作为外键引用。数据采用 JSON 格式,我想将 JSON blob 存储在行字段中,而不是将其解析出来。但是,我收到有关 NULL 值违反 PRIMARY KEYNOT-NULL 约束的错误。

我假设我的代码应该在 my_data table 中创建一个新记录(data_id 自动生成并且 data_fields 填充我的 JSON 对象),但我的假设似乎不正确。

我缺少或没有完全掌握什么?下面是复制我的设置的代码。

表:

CREATE TABLE my_data(
  data_id SERIAL PRIMARY KEY,
  data_fields JSONB
);

CREATE TABLE request_data(
    request_id SERIAL PRIMARY KEY,
    request_timestamp TIMESTAMP WITH TIME ZONE,
    data_id INTEGER REFERENCES my_data(data_id),
    record_count INTEGER,
    completedStatus boolean
);

函数:

CREATE OR REPLACE FUNCTION updateData (
dataFields JSONB,
requestTimestamp TIMESTAMP WITH TIME ZONE,
recordCount INTEGER,
completedStatus boolean,
OUT new_record_id INTEGER
)
RETURNS integer AS $$
BEGIN
INSERT INTO my_data SELECT * FROM jsonb_populate_recordset(NULL::my_data, ::jsonb) RETURNING data_id INTO new_record_id;
INSERT INTO request_data (request_timestamp, data_id, record_count, completed_status) VALUES(, new_record_id, , );
END;
$$ LANGUAGE plpgsql;

致电:

SELECT updateData (
'[{"identity": "personA", "timestamp": "2017-09-15T20: 03: 12+00: 00"},
{"identity": "personB", "timestamp": "2017-09-15T20: 03: 12+00: 00"},
{"identity": "personC", "timestamp": "2017-09-15T20: 03: 12+00: 00"}]'
 '2017-09-29', 
 3, 
 true)

错误:

ERROR: null value in column "data_id" violates not-null constraint
SQL state: 23502
Detail: Failing row contains (null, null).

my_datatable的预期结果:

data_id     | data_fields
------------+------------------------------
    1       | [{"identity": "personA", "timestamp": "2017-09-15T20: 03: 12+00: 00"},{"identity": "personB", "timestamp": "2017-09-15T20: 03: 12+00: 00"},{"identity": "personC", "timestamp": "2017-09-15T20: 03: 12+00: 00"}]

request_datatable的预期结果:

request_id  |    request_timestamp     | data_id | record_count | completed_status
------------+--------------------------+---------+--------------+-------------------
    1       |   2017-09-29             |  1      |  3           |   true

@Fahad Anjum 指出了插入 json 的更好方法。我将 INSERT 语句更改为 INSERT INTO my_data (data_fields) values() RETURNING data_id INTO new_record_id;,它给了我需要的结果。

@Fahad 指出了主要的逻辑错误。

但您不需要在 (::jsonb) 中进行强制转换,因为输入参数已键入 jsonb

我会推荐一个 单一 查询和一个数据修改 CTE 将两个插入组合在一个简单的 SQL 函数中 - 而不是两个 INSERT 查询在 PL/pgSQL 函数之间进行赋值。更短、更不容易出错、更快:

CREATE OR REPLACE FUNCTION update_data(data_fields jsonb
                                     , request_timestamp timestamptz
                                     , recordcount integer
                                     , completed_status boolean)
  RETURNS integer AS
$func$
   WITH ins1 AS (
      INSERT INTO my_data(data_fields)
      VALUES ()  -- no need to cast
      RETURNING data_id
      )
   INSERT INTO request_data(request_timestamp, data_id, record_count, completed_status)
   SELECT , i.data_id, , 
   FROM   ins1 i
   RETURNING data_id
$func$  LANGUAGE sql;

我也统一了小写拼写。您混合使用了命名约定,导致 completedStatuscompleted_status 之间不匹配。我的一贯建议是避免在 Postgres 中对标识符进行大小写混合拼写。

相关:

  • PostgreSQL multi INSERT...RETURNING with multiple columns
  • Insert inserted id to another table
  • Are PostgreSQL column names case-sensitive?