Postgresql 更新PL/pgSQL中的整行

Postgresql 更新PL/pgSQL中的整行,postgresql,sql-update,plpgsql,Postgresql,Sql Update,Plpgsql,我有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记录 我现在找到的唯一方法是: U

我有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;
即,使用我的行将信息持久保存在基础表中。我有很多参数要更新

我想知道是否可以直接更新“我的行” 记录

是的。
您可以在plpgsql中更新行或记录类型的列—就像您拥有它一样。很明显,它应该是有效的

当然,这将更新基础表,而不是变量

UPDATE my_table SET date=now() WHERE id='1';
你在这里混淆了两件事


对评论中澄清的答复 我认为PostgreSQL中没有语法可以更新整行。不过你可以。考虑这个演示:

请注意,我如何使用日期而不是日期作为列名,
date
是每个SQL标准中的一个名称,也是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;

是的,可以更新/追加行类型变量

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_表中的列日期

我用几行代码在PLPGSQL中实现了这一点

给定名为
示例
的架构中名为
的表,以及声明为
\u 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;

当然,在上面的示例中,
\u record.pkey
是表的主键。

为什么不首先选择NOW(),而不是模糊*?是否要更新plpgsql函数中的变量或基础表中的行?我想将变量保留到表中,而不必重写逐字段查询。如何直接保留ROWTYPE变量?是要更新整行还是只更新一列?整行,我用复杂的计算改变了很多领域。这有点像甲骨文的设定行。欧文。。。delete/insert方法的问题似乎是外键的问题。您将如何解决这些问题?@DavidS:指向表的外键将禁止删除/插入解决方案。您可以使用动态SQL从系统目录中为
UPDATE
生成一长串列,尤其是…我知道,日期就是一个例子,我正在对我的_行进行大量更改,我希望有一种简单的方法来再次保存信息,而不必编写更新我的表集,其中id=my_row.id。我认为Oracle有一个固定的行系统来使用这些结构保存记录。
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;