Autore Topic: SQLite3: chiave primaria non ordinata  (Letto 1243 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
SQLite3: chiave primaria non ordinata
« il: 08 Giugno 2009, 17:17:16 »
Dopo avere creatop le mie bravetabelle nel DB agganciato al progetto che sto scrivendo, pensavo di poetere caricare e gestire i dati in maniera snella e sicura. Ahimè, mi sbagliavo perché ho cominciato a caricare manualmente alcuni dati per potere provare una parte di codice ed ho riscontrato le seguenti differenze:
Tabella n°1:
la primary key é attribuita ad una colonna definita in fase di creazione come integer. Ho caricato disordinatamente tramite Sqliteman(Knoda) diversi record che dopo il commit mi sono ritrovato perfettamente in ordine ascndente di chiave primaria. Le istruzioni di creazione sono:
 
Codice: [Seleziona]

1.  sql = "CREATE TABLE 'PianCont'  ("                  
2.  sql = sql & " 'NumVoce' INTEGER,"                    
3.  sql = sql & " 'NomeVoce' VARCHAR(50) DEFAULT NULL,"  
4.  sql = sql & " 'DtCarico' INTEGER DEFAULT NULL,"      
5.  sql = sql & " 'NuMovv' INTEGER DEFAULT NULL,"        
6.  sql = sql & " 'AvvScad' CHAR(1) DEFAULT NULL,"      
7.  sql = sql & "  PRIMARY KEY ("                        
8.  sql = sql & " 'NumVoce')"                            
9.  sql = sql & " );"                                        
10.  sqltable = DB_Connection.Exec(sql)

In questo caso la primary key é la colonna "NumVoce"  dichiarata alla riga 2 come INTEGER.

Tabella n°2:
la primary key é attribuita ad una colonna definita in fase di creazione come CHAR(8). Anche in questo caso ho caricato alcuni record in maniera disordinata. Questa volta però, dopo il commit, é stato mantenuto l'ordine di inserimento che, ovviamente, non é quello ascendente di chiave primaria. Riporto le istruzioni di creazionme della tabella:
Codice: [Seleziona]

1. sql = "CREATE TABLE 'RiepMovg'  ("                
2.  sql = sql & " 'DtCoMovg' CHAR(8),"              
3.  sql = sql & " 'StaDtMovg' CHAR(1) DEFAULT NULL,"      
4.  sql = sql & " 'TotEntrg' INTEGER,"                    
5.  sql = sql & " 'TotUscg' INTEGER,"                      
6.  sql = sql & " 'RipFing' INTEGER,"                      
7.  sql = sql & " PRIMARY KEY ('DtCoMovg')"        
8.  sql = sql & " );"                                        
9.  sqltable = DB_Connection.Exec(sql)

La primary key é la colonna "DtCoMovg"  é dichiarata alla riga 2 come CHAR(8).

Tabella n°3:
Questa volta ho definito una chiave "UNIQUE", attribuita all'unica colonna  della tabella, definita in fase di creazione come CHAR(8). Per quest'ultima tabella ho caricato qualche record man manio che andavo avanti con le prove, quindi a maggior raggionme i record sono stati caricati in maniera disordinata. Ad ogni commit dato, l'ordine in cui sono presntati i record é quello di  inserimento. Ecco le istruzioni di creazionme della tabella:
Codice: [Seleziona]

1. sql = "CREATE TABLE 'GGAperte'  ("
2. sql = sql & " 'DtCoGGAp' CHAR(8),"
3. sql = sql & " UNIQUE ('DtCoGGAp')"        
4. sql = sql & " );"                                        
5. sqltable = DB_Connection.Exec(sql)

Dalla riga 2 é visibile che la colonna 'DtCoGGAp', chiave UNIQUE della tabella é definita come CHAR(8) .

E' superfluo dire che, ottenendo un sequenza disordinata di record in tabella, i risultati a cui perviene l'esecuzione del programma sono ingestibili. Ho allora provato ad inserire nella definizione della chiave il parametro ASC che ho interpretato come "ascbnedente", ma ottengo un errore alla
sqltable = DB_Connection.Exec(sql).

Ho riletto la praticissima costruenda guida di fsurfing, ma la casistica affrontata fino ad oggi non comprende un esempio che faccia al caso mio. Che cosa ho sbagliato?
 :uhm:

Ciao
:ciao:

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.482
    • Mostra profilo
Re: SQLite3: chiave primaria non ordinata
« Risposta #1 il: 08 Giugno 2009, 19:55:47 »
io non ho capito cosa volevi ottenere

però inj linea di massima non hai definito nessun campo come primary key

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.482
    • Mostra profilo
Re: SQLite3: chiave primaria non ordinata
« Risposta #2 il: 08 Giugno 2009, 20:04:17 »
se tui puo servire qui trovi la sintassi sql per creare un db con le varie opzioni

http://database.html.it/guide/lezione/1312/creare-il-database/

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: SQLite3: chiave primaria non ordinata
« Risposta #3 il: 08 Giugno 2009, 23:44:25 »
Nei DB la chiave intera è di un tipo particolare, e viene gestita in maniera diversa dalle altre. Può essere anche impostata su AUTOINCREMENT, in modo da far incrementare il numero al DB stesso.

Sugli altri tipi c'è solo il controllo della ripetizione della chiave.
Visita il mio sito personale: http://www.leonardomiliani.com

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SQLite3: chiave primaria non ordinata
« Risposta #4 il: 09 Giugno 2009, 01:13:29 »
Citazione

fsurfing ha scritto:
io non ho capito cosa volevi ottenere


mi dispiace di non essere stato felice nel descrivere quanto ho ottenuto e cosa invece mi aspettavo. Dopo avere letto la guida che mi hai suggerito ho modificato leggermente il mio codice e ripropongo il problema limitando l'esempio di creazione tabella ad una sola delle tabelle incriminate; riduco inoltre l'struzione di valorizzazione della costante sql ad un'unica riga:
Codice: [Seleziona]
DIM sql AS String
DIM sqltable AS Result

DBname = "ContabFam.db"  'imposto i parametri di connessione
DB_path = Application.path & "/ContabFam_DB"
WITH DB_Connection
    .Type = "sqlite3"
    .Host = DB_path
    .Login = ""
    .Password = "
END WITH
DB_Connection.Open

sql = "CREATE TABLE 'RiepMovg' ('DtCoMovg' CHAR(8) PRIMARY KEY, 'StaDtMovg' CHAR(1) DEFAULT NULL, 'TotEntrg' INTEGER,'TotUscg' INTEGER, 'RipFing' INTEGER);"              

Così ho creato la tabella con la colonna 'DtCoMovg' definita come primary key. Questa volta piuttosto che utilizzare un vincolo di tabella per la definizione della chiave primaria, ho utilizzato un vincolo di colonna (per usare i termini impiegati nella guida).
 Dopo la crerazione della tabella ho caricato manualmente i seguenti record:

Citazione

1. Col. DtCoMovg = 19861006   ; Col. StaDtMovg = A
2. Col. DtCoMovg = 19861004   ; Col. StaDtMovg = A

Non ho valorizzato le altre colonne perché non interessavano la prova che ho in corso.

Ad ogni scrittura di record ho dato il Commit. Ecco, dopo il secondo Commit avrei dovuto ottenere una query coi record riportati nel seguente ordine di chiave primaria:
Citazione

1. Col. DtCoMovg = 19861004   ; Col. StaDtMovg = A
2. Col. DtCoMovg = 19861006   ; Col. StaDtMovg = A
, invece nella query é stato mantenuto l'ordine di inserimento record, come se non ci fosse una PRIMARY KEY, mentre in fase di creazione tabella ho definito PRIMARY KEY la col.'DtCoMovg'.

Spero di essere stato chiaro questa volta. La domanda ora é: come fare per ottenere una lettura di record  in ordine acsndente di PRIMARY KEY?

Citazione

leo72 ha scritto:
Nei DB la chiave intera è di un tipo particolare, e viene gestita in maniera diversa dalle altre. Può essere anche impostata su AUTOINCREMENT, in modo da far incrementare il numero al DB stesso.

Sugli altri tipi c'è solo il controllo della ripetizione della chiave.


La chiave autoincrementale non é di mio interesse, ma per il semplice motivo che la chiave utilizzata nella tabella citata è una stringa di 8 crt valorizzata con una data di calendario nel formatto anno-mese-giorno (AAAAMMGG).

Io ricordo che definire una colonna di una tabella come PRIMARY KEY costituisce indicizzaziione della tabella riferita a quella colonna. Mi sbaglio?

Ciao a tutti.
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SQLite3: chiave primaria non ordinata
« Risposta #5 il: 09 Giugno 2009, 10:05:07 »
Non potendo spiegarmi il comportamento strano a livello di primary key ho ricreato la tabella assegnand0o il tipo dato INTEGER alla pruimary key , cioé
 
Codice: [Seleziona]

  sql = "CREATE TABLE 'RiepMovg' ("
  sql = sql & " 'DtCoMovg' INTEGER,"                
  sql = sql & " 'StaDtMovg' CHAR(1),"              
  sql = sql & " 'TotEntrg' INTEGER DEFAULT NULL,"  
  sql = sql & " 'TotUscg' INTEGER  DEFAULT NULL,"  
  sql = sql & " 'RipFing' INTEGER DEFAULT NULL,"    
  sql = sql & " PRIMARY KEY ('DtCoMovg')"     ' *** Vincolo di tipo Tabella ***
  sql = sql & " );"                          
  sqltable = DB_Connection.Exec(sql)


ho poi inserrito due record in tabella


Citazione

1. Col. DtCoMovg = 19861006   ; Col. StaDtMovg = A
2. Col. DtCoMovg = 19861004   ; Col. StaDtMovg = A

 Ho eseguito il commit ad ogni inserimento e dopo, mi sono ritrovato la sequenza di record che mi aspettavo e cioé:

Citazione

1. Col. DtCoMovg = 19861004   ; Col. StaDtMovg = A
2. Col. DtCoMovg = 19861006   ; Col. StaDtMovg = A
,

Ora i record sono visti nell'ordine relativo alla PRIMARY KEY

Io non sono in grado di capire, ma perché attribuendo alla PRIMARY KEY un tipo INTEGER la sequenza di lettura dei record é corretta ed attribuendo invece un tipo di dati CHAR la stessa lettura non avviene correttamente? :-o  :-o

Aggiungo ancora una cosa: guardando lo schema del DB nella presente in Sqliteman viene riportata la voce "indici di sistema (0)", mentre fino a ieri la stessa voce segnava  "indici di sistema (1)". Che significa tutto ciò?

Riproverò tutto indirizzandomi fin dove possibile a chiavi primarie di tipo INTEGER.

Non ho capito il bandolo della matassa. Comunque,  :ciao:
:ciao:

Offline leo72

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 2.163
    • Mostra profilo
    • http://www.leonardomiliani.com
Re: SQLite3: chiave primaria non ordinata
« Risposta #6 il: 09 Giugno 2009, 11:12:11 »
Da quel che so di SQL, solo la chiave primaria di tipo integer è ordinata perché in ogni tabella esiste un campo nascosto denominato rowid che contiene un indice numerico utilizzato dal DB stesso per identificare le righe. Quando si assegna una chiave di tipo INTEGER PRIMARY KEY, il DB crea un alias tra il valore di questo campo e quello del rowid. Se si inseriscono chiavi di un altro tipo, queste vengono gestite in maniera ordinaria, quindi le chiavi vengono inserite nell'ordine in cui vengono passate al DB e non credo che ci sia modo di averle ordinate perché il DB dovrebbe rigenerare l'ordine delle righe ogni volta che l'utente inserisce dei dati.
Visita il mio sito personale: http://www.leonardomiliani.com

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: SQLite3: chiave primaria non ordinata
« Risposta #7 il: 09 Giugno 2009, 14:18:32 »
Citazione

leo72 ha scritto:
Da quel che so di SQL, solo la chiave primaria di tipo integer è ordinata perché in ogni tabella esiste un campo nascosto denominato rowid che contiene un indice numerico utilizzato dal DB stesso per identificare le righe. Quando si assegna una chiave di tipo INTEGER PRIMARY KEY, il DB crea un alias tra il valore di questo campo e quello del rowid. Se si inseriscono chiavi di un altro tipo, queste vengono gestite in maniera ordinaria, quindi le chiavi vengono inserite nell'ordine in cui vengono passate al DB e non credo che ci sia modo di averle ordinate perché il DB dovrebbe rigenerare l'ordine delle righe ogni volta che l'utente inserisce dei dati.


Allora occorrerà, nei casi di primary key riferita a colonna con tipo dati char, per es., definire anche un indice basato su quella colonna o addirittura non definire una primary key, ma semplicemente un indice?

Grazie Leo. :ciao:  :ciao:
:ciao: