我有plpgsql函数:
CREATE OR REPLACE FUNCTION test() RETURNS VOID AS
$$
DECLARE
my_row my_table%ROWTYPE;
BEGIN
SELECT * INTO my_row FROM my_table WHERE id='1';
my_row.date := now();
END;
$$ LANGUAGE plpgsql;
我想知道是否可以直接更新my_row
记录。
我现在发现的唯一方法是:
UPDATE my_table SET date=now() WHERE id='1';
请注意,这只是一个示例函数,真正的函数远比这复杂。
我正在使用PostgreSQL 9.2。
更新:
对于这种困惑感到抱歉,我想说的是:
SELECT * INTO my_row FROM my_table INTO my_row WHERE id='1';
make_lots_of_complicated_modifications_to(my_row, other_complex_parameters);
UPDATE my_row;
即。使用我的_ row
来保存基础表中的信息。我有很多参数需要更新。
答案 0 :(得分:4)
我想知道是否可以直接更新“my_row” 记录。
是的 您可以在plpgsql中更新行或记录类型的列 - 就像您拥有它一样。它应该工作,显然?
这会更新基础表,当然不是变量!
UPDATE my_table SET date=now() WHERE id='1';
你在这里混淆了两件事......
我不认为PostgreSQL中的语法可以UPDATE
整行。不过你可以UPDATE
a column list。考虑一下这个演示:
请注意我使用thedate
代替date
作为列名,date
在每个SQL标准中都是reserved word,在PostgreSQL中是类型名称。
CREATE TEMP TABLE my_table (id serial, thedate date);
INSERT INTO my_table(thedate) VALUES (now());
CREATE OR REPLACE FUNCTION test_up()
RETURNS void LANGUAGE plpgsql AS
$func$
DECLARE
_r my_table;
BEGIN
SELECT * INTO _r FROM my_table WHERE id = 1;
_r.thedate := now()::date + 5 ;
UPDATE my_table t
-- explicit list of columns to be to updated
SET (id, thedate) = (_r.id, _r.thedate)
WHERE t.id = 1;
END
$func$;
SELECT test_up();
SELECT * FROM my_table;
但是,您可以轻松地 INSERT
a whole row 。只是不提供表的列列表(通常应该这样,但在这种情况下,它完全没问题,而不是)。
由于UPDATE
内部是DELETE
,后跟INSERT
,并且函数会自动封装事务中的所有内容,我看不出,为什么你不能使用相反:
CREATE OR REPLACE FUNCTION x.test_ delins()
RETURNS void LANGUAGE plpgsql AS
$func$
DECLARE
_r my_table;
BEGIN
SELECT * INTO _r
FROM my_table WHERE id = 1;
_r.thedate := now()::date + 10;
DELETE FROM my_table t WHERE t.id = 1;
INSERT INTO my_table SELECT _r.*;
END
$func$;
答案 1 :(得分:0)
是的,它可以更新/附加行型变量
CREATE OR REPLACE FUNCTION test() RETURNS VOID AS $$
DECLARE
my_row my_table%ROWTYPE;
BEGIN
SELECT * INTO my_row FROM my_table WHERE id='1';
my_row.date := now();
raise notice 'date : %; ',my_row.date;
END;
$$ LANGUAGE plpgsql;
此处加注通知仅显示今天的日期。
但这不会更新my_table中的列日期。
答案 2 :(得分:0)
我设法通过两行代码使它在PLPGSQL中工作。
给定一个名为table
的模式中名为example
的表以及一个声明为_record
的相同类型的记录,您可以更新表中的所有列以匹配该记录使用以下技巧:
declare _record example.table;
...
-- get the columns in the correct order, as a string
select string_agg(format('%I', column_name), ',' order by ordinal_position)
into _columns
from information_schema.columns
where table_schema='example' and table_name='table';
execute 'update example.table set (' || _columns || ') = row($1.*) where pkey=$2'
using _record, _record.pkey;
在上面的示例中,当然,_record.pkey
是表的主键。