5

我有 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;

即使用 my_row将信息持久保存在基础表中。我有很多参数要更新。

4

4 回答 4

7

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

这是。
您可以在 plpgsql 中更新行或记录类型的列 - 就像您拥有它一样。它应该工作,显然?

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

UPDATE my_table SET date=now() WHERE id='1';

你在这里混淆了两件事......


在评论中回答澄清

我认为 PostgreSQL 中没有可以UPDATE整行的语法。不过,您可以UPDATE列 list。考虑这个演示:

请注意我如何使用thedate而不是date列名,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;

但是,您可以轻松地INSERT整行。只是不要为表格提供列列表(您通常应该这样做,但在这种情况下完全可以,不要这样做)。

因为 anUPDATE在内部是 aDELETE后面跟着 an 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$;
于 2012-09-21T11:18:02.117 回答
3

我设法在几行代码中让这个在 PLPGSQL 中工作。

给定一个在名为table的模式中调用的表example,以及声明为 的同一类型的记录_record,您可以使用以下 hack 更新表中的所有列以匹配记录:

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是表的主键。

于 2020-04-10T14:40:06.413 回答
1

Postgresql 没有在更新中设置行。如果您不更新整行,则应分别为每列分配值

于 2021-12-05T16:23:08.377 回答
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 中的列日期。

于 2012-09-21T11:20:20.650 回答