PostgresQL:插入键值而不是两个列表
Posted
技术标签:
【中文标题】PostgresQL:插入键值而不是两个列表【英文标题】:PostgresQL: Insert with key-value instead of two lists 【发布时间】:2016-02-19 01:12:47 【问题描述】:PostgresQL 允许您插入两个列表,一个是字段名称,另一个是值。
INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', 9.99);
对于长列表,很难确定您所在的列表索引。有没有办法通过在值旁边指定列名来插入,即键值对?注意:这与hstore
不同。
即。
INSERT INTO products (product_no => 1, name => 'Cheese', price => 9.99);
【问题讨论】:
【参考方案1】:常规的 DML 是不可能的。
作为替代方案:
使用值列表使 DML 更短:
INSERT INTO products (product_no, name, price) VALUES
(1, 'Cheese', 9.99),
(2, 'Sausages', 9.99),
...;
或者创建可以通过指定参数执行的函数:
create or replace function insert_product(
in product_no products.product_no%type,
in name products.name%type,
in price products.price%type) returns products.product_no%type as $$
insert into products(product_no, name, price) values (product_no, name, price) returning product_no;
$$ language sql;
select insert_product(1, 'Mashrooms', 1.99); -- Parameters by order
select insert_product(product_no := 2, name := 'Cheese', price := 9.99); -- Parameters by name
select insert_product(product_no := 3, price := 19.99, name := 'Sosages'); -- Order does mot matter
【讨论】:
【参考方案2】:我创建了一个供我使用。下面以json作为输入并创建动态SQL查询并执行。
示例用法
create table employee(name character varying(20), address character varying(100), basic integer);
--sample call-1
call insert_into(true, 'employee', '
"name" : "''Ravi Kumar''",
"address" : "''#1, 2nd Cross, Bangalore''",
"basic" : 35000
',
'');
--sample call-2
call insert_into(true, 'employee', '
"name" : "eo.name",
"address" : "eo.address",
"basic" : "eo.basic"
',
'
from employee_old eo
');
程序
CREATE or REPLACE PROCEDURE insert_into(
debug BOOLEAN,
tableName TEXT,
jsonTxt json,
fromWhere TEXT
)
LANGUAGE plpgsql
as $$
DECLARE
field TEXT;
fieldQuery TEXT;
valueQuery TEXT;
finalQuery TEXT;
noOfRecords INT;
BEGIN
IF debug THEN
raise notice 'preparing insert query';
END IF;
fieldQuery := CONCAT('INSERT INTO ', tableName, '(', E'\n');
valueQuery := CONCAT('SELECT ', E'\n');
FOR field IN SELECT * FROM json_object_keys(jsonTxt)
LOOP
fieldQuery := CONCAT(fieldQuery, field, E',\n');
valueQuery := CONCAT(valueQuery, json_extract_path_text(jsonTxt, field), E',\n');
END LOOP;
fieldQuery := RTRIM(fieldQuery, E',\n');
fieldQuery := CONCAT(fieldQuery, ')');
valueQuery := RTRIM(valueQuery, E',\n');
finalQuery := CONCAT(fieldQuery, E'\n', valueQuery, E'\n', fromWhere, ';');
IF debug THEN
RAISE NOTICE 'query:: %', finalQuery;
END IF;
EXECUTE finalQuery;
get diagnostics noOfRecords = row_count;
RAISE NOTICE 'Inserted:: %', noOfRecords;
END
$$;
【讨论】:
以上是关于PostgresQL:插入键值而不是两个列表的主要内容,如果未能解决你的问题,请参考以下文章
Oracle Apex 5.1:基于 LOV(值列表)的报告列显示返回值而不是显示值