Newsgroup: it.comp.www.php
Titolo: [OT] Problema Postgres

So di essere un tantino OT, ma visto che in questo NG molti sono degli
esperti di database pongo qui la domanda.
Sto lavorando su un database Postgres (6.5.3 su Debian) e mi succede
una cosa a mio parere strana lavorando con valori numerici in serie.
Mi spiego:
$ createdb miodatabase
psql miodatabase
=> create sequence id;
CREATE
=> create table miatabella (numero int4, nome text UNIQUE);
NOTICE:  CREATE TABLE/UNIQUE will create implicit index 'miatabella_nome_key' for table 'miatabella'
CREATE
=> insert into miatabella values(NEXTVAL('id'), 'pippo');
=> insert into miatabella values(NEXTVAL('id'), 'pluto');
// E fino a qui tutto bene, se faccio la query:
=> select * from miatabella;
// mi esce:
numero|nome
------+-----
     1|pippo
     2|pluto
// Adesso però faccio un errore: inserisco un altro record con il campo
// "nome" identico ad un altro:
=> insert into miatabella values(NEXTVAL('id'), 'pippo');  [*]
// e giustamente mi viene detto:
ERROR:  Cannot insert a duplicate key into a unique index
=> allora correggo:
insert into miatabella values(NEXTVAL('id'), 'paperino');
// tutto regolarmente accettato da postgres solo che è nato un errore:
// se lancio 
select * from miatabella;
// mi dà:
numero|nome
------+---------
     1|pippo
     2|pluto
     4|paperino
In pratica, manca il numero tre, che è stato assegnato alla query che ho
contrassegnato con [*]. Ma ha senso tutto questo? Sembra che prima venga
'occupato' il numero 3 nella SEQUENCE, e solo dopo venga tentata la
scrittura nella tabella, che riporta esito negativo, quando però ormai
il mio '3' è già andato a farsi benedire!
Prima di urlare al baco chiedo a qualcuno che conosce questo 'orpelli'
meglio di me: ho tralasciato qualcosa? (sarà sicuramente così!!)
E nel manuale di postgres non ho letto niente a riguardo!
Grazie a tutti e scusate ancora per l'OT! (però il db lo comando via
PHP!!)
Mimmo
-- 
:wq



Hai dimenticato che PRIMA vengono valutati i parametri di INSERT, e solo
dopo viene effettuata la INSERT. Questo vale anche se si usa SET DEFAULT
numero = NEXTVAL('id'), per lo stesso motivo.
Pero', con un costo maggiore, puoi usare
INSERT INTO miatabella ( numero, nome ) 
	SELECT MAX(numero)+1, 'topolino' 
		FROM miatabella;
Per diminuire il costo su tabelle complesse, crea un altro indice
CREATE UNIQUE INDEX miatabella_id ON miatabella('numero');
...tra l'altro puoi evitarti SEQUENCE, a questo punto.
Altro sistema, per inserimenti massicci:
	INSERT INTO miatabella ( numero, nome )
		VALUES ( -1, '...');
	...
	UPDATE miatabella SET numero=NEXTVAL('id')
		WHERE numero=-1;
...questo usando la SEQUENCE e senza UNIQUEness su miatabella_id.
Leonardo
-- 
".signature": bad command or file name

 		WHERE numero=-1;
Questo mi sembra il metodo migliore, sempre che l'abbia capito!
In pratica, inserisco nella tabella un valore numerico di default (-1)
ed il campo "nome" (che poi non è quello visto che ho fatto qui una
semplificazione mostruosa!), di cui viene controllata l'unicità. Se
tutto è a posto, eseguo subito un update che mi mette a posto il campo
numerico semza rischiare di "perdere" numeri, visto che una insert
fallita non porta all'assegnazione del valore numerico tramite la
SEQUENCE.
Giusto? :-)
Solo un dubbio, a questo punto: se la tabella è molto grossa (e lo
sarà!!) e contenente molti dati, non è un'operazione troppo onerosa per
il sistema passarsi in rassegna tutti i campi alla ricerca di un campo
"numero" con valore -1?
Ehm, aggiungo un altro dubbio in append!
Ma se con la procedura di insert/update l'insert mi fallisce, l'update si
incavola o si fa solamente un giro per la tabella alla ricerca di un valore
"-1" e, non trovandolo, si rimette a dormire?
Ciao
M.
-- 
rm -rf 
and be happy

"-1" e, non trovandolo, si rimette a dormire?
La seconda che hai detto... e ci mette anche poco :-)
