概述
数据表更新时,如果需要对修改前后的数据进行记录或比较,需要返回更新前后的数据。KingbaseES 可以通过 UPDATE语句是否能直接返回影响的数据。
KingbaseES支持insert,delete,update的returning。
- insert returning 返回的是新插入的值。
- delete returning 返回的是被删除的值。
- update returning 返回的是更新后的值,不能返回更新前的值。
RETURNING语法:
RETURNING * | output_expression [ [ AS ] output_name ] [, ...]
RETURNING用法
INSERT
在INSERT
中,可用于RETURNING
的数据是插入的行。 这在琐碎的插入中并不是很有用,因为它只会重复客户端提供的数据。 但依赖于计算出的默认值时可以非常方便。例如,当使用 serial
列来提供唯一标识符时, RETURNING
可以返回分配给新行的ID:
CREATE TABLE users (firstname text, lastname text, id serial primary key);
INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;
除了返回特定的列外,也可以 returning rowid ,或者 returning ctid
UPDATE
在UPDATE
中,可用于RETURNING
的数据是被修改行的新内容。 例如:
UPDATE users SET firstname = 'Joe1'
WHERE firstname = 'Joe'
RETURNING firstname;
DELETE
在DELETE
中,可用于RETURNING
的数据是删除行的内容。例如:
DELETE FROM users
WHERE lastname = 'Cool'
RETURNING *;
UPDATE 如何返回更新前的值
在DML触发器中,可以使用 RECORD类型NEW,存储INSERT或UPDATE操作产生的新的数据行,RECORD类型OLD 存储被UPDATE或DELETE操作修改或删除的旧的数据行。
为了 UPDATE RETURNING 返回 NEW 数据,同时返回OLD数据,可以使用关联OLD表,同时返回旧数据。
UPDATE users NEW SET firstname = OLD.firstname||'_A'
from users OLD
where OLD.ctid = NEW.ctid
RETURNING NEW.firstname firstname_new, OLD.firstname firstname_old;
QUERY PLAN
-------------------------------------------------------------------------------
Update on users new (cost=28.90..60.95 rows=840 width=112)
-> Hash Join (cost=28.90..60.95 rows=840 width=112)
Hash Cond: (new.ctid = old.ctid)
-> Seq Scan on users new (cost=0.00..18.40 rows=840 width=42)
-> Hash (cost=18.40..18.40 rows=840 width=38)
-> Seq Scan on users old (cost=0.00..18.40 rows=840 width=38)
需要返回更新前的数据,添加了OLD表,所以COST增加了一次Seq Scan成本。