我对Postgres SQL非常陌生。我的要求是传递动态数量的columnId,columnValue对并将此组合插入表中(例如:employeeId,employeeName组合)。列表的长度可以是任何值。我正在考虑在代码端构建动态查询,并将其作为字符串传递给函数并执行语句。有没有更好的方法来解决此问题。任何示例或想法将不胜感激。
答案 0 :(得分:2)
如果允许您将该信息作为结构化JSON值传递,这将变得非常容易。 Postgres具有使用功能json_populate_record
样品表:
create table some_table
(
id integer primary key,
some_name text,
some_date date,
some_number integer
);
插入函数:
create function do_insert(p_data text)
returns void
as
$$
insert into some_table (id, some_name, some_date, some_number)
select (json_populate_record(null::some_table, p_data::json)).*;
$$
language sql;
然后您可以使用:
select do_insert('{"id": 42, "some_name": "Arthur"}');
select do_insert('{"id": 1, "some_value": 42}');
请注意,使用此方法将不属于所传递的JSON字符串的列明确设置为NULL
。
如果传递的字符串包含不存在的列名,则将其忽略,因此
select do_insert('{"id": 12, "some_name": "Arthur", "not_there": 123}');
将忽略not_there
“列”。
在线示例:https://rextester.com/JNIBL25827
修改
可以使用类似的方法进行更新:
create function do_update(p_data text)
returns void
as
$$
update some_table
set id = t.id,
some_name = t.some_name,
some_date = t.some_date,
some_number = t.some_number
from json_populate_record(null::some_table, p_data::json) as t;
$$
language sql;
或使用insert on conflict
通过一个功能涵盖两个用例:
create function do_upsert(p_data text)
returns void
as
$$
insert into some_table (id, some_name, some_date, some_number)
select (json_populate_record(null::some_table, p_data::json)).*
on conflict (id) do update
set id = excluded.id,
some_name = excluded.some_name,
some_date = excluded.some_date,
some_number = excluded.some_number
$$
language sql;