Postgresql

無論如何更新具有復合類型記錄/行的行上的一系列列?

  • September 16, 2017

拿一張桌子foo

CREATE TABLE foo(a,b,c,d)
AS VALUES
 (1,2,3,4);

foo我可以使用行類型插入..

INSERT INTO foo
 SELECT (foo).*
 FROM foo;

INSERT INTO foo
 SELECT (v).*
 FROM ( VALUES (42,42,42,42) )
   AS v;

但我不能用行類型更新 foo 。

-- fails
UPDATE foo SET (a,b,c,d) = (
 SELECT ROW(1,2,3,4)
).*;

-- also fails.
UPDATE foo SET (a,b,c,d) = (SELECT (1,2,3,4));
ERROR:  number of columns does not match number of values
LINE 1: UPDATE foo SET (a,b,c,d) = (SELECT (1,2,3,4));

是否有任何語法可以使用複合類型更新整行。真正奇怪的是,這可以在帶有 的觸發器中使用NEW,而我正在嘗試編寫沒有觸發器的相同程式碼。

CREATE OR REPLACE FUNCTION foo()
RETURNS trigger
AS $$
 BEGIN
   NEW=(42,42,42,42);
   RETURN NEW;
 END;
$$ LANGUAGE plpgsql
IMMUTABLE;

CREATE TRIGGER ok
 BEFORE UPDATE ON foo
 FOR EACH ROW
 EXECUTE PROCEDURE foo();

-- The NEW row in trigger gets updated with (42,42,42,42)
-- the UPDATE succeeds; all rows (42,42,42,42)
UPDATE foo
 SET (a,b,c,d) = (1,2,3,4);

你可以在這裡看到我們可以更新過程中的行對象,並更改更新。但是,我們不能在UPDATEddl 中這樣做嗎?我希望由同名表生成的 RECORD 以相同的方式工作。

-- Such as this,
UPDATE foo
 SET foo = (1,2,3,4);

其實有很多關於這個的文章。。

但是,根據/u/pstef,其中一個已送出,並且此語法現在適用於 HEAD,儘管 @ypercubeᵀᴹ 報告它不適用於 9.6.5

UPDATE foo SET (a,b,c,d) = ROW(10,9,8,7);

文件對此並沒有多說

根據標準,帶括號的目標列名稱子列表的源值可以是產生正確列數的任何行值表達式。**PostgreSQL 只允許源值是行建構子或子 SELECT。**單個列的更新值可以在行建構子的情況下指定為 DEFAULT,但不能在子 SELECT 中指定。

但您也可以在UPDATE 的語法中看到

  ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |

怎麼樣(伺服器 9.5.7)…

create table foo(a,b,c,d)
as values
 (1,2,3,4)
, (4,5,6,7)
, (8,9,0,null);

postgres=# select * from foo;
a | b | c | d 
---+---+---+---
1 | 2 | 3 | 4
4 | 5 | 6 | 7
8 | 9 | 0 |  
(3 rows)


update foo
set (a,b,c,d) = ( 
 select (v).*
 from ( values (42,42,42,42) ) as v 
) ;

postgres=# select * from foo;
a  | b  | c  | d  
----+----+----+----
42 | 42 | 42 | 42
42 | 42 | 42 | 42
42 | 42 | 42 | 42
(3 rows)

Dbfiddle在這裡

或者,確實(沒有觸發器):

postgres=# update foo
postgres-# set (a,b,c,d) = (11,22,33,44) ;
UPDATE 3
postgres=# select * from foo;
a  | b  | c  | d  
----+----+----+----
11 | 22 | 33 | 44
11 | 22 | 33 | 44
11 | 22 | 33 | 44
(3 rows)

引用自:https://dba.stackexchange.com/questions/186081