我正在尝试INSERT
Postgres 9.6数据库中的新记录,并获取新插入记录的ID并将其传递给另一个表以进行外键引用。数据采用JSON格式,我想将JSON blob存储在行字段中,而不是将其解析出来。但是,我收到有关NULL
违反NOT-NULL
PRIMARY KEY
约束的错误。
我假设我的代码应该在my_data
表中创建一个新记录(自动生成data_id
并用我的JSON对象填充data_fields
)但是它似乎我的假设不正确。
我缺少什么或者没有完全掌握?以下是复制我的设置的代码。
表:
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, $1::jsonb) RETURNING data_id INTO new_record_id;
INSERT INTO request_data (request_timestamp, data_id, record_count, completed_status) VALUES($2, new_record_id, $3, $4);
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_data
表的预期结果:
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_data
表的预期结果:
request_id | request_timestamp | data_id | record_count | completed_status
------------+--------------------------+---------+--------------+-------------------
1 | 2017-09-29 | 1 | 3 | true
答案 0 :(得分:0)
@Fahad Anjum指出了插入json的更好方法。我将INSERT
语句更改为INSERT INTO my_data (data_fields) values($1) RETURNING data_id INTO new_record_id;
,它为我提供了我需要的结果。
答案 1 :(得分:0)
@Fahad指出了主要的逻辑错误。
但是你不需要 中的强制转换,因为输入参数已经输入($1::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 ($1) -- no need to cast
RETURNING data_id
)
INSERT INTO request_data(request_timestamp, data_id, record_count, completed_status)
SELECT $2, i.data_id, $3, $4
FROM ins1 i
RETURNING data_id
$func$ LANGUAGE sql;
我还统一了小写拼写。您有多种命名惯例,导致completedStatus
和completed_status
不匹配。我的常设建议是避免在Postgres中使用标识符的混合大小写拼写。
相关: