"INSERT has more target columns than expressions" 在 PL/pgSQL 函数中
"INSERT has more target columns than expressions" in PL/pgSQL function
我正在创建一个函数并将其与长生不老药一起使用。我正在执行该函数并将其解析为下面的 JSON 有效负载:
有效负载包含 table 的键值对,函数应该插入一条记录,稍后我想重构以首先通过 ID 获取 table,然后使用格式化插入语句我在表格 table.
中得到的模式
这是我正在执行的函数:
CREATE OR REPLACE FUNCTION create_record(data json) returns text
language plpgsql
as
$$
declare
table_id uuid := gen_random_uuid();
id uuid := gen_random_uuid()::uuid;
inserted_at timestamp := NOW()::timestamp(0);
updated_at timestamp := NOW()::timestamp(0);
columns text;
values text;
j jsonb;
v text;
statement text;
n integer := 0;
length integer := json_array_length(data -> 'schema');
begin
for j in (select json_array_elements(data -> 'schema')::jsonb) loop
if n < length - 1 then
columns := concat(columns, j ->> 'key', ',',' ');
values := concat(values, j ->> 'value', ',',' ');
else
columns := concat(columns, j ->> 'key');
values := concat(values, j ->> 'value');
end if;
n := n + 1;
end loop;
columns :=concat('id',',',' ','inserted_at',',', ' ', 'updated_at', ',', ' ', columns);
values :=concat(id,',',' ',inserted_at,',', ' ', updated_at, ',', ' ', values);
RAISE NOTICE 'cols: (%)', columns;
RAISE NOTICE 'vals: (%)', values;
statement := format('INSERT INTO %I (%s) VALUES (%L) RETURNING id;', data ->> 'name', columns, values);
execute (statement);
exception
when others then
return format('{"error": "%L"}', SQLERRM);
end
$$;
这是我要发送的负载:
{
"action": "create",
"body": {
"id": "2ed27f13-62d1-48dc-bbd3-0a031fe2712e",
"name": "test1",
"parent": "base",
"schema": [
{
"key": "hello",
"value": "some"
},
{
"key": "world",
"value": "some"
},
{
"key": "test",
"value": "some"
}
]
}
}
这是我收到的错误:
%Postgrex.Result{
columns: ["create_record"],
command: :select,
connection_id: 1718,
messages: [
%{
code: "00000",
file: "pl_exec.c",
line: "3859",
message: "vals: (62d2364b-9add-4c85-b964-45d6b86d7db7, 2022-01-30 20:45:53, 2022-01-30 20:45:53, some, some, some)",
routine: "exec_stmt_raise",
severity: "NOTICE",
unknown: "NOTICE",
where: "PL/pgSQL function create_record(json) line 28 at RAISE"
},
%{
code: "00000",
file: "pl_exec.c",
line: "3859",
message: "cols: (id, inserted_at, updated_at, hello, world, test)",
routine: "exec_stmt_raise",
severity: "NOTICE",
unknown: "NOTICE",
where: "PL/pgSQL function create_record(json) line 27 at RAISE"
}
],
num_rows: 1,
rows: [
["{\"error\": \"'INSERT has more target columns than expressions'\"}"]
]
}}
令我感到困惑的是,列数似乎与值完全相同,但是,我似乎遇到了这个错误 INSERT has more target columns than expressions
。
就像@lukStorms 在上面所说的那样,值需要文字字符串我用 quote_literal(j ->> 'value') 解决了我从中提取的 json 值的问题jsonb
我正在创建一个函数并将其与长生不老药一起使用。我正在执行该函数并将其解析为下面的 JSON 有效负载:
有效负载包含 table 的键值对,函数应该插入一条记录,稍后我想重构以首先通过 ID 获取 table,然后使用格式化插入语句我在表格 table.
中得到的模式这是我正在执行的函数:
CREATE OR REPLACE FUNCTION create_record(data json) returns text
language plpgsql
as
$$
declare
table_id uuid := gen_random_uuid();
id uuid := gen_random_uuid()::uuid;
inserted_at timestamp := NOW()::timestamp(0);
updated_at timestamp := NOW()::timestamp(0);
columns text;
values text;
j jsonb;
v text;
statement text;
n integer := 0;
length integer := json_array_length(data -> 'schema');
begin
for j in (select json_array_elements(data -> 'schema')::jsonb) loop
if n < length - 1 then
columns := concat(columns, j ->> 'key', ',',' ');
values := concat(values, j ->> 'value', ',',' ');
else
columns := concat(columns, j ->> 'key');
values := concat(values, j ->> 'value');
end if;
n := n + 1;
end loop;
columns :=concat('id',',',' ','inserted_at',',', ' ', 'updated_at', ',', ' ', columns);
values :=concat(id,',',' ',inserted_at,',', ' ', updated_at, ',', ' ', values);
RAISE NOTICE 'cols: (%)', columns;
RAISE NOTICE 'vals: (%)', values;
statement := format('INSERT INTO %I (%s) VALUES (%L) RETURNING id;', data ->> 'name', columns, values);
execute (statement);
exception
when others then
return format('{"error": "%L"}', SQLERRM);
end
$$;
这是我要发送的负载:
{
"action": "create",
"body": {
"id": "2ed27f13-62d1-48dc-bbd3-0a031fe2712e",
"name": "test1",
"parent": "base",
"schema": [
{
"key": "hello",
"value": "some"
},
{
"key": "world",
"value": "some"
},
{
"key": "test",
"value": "some"
}
]
}
}
这是我收到的错误:
%Postgrex.Result{
columns: ["create_record"],
command: :select,
connection_id: 1718,
messages: [
%{
code: "00000",
file: "pl_exec.c",
line: "3859",
message: "vals: (62d2364b-9add-4c85-b964-45d6b86d7db7, 2022-01-30 20:45:53, 2022-01-30 20:45:53, some, some, some)",
routine: "exec_stmt_raise",
severity: "NOTICE",
unknown: "NOTICE",
where: "PL/pgSQL function create_record(json) line 28 at RAISE"
},
%{
code: "00000",
file: "pl_exec.c",
line: "3859",
message: "cols: (id, inserted_at, updated_at, hello, world, test)",
routine: "exec_stmt_raise",
severity: "NOTICE",
unknown: "NOTICE",
where: "PL/pgSQL function create_record(json) line 27 at RAISE"
}
],
num_rows: 1,
rows: [
["{\"error\": \"'INSERT has more target columns than expressions'\"}"]
]
}}
令我感到困惑的是,列数似乎与值完全相同,但是,我似乎遇到了这个错误 INSERT has more target columns than expressions
。
就像@lukStorms 在上面所说的那样,值需要文字字符串我用 quote_literal(j ->> 'value') 解决了我从中提取的 json 值的问题jsonb