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