Newsgroup: it.comp.lang.delphi
Titolo: SQL e campo progressivo

Ciao a tutti!
Ho un DB con due campi: Prefisso, Codice. La chiave è
(Prefisso,Codice). Quando devo creare un nuovo record vorrei che Codice
fosse progressivo. Ho provato ad estrarre il codice più grande nel
seguente modo:
String str="SELECT MAX(Codice) FROM clifor WHERE
Prefisso='"+DBComboBoxPref->Text+"'";
KADaoTable1->Close();
KADaoTable1->SQL->Clear();
KADaoTable1->SQL->Add(str);
KADaoTable1->Open();
int codice = KADaoTable1->Fields->Fields[0]->AsInteger;
ma viene visualizzato un messaggio di errore perchè l'SQL ritorna solo
il campo MAX(Codice) mentre all'applicazione serve sempre avere
Precodice e Codice.
Qualcuno ha un'idea su come poter risolvere?
Grazie mille!

Dimenticavo di dire che il DB è Access...

fosse progressivo.
E' un approccio sbagliato.  O usi un contatore (identificatore
progressivo da 1 a infinito), oppure una chiave composta.
NON tutte e due.
Scegli.

Secondo me l'approccio non è sbagliato, infatti la chiave primaria
altro non è che un identificatore per identificare univocamente un
record, quindi credo sia perfettamente lecito e conveniente porre la
chiave (Prefisso,Codice). Una query che risolverebbe ogni problema
sarebbe questa: Select Prefisso,Codice From Clifor Where Codice=(Select
Max(Codice) From Clifor)
Purtroppo una query di questo tipo non sono riuscito ad eseguirla,
forse a causa di Access forse a causa di limiti nei components...
Quindi, siccome non posso eseguire la suddetta query, qualcuno avrebbe
in mente una valida alternativa?
Ne sarei molto grato! Grazie mille!

record, 
Il fatto che un approccio sia sbagliato non implica necessariamente
che stia negando un principio come quello dell'unicitą chiave
primaria.  Il modo in cui si sceglie una chiave primaria puņ essere
importante.  La chiave (Prefisso, Codice) puņ essere perfettamente
lecito (e questo nessuno lo nega), ma non č affatto conveniente
rendere Codice un campo progressivo.  Una chiave come quella mi lascia
invece supporre che Codice venga fornito esplicitamente.  Se vuoi
selezionare il nuovo numero per il campo Codice, devi fare prima una
select max + 1 con una where sul prefisso e poi inserire il nuovo
record.  Questo ti sottopone al rischio (che devi gestire) di due
utenti che selezionino la stessa chiave per il nuovo record.
Tutto questo giro č bypassabile utilizzando un semplice contatore.

Capisco che tutto questo si eviterebbe con un contatore, ma spiego
perchè avevo fatto questa scelta. Se Codice è un campo contatore non
c'è la possibilità di variarne il valore, mentre se non è un
contatore l'utente può scegliere se accettare la numerazione
automatica fornita da max()+1, oppure digitarlo.
Valutando i pro ed i contro credo comunque anche io che sia meglio
utilizzare un contatore in questo caso.
Però potrei incontrare in futuro una situazione analoga per la quale
non mi conviene il contatore, in questo caso come posso fare visto che
non posso eseguire una query innestata come la suddetta? Come potrei
fare dunque per calcolare il max()+1 senza ottenere errori? L'errore
credo sia dovuto al fatto che la query non innestata restituisce un
solo campo, e non entrambi Prefisso e Codice...

automatica fornita da max()+1, oppure digitarlo.
Io, nelle tabelle, uso sempre la segente semplice soluzione (che credo sia 
quello che vorresti fare tu):
 ho un campo 'id' di tipo contatore che si autoincrementa e mi garantisce 
l'univocità del record nella tabella e che non è editabile dall'utente; poi 
uso anche un campo 'codice' di tipo stringa che imposto con il valore del 
campo id, all'inserimento del record, e che l'utente è libero di accettare o 
modificare a suo piacimento.
Naturalmente nelle relazioni master-detail etc. uso sempre il campo id 
perchè non ci si deve mai fidare dei codici che può digitare l'utente.
Saluti, Giuseppe 

Grazie Giuseppe!
Credo che questa sia la migliore soluzione