Insert v PostgreSQL 7.1.3
David Zabensky
zabensky na ica.cz
Středa Únor 6 10:47:54 CET 2002
Karel Zak wrote:
> 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
>
>
Vsechno je to samozrejme pravda, ale - tazatel chtel zjistit currval(sekvence) po provedenem
insertu. Tudiz insert uz nextval(sekvence) nastavil (resp. volal).
Priklad p. Kanovskeho by zrejme byl tedy funkcni.:-) Ale tato debata uz je trochu mimo puvodni dotaz...
D.
Další informace o konferenci Databases