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