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 …" 🙂