Gambas-it

Archivi (sola lettura) => Programmazione (Gambas 2) => Topic aperto da: Picavbg - 27 Marzo 2010, 11:10:24

Titolo: [Risolto] rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 27 Marzo 2010, 11:10:24
SQLite ha colpito ancora! :o
Sarebbe il caso di dire: Non ne posso più! ... Ma vado al dunque: Dall'idea fissa di mantenere il contenuto di ciascuna tabella ordinato in base alla mia configurazione originaria di chiave primaria (costituita da una sola colonna o da più colonne, a seconda delle necessità), ho inserito come prima colonna di ciascuna tabella il codice id autoincrement, però ho anche inserito una gestione semiautomatica di ordinamento; infatti essa può scattare in seguito ad una segnalazione su eventuali nuovi inserimenti nelle varie tabelle, consigliando il riordino di quelle che abbiano subito, per es., più 100 accodamenti.  Dall'apposita Form di avvertimento, l'utente può avviare l'ordinamento o rimandarlo ad un momento successivo. La procedura di ordinamento prevede:
1) la creazione di una tabella transitoria;
2)  la trascrizione nella nuova tabella di tutte le righe lette dalla prima col criterio "ORDER BY";
3)  la cancellazione della tabella originaria;
4) la ridenominazione della tabella transitoria, attribuendole il nome della tabella appena cancellata.
le istruzioni utilizzate sono le seguenti:
Codice: [Seleziona]
1) CREATE TABLE "NomeTabellaTransito "('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'Colonna2' INTEGER, 'Colonna3' VARCHAR(50) DEFAULT NULL, 'Colonna4' CHAR(1) DEFAULT NULL, 'Colonna5' INTEGER );
2) RecTab = DB_Connection.Edit("NomeTabellaOrigine")
    RecTab = DB_Connection.Exec("SELECT * FROM NomeTabellaOrigine ORDER BY Colonna2")
    FOR EACH RecTab
       i_id += 1
       DB_Connection.EXEC("INSERT INTO NomeTabellaTransito VALUES(" & i_id & ", '" & RecTab!Colonna2 & "', '" & RecTab!Colonna3 & "', '" & RecTab!Colonna4 & "', '" & RecTab!Colonna5 & "')")
    NEXT
    DB_Connection.Commit
    DB_Connection.Close
3) DB_Connection.EXEC("DROP TABLE NomeTabellaOrigine ")
4) DB_Connection.EXEC("ALTER TABLE 'NomeTabellaTransito' RENAME TO 'NomeTabellaOrigine'")
Dopo l'esecuzione delle suddette istruzioni, sembra che tutto sia andato bene, però proseguendo ottengo un errore, attraverso il quale rilevo che:
la tabella rinominata non viene riconosciuta dall'istruzione
Codice: [Seleziona]
IF NOT DB_Connection.Tables.Exist("NomeTabellaOrigine") 
, mentre viene trovata tranquillamente da "Sqliteman", però il passo 4), di ridenominazione, l'ha completamente svuotata del suo contenuto.
Chi mi potrebbe spiegare perchè succede tutto ciò? >:( :'(
Ciao a tutti.

Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: fsurfing - 27 Marzo 2010, 15:32:37
invece di cambiargli nome perchè non la riscrivi in una nuova tabella con il nome corretto?
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 27 Marzo 2010, 16:46:02
invece di cambiargli nome perchè non la riscrivi in una nuova tabella con il nome corretto?
Un pò, perchè ho l'indole del programmatore pigro,  :D un pò perchè pensavo di abbreviare i tempi di esecuzione con una sola trascrizione dalla TabellaOriginaria alla TabellaTransitoria. Infatti ottenuta la nuova Tabella, ordinata a mio piacimento, cancellando l'originaira e ridenominado la Transitoria col nome di origine, avrei evitato proprio tutta la seconda trascrizione per riportare i dati nell'Originaria. Chissà perchè, ma ogni volta che provo un percorso fuori dallo standard, anche se citato nella guida sql, vado sempre ad incappare in problematiche pratiche che non dovrebbero assolutamente manifestarsi. Magari penserai che io ce l'ho con SQLite; io invece penso che è SQLite ad avercela con me! ;)
Comunque, ho gia avviato la correzione del programma aggiungendo l'intera ritrascrizione dalla TabellaTransitoria alla TabellaOriginaria. Ho solamente aggiunto una riga SQL per lo svuotamento del contenuto della TabellaOriginaria ed ha funzionato:
Codice: [Seleziona]
DB_Connection.EXEC("DELETE FROM TabellaOriginaria")
Si, direi, dato che col tuo invito, mi dai conferma di avere incontrato un ostacolo insormontabile, il problema segnalato sia proprio irrisolvibile.  :-X :)
Ciao.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: milio - 27 Marzo 2010, 16:58:37
la tabella rinominata non viene riconosciuta dall'istruzione
Codice: [Seleziona]
IF NOT DB_Connection.Tables.Exist("NomeTabellaOrigine") 
, mentre viene trovata tranquillamente da "Sqliteman", però il passo 4), di ridenominazione, l'ha completamente svuotata del suo contenuto.
Chi mi potrebbe spiegare perchè succede tutto ciò? >:( :'(
Ciao a tutti.




L'istruzione che hai scritto ti ritorna TRUE se la tabella non esiste...
Era quello che volevi fare?
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 28 Marzo 2010, 23:16:03
la tabella rinominata non viene riconosciuta dall'istruzione
Codice: [Seleziona]
IF NOT DB_Connection.Tables.Exist("NomeTabellaOrigine") 
, mentre viene trovata tranquillamente da "Sqliteman", però il passo 4), di ridenominazione, l'ha completamente svuotata del suo contenuto.
Chi mi potrebbe spiegare perchè succede tutto ciò? >:( :'(
Ciao a tutti.
L'istruzione che hai scritto ti ritorna TRUE se la tabella non esiste...
Era quello che volevi fare?
/quote]
No, il problema non è quello; L'istruzione di test sull'esistenza della tabella funziona benissimo. Quella che non funziona è l'istruzione di ridenominazione della tabella già valorizzata con gli elementi provenienti dalla TabellaOriginaria. Essa
Codice: [Seleziona]
DB_Connection.EXEC("ALTER TABLE 'NomeTabellaTransito' RENAME TO 'NomeTabellaOrigine'") 
infatti produce due effetti incredibili:
1) Modifica il nome della tabella, ma poi l'istruzione di test usata in Gambas non la trova, mentre il gestore di DB Sqliteman (io uso Fedora), la tabella viene riconosciuta col nuovo nome (TabellaOriginaria)
2) Svuota completamente il contenuto della tabella,

Se la mia  "ALTER TABLE" è stata scritta correttamente, il risultato finale è assolutamente illogico. Spero di essere riuscito  chiararti il problema incontrato  e l'annesso mio concetto.
Ciao.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: milio - 29 Marzo 2010, 04:40:36
Ho fatto il seguente test:
Codice: [Seleziona]
PUBLIC SUB QueryTest()
DIM Sql AS String
DIM Nx AS Integer
DIM Res AS Result

  ' Funzione che mi ritorna la connessione al db (non sono stato li a postarla)
  conn = MDatabase.CreateDatabase()

  ' la seguente sql mi crea la tabella e ci inserisce i dati dentro dalla tabella di origine
  Sql = "CREATE TABLE NomeTabellaTransito AS SELECT * FROM NomeTabellaOrigine ORDER BY cassa;"
  conn.Exec(Sql)

  ' cancello la tabella di origine
  Sql = "DROP TABLE NomeTabellaOrigine"
  conn.Exec(Sql)

  ' Rinomino la tabella di transito
  Sql = "ALTER TABLE 'NomeTabellaTransito' RENAME TO 'NomeTabellaOrigine';"
  conn.Exec(Sql)
  
  ' Test: Se la tabella NomeTabellaOrgine esiste mi esegue il test
  IF conn.Tables.Exist("NomeTabellaOrigine") THEN
    Sql = "SELECT * FROM NomeTabellaOrigine;"
    Res = conn.Exec(Sql)
    FOR Nx = 0 TO Res.Max
      Res.MoveTo(Nx)
      FMain.TextArea1.Text &= Res[0] & ";" & Res[1] & ";" & Res[2] & ";" & Res[3] & Chr(10)
    NEXT
  ENDIF

END

Il test viene eseguito perfettamente e mi ritorna nella mia textarea i record separati da ;

quello che volevo dire io e' che se metti

Codice: [Seleziona]
IF conn.Tables.Exist("NomeTabellaOrigine") THEN 

gambas esegue le istruzioni se la tabella esiste, invece se

Codice: [Seleziona]
IF NOT conn.Tables.Exist("NomeTabellaOrigine") THEN 

come hai scritto tu nel primo post, esegue le istruzioni se la tabella NON esiste...



Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 30 Marzo 2010, 10:16:10
Scusa,  milio, ma non ho capito cosa mi vuoi dimostrare con la tua prova. La prima parte di essa coincide con le istruzioni utilizzate da me, per cui fino alla "ALTER TABLE" siamo sulla stessa linea. Infatti io  ho scritto:
Codice: [Seleziona]
CREATE TABLE "NomeTabellaTransito "('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'Colonna2' INTEGER, 'Colonna3' VARCHAR(50) DEFAULT NULL, 'Colonna4' CHAR(1) DEFAULT NULL, 'Colonna5' INTEGER );
RecTab = DB_Connection.Edit("NomeTabellaOrigine")
RecTab = DB_Connection.Exec("SELECT * FROM NomeTabellaOrigine ORDER BY Colonna2")
FOR EACH RecTab
       i_id += 1
       DB_Connection.EXEC("INSERT INTO NomeTabellaTransito VALUES(" & i_id & ", '" & RecTab!Colonna2 & "', '" & RecTab!Colonna3 & "', '" & RecTab!Colonna4 & "', '" & RecTab!Colonna5 & "')")
NEXT
    DB_Connection.Commit
    DB_Connection.Close
DB_Connection.EXEC("DROP TABLE NomeTabellaOrigine ") DB_Connection.EXEC("ALTER TABLE 'NomeTabellaTransito' RENAME TO 'NomeTabellaOrigine'")
DB_Connection.EXEC("ALTER TABLE 'NomeTabellaTransito' RENAME TO 'NomeTabellaOrigine'")
mentre tu hai scritto:
Citazione
Ho fatto il seguente test:
Codice: [Seleziona]
  Sql = "CREATE TABLE NomeTabellaTransito AS SELECT * FROM NomeTabellaOrigine ORDER BY cassa;"
  conn.Exec(Sql)
  ' cancello la tabella di origine
  Sql = "DROP TABLE NomeTabellaOrigine"
  conn.Exec(Sql)
  ' Rinomino la tabella di transito
  Sql = "ALTER TABLE 'NomeTabellaTransito' RENAME TO 'NomeTabellaOrigine';"
  conn.Exec(Sql)
Stabilito ciò, quello che bisognerebbe capire è perchè a te il test
Codice: [Seleziona]
 IF conn.Tables.Exist("NomeTabellaOrigine") THEN 
si conclude con "TRUE", mentre a me  si conclude con "FALSE" e, poi, perchè tu ritrovi, nella tabella rinominata, tutti i record copiati precedentemente, mentre io mi ritrovo la tabella vuota. :o
La risposta a codeste domande non è facilmente fornibile, perchè operiamo in ambienti operativi diversi (tu usi Ubuntu ed io Fedora), e probabilmente tu usi una versionme di Gambas diversa dalla mia che è la 2.19. Potrebbero proprio i motori su cui girano i nostri programmai a produrre, non so per quale motivo, effetti diversi. Un'altra considerazione potrebbe essere: l'ambiente su cui gira il mio programma è teoricamente non responsabile, però l'anomalia che mi si verifica dipende dall'assenza nell'ide del mio Gambas di qualche componente preposto a svolgere correttamente le funzioni che ho richiamate.
Ti ringrazio per l'aiuto e mi complimento con te per la tua conoscenza di SQLite3; ho visto come usi le istruzioni SQL anche in altre discussioni  e non posso che fare tesoro dei tuoi consigli. Mi dispiace solo che non possa trarne vantaggio in questo momento. Ciao.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: leo72 - 30 Marzo 2010, 10:45:38
Milio ti sta dicendo che il test che esegui tu domanda al DB se NON esiste la tabella. Siccome la tabella esiste, ti restituisce False perché il test non è andato a buon fine (cioè la tabella esiste).

Quel "NOT" significa proprio questo: inverti il senso (o risultato) del test.
La tabella SQLiteMan la vede proprio perché c'è.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 30 Marzo 2010, 14:35:01
Milio ti sta dicendo che il test che esegui tu domanda al DB se NON esiste la tabella. Siccome la tabella esiste, ti restituisce False perché il test non è andato a buon fine (cioè la tabella esiste).
Quel "NOT" significa proprio questo: inverti il senso (o risultato) del test.
La tabella SQLiteMan la vede proprio perché c'è.
>:( >:( >:(
Carissimo Leo, forse invece non è chiaro il mio problema, perchè credo di  sapere benissimo che IF not ... exist è esattamente l'opposto di  IF  ... exist e so bene anche quale codice viene eseguito a seconda che si verifichi l'una o l'altra condizione. Io non vado  a scuola di programmazione per cui ho bisogno di avere spiegato che cosa sia una  "if" e quale sia l'effetto sul programma , a seconda che si verifichi una condizione o la sua opposta. Credo invece che nessuno di quelli che avete letto i miei post, a parte fsurfing, vi siate ancora resi conto di quello che non funziona.
Ho detto dal mio primo post che, dopo avere rinominato la tabella, gambas non la riconosce come tabella esistente col nuovo nome;
Ho detto anche che, dopo avere rinominato la tabella, dentro di essa non esiste più il suo contenuto e l'ho appurato anche tramite sqliteman.
Ci vuole tanto a capire quello che voglio dire? A volte, prima di rispondere, occorre leggere tutta la discussione, perchè la lettura dell'ultimo post può portare molto, ma molto fuori strada.
Mi dispiace di avere risposto in maniera irriguardevole, ma non posso accettare di passare per un pivello apprendista che non sappia distinguere la mano destra dalla sinistra.
Ho guardato il codice provato da Milio ed ho evidenziato la quasi specchiabilità di quello col mio, proprio per evidenziare che il problema non è nel codice, ma nell'effetto prodotto nel mio ambiente.
Allora, è chiaro quello che voglio dire?
Citazione
Perchè dopo avere rinominato una tabella qualsiasi in SQLite3, perdo il suo contenuto?
Perchè, , pur esistendo, la tabella, secondo Gambas 2.19, invece non esiste?
Credo che il problema sia da ricercare altrove, non nel codice che ho scritto io.
Comunque, se lo desideri, posso allegare tutto il sorgente, comprese le tabelle.
Ciao.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: milio - 30 Marzo 2010, 15:07:55
Urka come ti scaldi  ;D

Nessuno a detto a nessuno di essere un 'pivello apprendista' (ma poi che che male c'e')

Penso che qui sia nato l'equivoco:
nel tuo primo post, se vai a leggerlo attentamente, dopo che hai descritto cosa hai fatto per spostare-rinominare una tabella, hai scritto questo:


Dopo l'esecuzione delle suddette istruzioni, sembra che tutto sia andato bene, però proseguendo ottengo un errore, attraverso il quale rilevo che:
la tabella rinominata non viene riconosciuta dall'istruzione
Codice: [Seleziona]
IF NOT DB_Connection.Tables.Exist("NomeTabellaOrigine") 
, mentre viene trovata tranquillamente da "Sqliteman", però il passo 4), di ridenominazione, l'ha completamente svuotata del suo contenuto.
Chi mi potrebbe spiegare perchè succede tutto ciò? >:( :'(
Ciao a tutti.



Ecco perche', almeno io, continuo a dirti dove sta l'errore... poi se tu hai sbagliato a scrivere, e' tutta un'altra storia...

Ciao... ;)
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: milio - 30 Marzo 2010, 15:16:11
Poi per fare un'altra prova potresti usare il mio codice per testare se funziona anche sul tuo pc, con la tua distro e la tua versione di gambas... almeno ci togliamo ogni dubbio ;)

io uso kubuntu con gambas 2.20.2
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: leo72 - 31 Marzo 2010, 11:00:52
Concordo con Milio su tutti i punti:

1) nessuno ti ha dato del pivello, ti sei scaldato proprio per nulla  ;)
2) ho letto tutta la discussione e nel tuo primo post hai scritto che Gambas non vede la tabella creata ma Sqliteman sì anche se vuota;
3) non è facile capire i problemi quando uno è seduto di fronte ad un computer e l'altro è a 500 km di distanza  ::)
4) googlando ho trovato questo procedimento per cambiare il nome ad una tabella:
Codice: [Seleziona]
-Inserire una nuova colonna nel database (esempio completo).
ATTENZIONE FARE PRIMA UNA COPIA DEL FILE-DATABASE
sqlite prova
#Crea una tabella
sqlite> create table t1(a text, b text);
#Inizia la transazione
sqlite> BEGIN TRANSACTION;
#Crea una tabella temporanea uguale all'altra tabella
sqlite> CREATE TEMPORARY TABLE t1_backup(a,b);
#Fa un copia ed incolla dalla prima tabella alla tabella temporanea
sqlite> INSERT INTO t1_backup SELECT a,b FROM t1;
#Cancella la prima tabella
sqlite> DROP TABLE t1;
#Crea la nuova tabella con la nuova colonna
sqlite> CREATE TABLE t1(a text,b text,c text);
#Fa una copia dalla tabella temporanea alla nuova tabella
sqlite> INSERT INTO t1 (a,b) select * FROM t1_backup;
#Cancella la tabella temporanea
sqlite> DROP TABLE t1_backup;
#Finisce la transazione.
sqlite> COMMIT;
#Controllo nomi colonne
sqlite> .schema

Immagino che un adattamento a Gambas non sia difficile.
Qualcosa tipo:
Codice: [Seleziona]
DB_Connection.Begin
RecTab = DB_Connection.EXEC("CREATE TEMPORARY TABLE NomeTabellaTransito (id INTEGER PRIMARY KEY AUTOINCREMENT, Colonna2 INTEGER, Colonna3 VARCHAR(50) DEFAULT NULL, Colonna4 CHAR(1) DEFAULT NULL, Colonna5 INTEGER );")
RecTab = DB_Connection.EXEC("INSERT INTO NomeTabellaTransito FROM NomeTabellaOrigine ORDER BY Colonna2;")
RecTab = DB_Connection.EXEC("DROP TABLE NomeTabellaOrigine;")
RecTab = DB_Connection.EXEC("CREATE TABLE NomeTabellaOrigine (id INTEGER PRIMARY KEY AUTOINCREMENT, Colonna2 INTEGER, Colonna3 VARCHAR(50) DEFAULT NULL, Colonna4 CHAR(1) DEFAULT NULL, Colonna5 INTEGER );")
RecTab = DB_Connection.EXEC("INSERT INTO NomeTabellaOrigine FROM NomeTabellaTransito;")
RecTab = DB_Connection.EXEC("DROP TABLE NomeTabellaTransito;")
DB_Connection.Commit
DB_Connection.Close
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 31 Marzo 2010, 17:12:38
Poi per fare un'altra prova potresti usare il mio codice per testare se funziona anche sul tuo pc, con la tua distro e la tua versione di gambas... almeno ci togliamo ogni dubbio ;)
io uso kubuntu con gambas 2.20.2
Rispondo solo ora perchè ho voluto concludere un test sul programma. Infatti, mentre ragionavo con voi sulla funzione SQL "ALTER TABLE", sono andato avanti.

Anche se a me non piacciono le polemiche, devo dire che, per gli appellativi come "pivello" possono anche essere dichiarati senza nominare il termine esatto: Lo stesso effetto si ottiene, usando frasi che lo facciano capire:
(((se metti  IF conn.Tables.Exist("NomeTabellaOrigine") THEN  gambas esegue le istruzioni se la tabella esiste, invece se  IF NOT conn.Tables.Exist("NomeTabellaOrigine") THEN   esegue le istruzioni se la tabella NON esiste), rafforzata poi da: (Milio ti sta dicendo che il test che esegui tu domanda al DB se NON esiste la tabella. Siccome la tabella esiste, ti restituisce False perché il test non è andato a buon fine (cioè la tabella esiste). Quel "NOT" significa proprio questo: inverti il senso (o risultato) del test. La tabella SQLiteMan la vede proprio perché c'è.)))
Come vedi, soprattutto nella seconda affermazione il concetto è pungente, anche se il termine non è stato citato.
Siccome non credo che che sia costruttivo andare avanti con simili ragionamenti, anche perchè sono convinto che sia io, da una parte, che voi due, dall'altra, rimarremo sempre nelle nostre posizioni, per quanto mi riguarda, la parentesi comportamentale, può considerarsi chiusa.
 :)
Ho voluto provare il tuo codice, anche perchè contiene un'istruzione originale, che non conoscevo (ammetto la mia ignoranza in proposito):
Codice: [Seleziona]
' la seguente sql mi crea la tabella e ci inserisce i dati dentro dalla tabella di origine
  Sql = "CREATE TABLE NomeTabellaTransito AS SELECT * FROM NomeTabellaOrigine ORDER BY cassa;"
 IF DB_Connection.Tables.Exist("NomeTabellaTransito") THEN
    Sql = "SELECT * FROM NomeTabellaTransito;"
    RecTab = DB_Connection.Exec(Sql)
    FOR i = 0 TO RecTab.Max
    NEXT
    PRINT  i  ---->  stampa 142 (cioè il n° dei record teoricamente copiati)
  ENDIF
  ' cancello la tabella di origine
  Sql = "DROP TABLE NomeTabellaOrigine"
  DB_Connection.Exec(Sql)
  ' Rinomino la tabella di transito
  Sql = "ALTER TABLE 'NomeTabellaTransito' RENAME TO 'NomeTabellaOrigine';"
  DB_Connection.Exec(Sql)
  DB_Connection.Commit
  DB_Connection.Close
  WITH
      DB_Connection
      .Type = "sqlite3"
      .Host = VarGlob.$_DbPath
      .Name = VarGlob.$_DbNome
      .OPEN    'Apro il DB
  END WITH
  IF DB_Connection.Tables.Exist("NomeTabellaOrigine") THEN
    Sql = "SELECT * FROM NomeTabellaOrigine;"
    RecTab = DB_Connection.Exec(Sql)
    FOR i = 0 TO RecTab.Max
    NEXT
    PRINT i     ---->  stampa  ancora 142 (sembrerebbe perciò che il lavoro sia andato bene)
  ELSE
    PRINT "La Tabella 'piancont' non esiste"
  ENDIF
Dall'andamento delle interrogazioni sui record di tabella, sia nella fase intermedia, di registrazione sulla 'TabellaTransito',  che nella fase finale, di registrazione sulla 'TabellaOrigine', sembrerebbe che abbia funzionato.
Accedendo però alla Tabella di DB tramite Sqliteman, ahimè, l'ho trovata di nuovo vuota. L'unica cosa che è cambiata dalla mia prova iniziale  è che il test  'IF DB_Connection.Tables.Exist("NomeTabellaOrigine") ' questa volta trova la tabella.
 :-\
Che ne pensi?
Secondo me, non conviene insistere. :)
Ciao.


Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: milio - 31 Marzo 2010, 17:56:43
Nessun problema, discussione 'animata' chiusa; discussione 'costruttiva' aperta ;)

hai provato a vedere se gambas 'vede' i record, cioe' se al posto di contare i record ci fai un print del contenuto ?

cosi' vediamo se effettivamente sono stati copiati... fammi sapere...

ps. altra cosa che ho visto e' che hai preso pari pari il mio codice
Codice: [Seleziona]
Sql = "CREATE TABLE NomeTabellaTransito AS SELECT * FROM NomeTabellaOrigine ORDER BY cassa;"

io ho messo ORDER BY cassa perche' avevo un campo chiamato cosi'... e' chiamato cosi' anche il tuo campo di riordino?
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: fsurfing - 31 Marzo 2010, 17:57:26
Citazione
Anche se a me non piacciono le polemiche, devo dire che, per gli appellativi come "pivello" possono anche essere dichiarati senza nominare il termine esatto: Lo stesso effetto si ottiene, usando frasi che lo facciano capire:
(((se metti  IF conn.Tables.Exist("NomeTabellaOrigine") THEN  gambas esegue le istruzioni se la tabella esiste, invece se  IF NOT conn.Tables.Exist("NomeTabellaOrigine") THEN   esegue le istruzioni se la tabella NON esiste), rafforzata poi da: (Milio ti sta dicendo che il test che esegui tu domanda al DB se NON esiste la tabella. Siccome la tabella esiste, ti restituisce False perché il test non è andato a buon fine (cioè la tabella esiste). Quel "NOT" significa proprio questo: inverti il senso (o risultato) del test. La tabella SQLiteMan la vede proprio perché c'è.)))
Come vedi, soprattutto nella seconda affermazione il concetto è pungente, anche se il termine non è stato citato.
io sono sicurissimo che sia leo che milio con quella frase non volesso asserire che tu sei un "pivello", spesso capitano delle sviste anche sul codice semplice e ci sbattiamo la testa per ore ore o giorni , poi quando ci accorgiamo della cacchiata che abbiamo fatto ci diamo del pirla :)
cmq hai fatto bene a mettere in chiaro le cose , mi spiace solo non aver tempo per fare delle prove e capire quale sia il problema.
facci sapere quando risolvi ciao ciao
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: leo72 - 31 Marzo 2010, 23:49:56
Replico solo perché alle volte uno sterile messaggio di testo non riporta bene il concetto che uno vorrebbe esprimere, non per fare sterile polemica.

fsurfing ha espresso molto meglio di me ciò che è successo e cioè che io pensavo ti fossi arenato di fronte al classico errore banalissimo che, proprio perché banale, è l'ultimo della lista degli indiziati.

Con questo anch'io chiudo perché questa comunità è bella proprio perché siamo molto uniti e legati, avendo fatto un percorso comune che, nel giro di 2 anni, ci ha portato ad essere forse il gruppo organizzato di utenti Gambas più numeroso, competente ed organizzato che c'è.

Archivio questa discussione come il classico "attrito" che c'è anche nelle migliori famiglie ma che, come nelle migliori famiglie, si chiarisce sempre discutendo schiettamente.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 01 Aprile 2010, 00:10:14
facci sapere quando risolvi ciao ciao
Per la verità, praticamente ho superato l'ostacolo seguendo il tuo consiglio, cioè:
Codice: [Seleziona]
$_TbRiord2 = "TabellaTransito" 
CreTabDb = NEW CreaTabDb($_TbRiord2)       'classe di creazione di tutte le tabelle del DB o singolarmente in base al nome contenuto in $_TbRiord2
RecTab = DB_Connection.Edit("TabellaOriginaria")     
RecTab = DB_Connection.Exec("SELECT * FROM TabellaOriginaria ORDER BY NumVoce")
i_id = 0
  FOR EACH RecTab
      i_id += 1
      DB_Connection.EXEC("INSERT INTO TabellaTransito VALUES(" & i_id & ", '" & RecTab!NumVoce & "', '" & RecTab!NomeVoce & "', '" & RecTab!ContrPartSiNo & "', '" & RecTab!DtPrimoUso & "')")
  NEXT
DB_Connection.Commit
  DB_Connection.Close
  WITH
      DB_Connection
      .Type = "sqlite3"
      .Host = VarGlob.$_DbPath
      .Name = VarGlob.$_DbNome
      .OPEN    'Apro il DB
  END WITH
 DB_Connection.EXEC("DELETE FROM TabellaOriginaria")        'Cancellazione del contenuto della "TabellaOriginaria"
    DB_Connection.Commit
    DB_Connection.Close
    WITH
      DB_Connection
      .Type = "sqlite3"
      .Host = VarGlob.$_DbPath
      .Name = VarGlob.$_DbNome
      .OPEN    'Apro il DB
    END WITH
    RecTab = DB_Connection.Edit("TabellaTransito")
    RecTab = DB_Connection.Exec("SELECT * FROM TabellaTransito ORDER BY NumVoce")
    i_id = 0
    FOR EACH RecTab
      i_id += 1
      TRY DB_Connection.EXEC("INSERT INTO TabellaOriginaria VALUES(" & i_id & ", '" & RecTab!NumVoce & "', '" & RecTab!NomeVoce & "', '" & RecTab!ContrPartSiNo & "', '" & RecTab!DtPrimoUso & "')")
    NEXT
    DB_Connection.Commit
    DB_Connection.Close
 WITH
      DB_Connection
      .Type = "sqlite3"
      .Host = VarGlob.$_DbPath
      .Name = VarGlob.$_DbNome
      .OPEN    'Apro il DB
    END WITH
 DB_Connection.EXEC("DROP TABLE TabellaTransito")
Certo il tempo di esecuzione si raddoppia, e si nota, ma funziona benissimo. Ho adottato la soluzione ancora prima di leggere il primo suggerimento di milio, poi ho voluto riprendere la prova perchè speravo che l'istruzione
Codice: [Seleziona]
Sql = "CREATE TABLE TabellaTransito AS SELECT * FROM TabellaOriginaria ORDER BY NumVoce;"
DB_Connection.Exec(Sql)
, molto accattivante, di milio potesse aiutarmi a ritornare alla prima soluzione (ALTER TABLE). Purtroppo la prova non sembra funzionare.

@ milio:
Nella mia tabella, la colonna indicata dopo l'ORDER BY è NumVoce, solo che nel ripetere il codice da allegare al mio messaggio ho dimenticato di sostituire il tuo nome campo col mio; però tutto sommato, penso che abbia poca importanza (i miei nomi campo non sono molto facili da ricordare, mi rendo conto).
Ho colto il tuo invito. Domani, spero di trovare il tempo di fare la prova che dici e che già avevo capito di fare leggendo il tuo esempio  di partenza, ma che avevo sostituito con la "print RecTab.Max" perchè in debug avevo notato che la "CREATE TABLE ... ORDER BY" aveva, almeno apparentemente, creato una tabella vuota (da Sqliteman).

@ Leo:
Proprio come dici tu; Il bello di una famiglia aperta al dialogo è il ritorno del sereno dopo la tempesta.

Ciao a tutti.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 01 Aprile 2010, 09:55:25
@ milio:
Ho eseguito la prova come mi hai proposto, ma relativamente ad una tabella di soli tre record; per la print non ho usato una textarea, ma una semplice FOR EACH, print. Purtroppo non ha funzionato.
Codice: [Seleziona]
Sql = "CREATE TABLE causalifreq2 AS SELECT * FROM causalifreq ORDER BY id;"
  DB_Connection.Exec(Sql)
  DB_Connection.Commit
  DB_Connection.Close
  WITH
      DB_Connection
      .Type = "sqlite3"
      .Host = VarGlob.$_DbPath
      .Name = VarGlob.$_DbNome
      .OPEN    'Apro il DB
  END WITH
  IF DB_Connection.Tables.Exist("causalifreq2") THEN
    Sql = "SELECT * FROM causalifreq2;"
    RecTab = DB_Connection.Exec(Sql)
    FOR i_id = 0 TO RecTab.Max
    NEXT
   PRINT i_id
 ENDIF
 ' cancello la tabella di origine
 Sql = "DROP TABLE causalifreq"
 DB_Connection.Exec(Sql)
 ' Rinomino la tabella di transito
 Sql = "ALTER TABLE 'causalifreq2' RENAME TO 'causalifreq';"
 DB_Connection.Exec(Sql)
 DB_Connection.Commit
 DB_Connection.Close
  WITH
      DB_Connection
      .Type = "sqlite3"
      .Host = VarGlob.$_DbPath
      .Name = VarGlob.$_DbNome
      .OPEN    'Apro il DB
  END WITH
  IF DB_Connection.Tables.Exist("causalifreq") THEN
    Sql = "SELECT * FROM causalifreq;"
    RecTab = DB_Connection.Exec(Sql)
    FOR i_id = 0 TO RecTab.Max
     
    NEXT
    PRINT i_id
    RecTab = DB_Connection.Edit("causalifreq")
    FOR EACH RecTab
       PRINT "id= " & RecTab!id, "RecTab!DescrCausFreq= " & RecTab!DescrCausFreq, "RecTab!DtUltCausFreq= " & RecTab!DtUltCausFreq
    NEXT
  ELSE
    PRINT "La Tabella 'causalifreq' non esiste"
  ENDIF

l'istruzione
Codice: [Seleziona]
 RecTab = DB_Connection.Edit("causalifreq")
produce l'errore
"Table 'caualifreq' has no priimary key
Penso proprio che per me e per il mio ambiente la strada "ALTER TABLE" non sia percorribile.
Ciao.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: milio - 01 Aprile 2010, 16:39:48
e se fai in questo modo?

Codice: [Seleziona]
    Sql = "CREATE TABLE nometabellatransito AS SELECT id, cassa, entrate, uscite FROM nometabellaorigine ORDER BY cassa;"
  conn.Exec(Sql)

  Sql = "DROP TABLE nometabellaorigine"
  conn.Exec(Sql)

  Sql = "CREATE TABLE nometabellaorigine AS SELECT id, cassa, entrate, uscite FROM nometabellatransito;"
  conn.Exec(Sql)

  Sql = "DROP TABLE nometabellatransito"
  conn.Exec(Sql)

devi specificare ogni singolo campo nella select perche' ho visto che se metti * rinomina il campo in nometabella.nomecampo
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 01 Aprile 2010, 23:46:58
e se fai in questo modo?
Codice: [Seleziona]
    Sql = "CREATE TABLE nometabellatransito AS SELECT id, cassa, entrate, uscite FROM nometabellaorigine ORDER BY cassa;"
  conn.Exec(Sql)
  Sql = "DROP TABLE nometabellaorigine"
  conn.Exec(Sql)
  Sql = "CREATE TABLE nometabellaorigine AS SELECT id, cassa, entrate, uscite FROM nometabellatransito;"
  conn.Exec(Sql)
  Sql = "DROP TABLE nometabellatransito"
  conn.Exec(Sql)
devi specificare ogni singolo campo nella select perche' ho visto che se metti * rinomina il campo in nometabella.nomecampo
Grazie per il suggerimento. Ma dove hai letto tutto qello che hai imparato? Ho visto che usi istruzioni che io non ho mai incontrato prima. Complimenti !!! :D
Allora; quasi non ci credo, ma penso proprio che mi hai acceso la lampadina giusta.  Solo che dell'ultimo codice da te suggerito, a causa della mia testardaggine, ho modificato ho preso solo una parte, lasciando per il resto quello usato nella prova precedente. Riporto qui di seguiito solo le istruzioni salienti, trascurando tutti i passi di Open, Commit  e Close.
Codice: [Seleziona]
Sql = "CREATE TABLE nometabellatransito AS SELECT id, Campo1, Campo2 FROM nometabellaorigine ORDER BY Campo1;"
 DB_Connection.Exec(Sql)

  IF DB_Connection.Tables.Exist("nometabellatransito") THEN
    Sql = "SELECT * FROM nometabellatransito;"
    RecTab = DB_Connection.Exec(Sql)
    FOR EACH RecTab
       PRINT "id= " & RecTab!id, "RecTab!Campo1= " & RecTab!Campo1, "RecTab!Campo2= " & RecTab!Campo2
    NEXT
   ENDIF

  Sql = "DROP TABLE nometabellaorigine"
 DB_Connection.Exec(Sql)

 Sql = "ALTER TABLE 'nometabellatransito' RENAME TO 'nometabellaorigine';"
 DB_Connection.Exec(Sql)
 '--- wwwwwwwwwwwwwwwwwww -------------------- HA FUNZIONATO: la tabella presenta tutto il suo contenuto anche con Sqliteman ----------------------
  IF DB_Connection.Tables.Exist("nometabellaorigine") THEN
    Sql = "SELECT * FROM causalifreq;"
    RecTab = DB_Connection.Exec(Sql)
   
    Sql = "SELECT * FROM nometabellaorigine;"
    RecTab = DB_Connection.Exec(Sql)
'--------------------------- qui ho dovuto sostituire l'istruzione  --> RecTab2 = DB_Connection.Edit("nometabellaorigine")  <-- perchè dava l'errore: ...' has no primary key.
   
    FOR EACH RecTab
       PRINT "id= " & RecTab!id, "RecTab!Campo1= " & RecTab!Campo1, "RecTab!Campo2= " & RecTab!Campo2
    NEXT
Tutte e due le funzioni di stampa hanno riportato le righe presenti effettivamente in tabella. Non solo, ho verificato anche con Sqliteman e ...
la tabella è completa con tutte le sue righe, per cui, ..... finalmente ... ALTER TABLE ha funzionato
 :D ;D
Ma solo perchè ... hai insistito.
Non capisco perchè la .Edit non ha voluto più funzionare.
Ciao.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 02 Aprile 2010, 23:28:49
@ milio:
Ho cantato vittoria troppo presto. Infatti tutte le istruzioni
Codice: [Seleziona]
RecTab = DB_Connection.Edit("NomeTabella")
che hanno riferite alla tabella interessata dall'ALTER TABLE, producono l'errore
Citazione
"Table 'NomeTabella' has no priimary key
Ho guardato in Sqliteman->Contesto->Descrivi tabella, prima e dopo l'ALTER TABLE, ed ecco la differenza:
Citazione
Prima dell'istruzione ALTER TABLE:
-- Descrizione CAUSALIFREQ
Codice: [Seleziona]
CREATE TABLE 'causalifreq'('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'DescrCausFreq' VARCHAR(100), 'DtUltCausFreq' INTEGER )

Dopo l'istruzione ALTER TABLE:
Codice: [Seleziona]
-- Descrizione CAUSALIFREQ
CREATE TABLE "causalifreq"(
  id INT,
  DescrCausFreq TEXT,
  DtUltCausFreq INT
)
Come vedi non esiste più la definizione INTEGER PRIMARY KEY AUTOINCREMENT per l'id e non esistono più datatype relativi alle colonne.
 :( :(
Ciao.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: milio - 03 Aprile 2010, 10:05:22
Si ho visto anche io (finalmente dirai tu ;) ) che si pianta casino con l'Alter Table... allora mi sono chiesto: come fa sqliteman a rinominare la tabella?

Prova a fare:

Selezioni una tabella.
Tasto destro del mouse - Modifica Tabella
Nella box Nome Tabella modifica il nome della tabella
Clicca su Esegui Alter
Guarda cosa succede nella finestra del log!
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 04 Aprile 2010, 10:31:09
@ milio:
Spero di avere capito il tuo riferimento alla finestra di log.

Ho segutio passo passo la tua indicazione per alterare a manina il nome di una tabella del mio DB; ho scelto la tabella "causalifreq"  . Riporto qui oltre al contenuto della relativa finestra di log, anche la descrizione, prima e dopo il processo di alterazione.
Citazione
-- Descrizione CAUSALIFREQ   (prima di ALTER):
CREATE TABLE "causalifreq2"('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'DescrCausFreq' VARCHAR(100), 'DtUltCausFreq' INTEGER )

--Contenuto della finestra di log, in Sqliteman:
Renaming the table "causalifreq" to "causalifreq2".
Rinomino la tabella originale in _alter0_causalifreq2
Sto per creare una nuova Tabella: causalifreq2
Inizio la Transazione
Trasferimento Dati
Chiudo la Transazione
Elimino la tabella originale _alter0_causalifreq2
Alter Table Eseguito

-- Descrizione CAUSALIFREQ    (dopo di ALTER):
CREATE TABLE causalifreq2 (
    "id" INTEGER,
    "DescrCausFreq" VARCHAR(100),
    "DtUltCausFreq" INTEGER
)
Come si vede, Sqliteman, pur modificando qualcosa nella descrizione, si comporta bene: il comando ALTER ha funzionato perfettamente; ciascuna colonna ha mantenuto il suo datatype corretto. Ho guardato  la tabella  ed ho constatato che ha mantenuto tutte le sue righe; poi ho rieseguito il programma ed esso non ha prodotto alcun errore sull'istruzione:
Codice: [Seleziona]
RecTab = DB_Connection.edit($_NomeTab) 

Però devo aggiungere che in Sqliteman esiste un altro percorso per rinominare una tabella. Esso  è quello eseguito da me, per provare il mio prgramma, prima di conoscere la funzione ALTER. La funzione non utilizza tabelle di transito, ma cambia solamente il nome della tabella e, pertanto, non modifica la parte descrittiva della tabella. Ciò si vede dal seguente percorso:
Citazione
-- Descrizione CAUSALIFREQ (prima di Rinomina la tabella):
Codice: [Seleziona]
CREATE TABLE 'causalifreq'('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'DescrCausFreq' VARCHAR(100), 'DtUltCausFreq' INTEGER )

Ho seleziono la tabella
Tasto destro del mouse - Rinomina la Tabella;
Nella box Nuovo Nome della Tabella, ho modificato il nome della tabella
ho cliccato su OK.
Non c'è finestra di log

-- Descrizione CAUSALIFREQ1  (dopo avere rinominato la tabella):
Codice: [Seleziona]
CREATE TABLE "causalifreq1"('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'DescrCausFreq' VARCHAR(100), 'DtUltCausFreq' INTEGER )

Dal confronto delle due descrizioni, prima e dopo avere rinominatio la tabella, si rileva la perfetta corrispondenza di tutti i caratteri. Però, non mi pare che esista un'istruzionme SQL eseguibile da Gambas che svolga la stessa funzione, perchè, come abbiamo vissuto, con la funzione "ALTER TABLE" l'istruzione SQL in Gambas si comporta in maniera diversa rispetto a come lavora Sqliteman.
Ciao.
Titolo: Re: rinominare tabella SQlite3 da programma
Inserito da: Picavbg - 24 Settembre 2013, 00:11:34
Riprendo questa vecchia discussione solamente per porre la parola [Risolto].

Ieri, dopo tanto tempo, ho ripreso la parte di programma dove avrei voluto utilizzare all'epoca l'istruzione SQL si SQLite3 "ALTER TABLE". Allora non riuscii, nemmeno coi suggerimenti ricevuti, ad impiegare l'istruzione a causa di errori ottenuti durante l'esecuzione.
Cosa sia accaduto esattamente allora non ricordo più, ma sicuramente la mia inesperienza nell'utilizzo di SQLite3, ha influito enormemente.  :-\

Ieri, ripeto, allo scopo di ridurre notevolmente i tempi di rsequenziazione dei record di ciascuna tabella del mio DB, ho ripreso coraggio ed ho voluto ripetere la prova. Ebbene, è andato tutto liscio come l'olio, le tabelle sono state risequenziate copiandole, nell'ordine dovuto, in tabelle di transito che, dopo avere cancellato quelle d'origine, sono state rinominate ciascuna col suo nome originario. É stato finalmente un ottimo risultato che mi ha permesso praticamente di dimezzare il tempo di lettura e scrittura della tabelle.

Per completezza d'informazione riporto il concetto di risequenziazione vecchio:
1) lettura della 1a tabella del DB e scrittura della stessa, record dopo record, in una tabella transitoria
 
Codice: [Seleziona]
 Try RecTab = ApriDB.DBConnection.Exec("SELECT * FROM piancont ORDER BY NumVoce")
  If RecTab.Available = False Then
      Message.ERROR("Attenzione! ->  " & ERROR.Text & Chr(10) & Chr(10) & "durante la lettura della Tabella '" & ApriDB.$_DbNome & "!piancont'" & Chr(10) & Chr(10) & " il programma verrà chiuso")
      Quit
  Endif
  iId = 0
  For Each RecTab
      iId += 1
      Try ApriDB.DBConnection.EXEC("INSERT INTO piancont2 VALUES(" & RecTab!IdPiaCon & ", '" & RecTab!NumVoce & "', '" & RecTab!NomeVoce & "', '" & RecTab!ContrPartSiNo & "', '" & RecTab!DtPrimoUso & "')")
      If ( Error ) Then
          Message.ERROR("Attenzione!  ERRORE --> '" & ERROR.Text & "'" & Chr(10) & "alla riga " & Error.Where & Chr(10) & Chr(10) & "durante la registrazione della '" & ApriDB.$_DbNome & "!piancont2'" & Chr(10) & Chr(10) & Space$(30) & " IL PROGRAMMA VERRÀ CHIUSO")
          Quit
      Endif
 

2) svuotamento della tabella originaria e riscrittura della stessa coi record precedentemente inseriti nella tabella transitoria. Di questo passo riporto solamente l'istruzione di svuotamento della tabella originaria, perchè quella di scrittura è uguale a quella del passo1, coi nomi delle tabelle invertiti:
Codice: [Seleziona]
 Try ApriDB.DBConnection.EXEC("DELETE FROM piancont")  
3) cancellazione della tabella transitoria.

Il nuovo passo 2) è:
   
Codice: gambas [Seleziona]
 Try ApriDB.DBConnection.EXEC("DROP TABLE piancont")       'Cancellazione della Tabella 'ContabFamdb.piancont', a fine ordinamento
 If ( Error ) Then
        Message.ERROR("Attenzione!  ERRORE --> '" & ERROR.Text & "'" & Chr(10) & "alla riga " & Error.Where & Chr(10) & Chr(10) & "durante la cancellazione della tabella 'piancont' a fine riordino" & Chr(10) & Chr(10) & Space$(30) & " IL PROGRAMMA VERRÀ CHIUSO")
        Quit
    Endif
'------------------------------------------------------------------------------------------------------------------------------------------------------------
    ApriDB.DBConnection.Close
    ApriDB = New OpenDB
    ApriDB.DBConnection.EXEC("ALTER TABLE piancont2 RENAME To piancont")


Il tempo guadagnato è stato tantissimo, perchè attualmente il DB contiene circa 41000 record ed una sola tabella ne contiene 18000. Non sono tantissimi, ma la procedura di lettura e scrittura di quella più corposa impiega circa 35' . Ciò significa che prima della modifica il tempo di risequenziazione dei detta tabella era di circa: h 1:10:00. Sono perciò assai soddisfatto del grande risultato ottenuto ieri. ;D
 :ciao: