nowości w postgresie 8.2 – … returning

dziś pierwszy odcinek o zmianach w postgresie 8.2. tematem odcinka są zapytania “… returning".

do zapytań modyfikujących dane – INSERT INTO, UPDATE, DELETE FROM zostało dodane rozszerzenie “RETURNING".

składnia wygląda następująco:

  • INSERT INTO tabelka (pola) VALUES (costam) RETURNING wyrażenie;
  • UPDATE tabelka SET pole = X WHERE cośtam RETURNING wyrażenie;
  • DELETE FROM tabelka WHERE cośtam RETURNING wyrażenie;

przykłady użycia dla INSERT:

# CREATE TABLE x (id serial PRIMARY KEY, ble INT4);
NOTICE:  CREATE TABLE will create implicit sequence "x_id_seq" for serial column "x.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "x_pkey" for table "x"
CREATE TABLE
# insert into x (ble) values ('123') returning id;
id
----
1
(1 row)
INSERT 0 1
# insert into x (ble) values ('123') returning id, ble + 123;
id | ?column?
----+----------
2 |      246
(1 row)
INSERT 0 1
# insert into x (ble) values ('123') returning *;
id | ble
----+-----
3 | 123
(1 row)
INSERT 0 1
# insert into x (ble) values ('123') returning *, now(), (select count(*) from pg_class);
id | ble |              now              | ?column?
----+-----+-------------------------------+----------
4 | 123 | 2006-12-07 22:52:24.573777+01 |      209
(1 row)
INSERT 0 1
# select * from x;
id | ble
----+-----
1 | 123
2 | 123
3 | 123
4 | 123
(4 rows)
# insert into x (ble) select ble + 2 from x returning *;
id | ble
----+-----
5 | 125
6 | 125
7 | 125
8 | 125
(4 rows)
INSERT 0 4

miłe, czyż nie? głównym celem jest możliwość automatycznego pobierania wartości typu id – nadawanych z sekwencji. ale zadziała to także zwracając dane modyfikowane przez triggery.

to co jest po “RETURNING" musi być zgodne formatowo z tym co jest w standardowym select'cie między SELECT a FROM.

przykłady użycia dla UPDATE:

# update x set ble = ble * 2 where id % 2 = 0 returning *;
id | ble
----+-----
2 | 246
4 | 246
6 | 250
8 | 250
(4 rows)
UPDATE 4

zwracam uwagę na to, że returning zwraca nowe wartości! czyli tak po triggerowemu mówiąc: retyrning * oznacza return NEW; a nie return OLD;!

przykłady użycia dla DELETE:

# delete from x where id % 2 = 1 returning *;
id | ble
----+-----
1 | 123
3 | 123
5 | 125
7 | 125
(4 rows)
DELETE 4

jak widać składnia wszędzie jest podobna, miła łatwa i prosta. a do tego niesie sporo ułatwień. mnie osobiście cieszy INSERT … returning id; bo załatwia mi w piękny sposób odpowiadanie ludziom pytającym o id, i reagującym nerwowo na sugestie: select currval() : “ale czy jak dwa połączenia wstawią rekordy …" 🙂