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