我创建了一个函数result1 = {{"B",1,2,3,4}};
result2 = {{"D",1,2,3,4}};
resultEdit1 = {{"C",1,2,3,4}};
,它复制表中的记录并为它们提供新的主键值。它返回一个包含old_id =>对的hstore; NEW_ID。例如,对于表copy_rows_from_table(_tbl regclass)
,我的函数将创建两个额外的记录并返回一个hstore。
books
:
books
评估 id | title | price | author_id | publisher_id
----+---------------+-------+-----------+--------------
1 | The Cyberiad | 15.00 | 23 | 46
2 | The Trial | 10.00 | 12 | 67
后 books
:
copy_rows_from_table('books')
返回hstore:
id | title | price | author_id | publisher_id
----+---------------+-------+-----------+--------------
1 | The Cyberiad | 15.00 | 23 | 46
2 | The Trial | 10.00 | 12 | 67
3 | The Cyberiad | 15.00 | 23 | 46
4 | The Trial | 10.00 | 12 | 67
工作正常。现在我想创建一个函数来复制几个表中的记录(在数组中传递),然后使用返回的hstore更新所有外键。例如,在复制"1"=>"3", "2"=>"4"
和books
之后,我希望在authors
表中更新author_id
列。在books
,books
和authors
上使用我的函数后,如果我有一个包含publishers
的hstore,我的函数应该以这种方式更新"1"=>"3", "2"=>"4","23"=>"167","12"=>"98","46"=>"87","67"=>"102"
表:
books
我想出了类似的东西:
id | title | price | author_id | publisher_id
----+---------------+-------+-----------+--------------
1 | The Cyberiad | 15.00 | 23 | 46
2 | The Trial | 10.00 | 12 | 67
3 | The Cyberiad | 15.00 | 167 | 87
4 | The Trial | 10.00 | 98 | 102
但它不太有用。是否有可能以我解释的方式更新记录?
答案 0 :(得分:1)
我终于找到了在PLpgSQL中实现它的方法。我只是遍历每个记录的每一列。这是我的工作职能:
CREATE OR REPLACE FUNCTION copy_tables(_tbls regclass[])
RETURNS void AS
$func$
DECLARE
_id_pairs hstore;
_table_id_pairs hstore;
_row record;
_hs_row record;
BEGIN
FOR I IN array_lower(_tbls, 1)..array_upper(_tbls, 1)
LOOP
EXECUTE format('SELECT copy_rows_from_table(''%1$s'')', _tbls[I])
INTO _table_id_pairs;
SELECT COALESCE(_id_pairs, hstore('')) || COALESCE(_table_id_pairs, hstore('')) INTO _id_pairs;
END LOOP;
FOR I IN array_lower(_tbls, 1)..array_upper(_tbls, 1)
LOOP
FOR _row IN EXECUTE format('SELECT * FROM %1$s WHERE id = ANY(''%2$s''::uuid[])', _tbls[I], avals(_id_pairs))
LOOP
FOR _hs_row IN SELECT kv."key", kv."value" FROM each(hstore(_row)) kv
LOOP
IF _hs_row."value" = ANY(akeys(_id_pairs)) THEN
EXECUTE format('UPDATE %1$s SET %2$s = ''%3$s'' WHERE id = ''%4$s''',
_tbls[I], _hs_row."key", _id_pairs -> _hs_row."value", _row.id);
END IF;
END LOOP;
END LOOP;
END LOOP;
END
$func$
LANGUAGE plpgsql;
答案 1 :(得分:0)
PLpgSQL不是动态更新的好工具。可能还有其他一些可能性,但没有人是微不足道的。其他方式:
record_get_fields
和record_set_fields