Insert v PostgreSQL 7.1.3

Radek Kanovsky rk na dat.cz
Středa Únor 6 11:04:04 CET 2002


On Wed, Feb 06, 2002 at 10:36:29AM +0100, Karel Zak wrote:

>  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)

Takto to ale nikdo nenavrhoval.

>  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. 

Proc je to na nic? Tento zpusob mne prijde prave jediny spravny ze zde
uvedenych. Radeji to tady zopakuju:

 SELECT nextval('xxx_id_seq');
 nextval
 --------
       7
 INSERT INTO xxx (id, data) VALUES (7, 'aaa');

Nextval vrati vzdy jedinecne seriove cislo, proto ten INSERT
nemusi byt ani v zadne transakci a bude to fungovat vzdy.

> 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)

Toto neni funkcni protoze mezi INSERT a SELECT muze byt INSERT od
dalsiho klienta, ktery sekvenci inkrementuje.

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

Proto nefunguje vas posledni priklad uplne vzdy.

Zdravi

Radek Kaňovský


Další informace o konferenci Test