Insert v PostgreSQL 7.1.3

Karel Zak zakkr na zf.jcu.cz
Středa Únor 6 10:36:29 CET 2002


On Wed, Feb 06, 2002 at 10:07:48AM +0100, Radek Kanovsky wrote:
> On Wed, Feb 06, 2002 at 09:57:05AM +0100, Karel Zak wrote:

 Ja se tak snadno nedam :-)

> Podle me ten prvni zpusob bude efektivnejsi (a mozna i prenositelnejsi,
> ale to malokoho zajima :-), protoze ten prvni SELECT CURVAL... se musi
 
 Prvne neni select jako select. Pokud INSERT vnitrne vola nextval()
 tak je to rychlostne o necem jinem nez pokud to udela user pomoci SQL
 dotazu, ktery se musi parsovat apod.

 A hlavne ten napad neni funkcni, alespon tak jak byl navrzen (v 7.2):

test=# CREATE TABLE xxx (id serial, data text);
NOTICE:  CREATE TABLE will create implicit sequence 'xxx_id_seq' for SERIAL column 'xxx.id'
NOTICE:  CREATE TABLE / UNIQUE will create implicit index 'xxx_id_key' for table 'xxx'
CREATE

 ...ok, mame tabulku a udelala se sequence 'xxx_id_seq':

test=# SELECT currval('xxx_id_seq');
ERROR:  xxx_id_seq.currval is not yet defined in this session


 Problem je, ze nejdrive se musi udelat nextval('xxx_id_seq'), ktery
"zamluvi" dane ID pro danou session.

 Spravne tedy je: 

test=# SELECT nextval('xxx_id_seq');
 nextval
---------
       1
(1 row)

 Ovsem pokud ted provedu INSERT tak se vnitrne zavola znova nextval()
a ID bude '2' (nemluve o tom, ze i jiny prave pripojney klient muze 
zavolat nextval() a zvysit tak dane cislo).

test=# INSERT INTO xxx (data) VALUES ('aaa');
INSERT 45412 1
test=# SELECT * FROM xxx;
 id | data
----+------
  2 | aaa
(1 row)


 Reseni by tedy bylo pouzivat rovnou INSERT a sam si tam dosadit hodnotu 
zjistenou od predesleho SELECT. Tedy:

 INSERT INTO xxx (id, data) VALUES (....)

 Coz mi prijde ponekud nanic. 


Funkcni modifikace toho napadu je udelat INSERT a pak az nasledne 
SELECT currval():

test=# INSERT INTO xxx (data) VALUES ('one');
INSERT 45419 1
test=# SELECT currval('xxx_id_seq');
 currval
---------
      11
(1 row)

test=# SELECT * FROM xxx;
 id | data
----+------
 11 | one
(1 row)


 Coz by mozna mohlo byt i rychlejsi nez mnou navrhovane reseni, 
protoze tabulka s hodnotami sequence je asi vzdy mensi sousto 
nez tabulka s daty se kterou pracuje INSERT.


 BTW, je vhodne si taktez uvedomit, ze sequence jsou mimo transakce.

        Karel

-- 
 Karel Zak  <zakkr na zf.jcu.cz>
 http://home.zf.jcu.cz/~zakkr/
 
 C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz


Další informace o konferenci Databases