ho un piccolo problemino con l'sql....
allora il database
con
Public $conn As New Connection
Public sqliteName As String = "db"
Public sqlitePercorso As String = Application.Path
nel modulo gestisci_db
si crea
Public Sub controlladb()
If Not Exist(sqlitePercorso &/ sqliteName) Then
If Message.Question("Il database non esiste!, Lo creo?", "Si") = 1 Then
With $conn
.Type = "sqlite3"
.Host = sqlitePercorso
End With
$conn.Open
$conn.Databases.Add(sqliteName)
$conn.Close
$conn.Name = sqliteName
$conn.Open()
creatabella()
Endif
Endif
End
Public Sub creatabella()
Dim n As Byte
Dim sql As String
Dim htable As Result
sql = "CREATE TABLE 'db' ("
sql &= " 'id_db' INTEGER PRIMARY KEY,"
sql &= " 'nome' varchar(20) DEFAULT NULL,"
sql &= " 'cognome' varchar(20) DEFAULT NULL,"
sql &= " 'citta_n' varchar(30) DEFAULT NULL,"
sql &= " 'nato_il' varchar(15) DEFAULT NULL);"
hTable = $conn.Exec(sql)
$conn.Commit
$conn.Close
End
sempre nel modulo
ci si connette con
Public Sub Connect()
$conn.Close
$conn.Type = "sqlite3"
$conn.Host = sqlitePercorso
$conn.Name = sqliteName
$conn.Open
End
sempre nel modulo
ora io ho 2 form uno con tutta la tabella (una grossa gridview) e uno per inserire le nuove rige con le varie texbox etc...
e per caricare la tabella sulla grid si fà
Public Procedure riempi_grid()
Dim n As Integer
sql = "SELECT * FROM db"
MyRS = gestisci_db.$conn.Exec(sql)
grid_db.Clear
grid_db.Mode = Select.Multiple
grid_db.Header = grid_db.Both
grid_db.Columns.Count = 11 ''' 'imposta il numero di colonne della GridView1
grid_db.Columns[0].Text = "id" '' 'titolo prima colonna
grid_db.Columns[1].Text = "cognome"
grid_db.Columns[2].Text = "nome"
grid_db.Columns[3].Text = "città/paese natale"
grid_db.Columns[4].Text = "data di nascita"
If MyRS.Available = True Then
grid_db.Rows.Count = MyRS.Count 'imposta il numero di record in base al numero di risuktati presenti
n = 0
For Each MyRS
grid_db[n, 0].Text = MyRS!id_db 'inizio del ciclo
grid_db[n, 1].Text = MyRS!cognome '''
grid_db[n, 2].Text = MyRS!nome '''
grid_db[n, 3].Text = MyRS!citta_n
grid_db[n, 4].Text = MyRS!nato_il
Inc n
Next
Else
grid_db.Header = grid_db.None
grid_db.Columns.Count = 1
grid_db.Rows.Count = 1
grid_db[0, 0].Text = "Nessun dato" 'viene visualizzata la scritta "nessun dato"
Endif
End
in f_db
per riempire le text con i dati presi dal db
Public MyRS As Result
Public sql As String
Public Procedure riempi_caselle()
MyRS.MoveTo(c_var.send_row) 'la variabile che [u]in teoria[/u](sottolineato :D) contiene la riga cliccata
Print c_var.send_row
MyRS = gestisci_db.$conn.Exec(sql)
tb_cognome.Text = MyRS!cognome
tb_nome.Text = MyRS!nome
tb_citta_n.Text = MyRS!citta_n
tb_nato_il.Text = MyRS!nato_il
End
in f_nuovo
adesso
come vaccio a creare una nuova riga, sapere che riga è e comunicarlo all'altro form in modo che quando deve poi salvare sappia su quale riga.
quando si dblclick su una riga: come sapere su quale riga si è cliccato e a quale id corrisponde e comuncarlo all'altro form in modo che sappia dove deve poi andare a salvare
quando si salva come posso fare in modo che salvi sulla riga giusta?...
il problema principale è comunicare continuamente su quale riga si sta lavorando...
e da un bel pò di tentativi sono arrivato ad un punto morto....
spero di essermi spiegato... :D
:ciao:
P.S.
il database usato da me contiene più del triplo degli elementi.....
come vaccio a creare una nuova riga, sapere che riga è e comunicarlo all'altro form in modo che quando deve poi salvare sappia su quale riga.
quando si dblclick su una riga: come sapere su quale riga si è cliccato e a quale id corrisponde e comuncarlo all'altro form in modo che sappia dove deve poi andare a salvare
quando si salva come posso fare in modo che salvi sulla riga giusta?...
il problema principale è comunicare continuamente su quale riga si sta lavorando...
Cerco di rispondere con ordine alle 4 domande:
1) Mi sembra di capire che le righe della griglia riportano i record del DB. nella stessa sequenza di lettura dal DB. stesso, perciò
Per creare una nuova riga dovrai rilevare, se no lo sai già, il n° di righe componenti la glriglia:
ripetere l'istruzione di dichiarazione del n° di righe:
Per sapere qual'è l'ultima riga aggiunta basta togliere 1 a ITotRighe, in modo da sapere l'esatto puntamento alla riga di riferimento del momento.
La 2a parte della domanda è ripetuta nella domanda successiva, perciò rispondo dopo.
2) iNuRiga=grid_db.row 'estrai il n° di riga sulla quale hai cliccato (1 o 2 volte non importa).
Tieni conto poi che iNuriga sarà uguale al numero di riga, a partire dalla prima superiore, diminuita di uno (per riga n.8, InuRiga=7)
Per comunicare il contenuto di iNuriga all'altro Form devi solo scegliere:
1a) definire iNuriga come public nelle dichiarazioni della Form di partenza (Form1), di modo che da una procedura qualsiasi della Form n.2 puoi andarlo a prelevare con:
1b) dichiararare la variabile in un modulo come public in modo che sia vista da tutto il programma:
Public Sub Modulo_1()
Public iNuRiga as integer
End
In questo caso però nella Form contenente la griglia dovrai valorizzarla con
Modulo1.iNuRiga = rid_db.row
Per leggerla, farai:
1c) dichiarare la variabile in una nuova Classe come Public dove andrai a scrivere o leggere a tuo piacimento.
Nuova Classe = Variabili_Comuni
Public iNuRiga as integer
Public Function Usa_iNuRiga(VarInput)
iNuRiga = VarInput
End
Nella Form1 scriverai:
Variabili_Comuni.Usa_iNuRiga(rid_db.row)
mentre nella Form2, la leggerai con:
iIndRiga = Variabili_Comuni.iNuRiga
Per ora non dispongo di Gambas, quindi non ho potuto verificare tutto quanto ho scritto sopra, ma dovrebbe essere tutto come ho indicato.
3) Per salvare i dati sulla Riga corretta, devi riprendere, per es. il valore di Variabili_Comuni.iNuRiga.
Perciò nella Form1:
iRg = Variabili_Comuni.iNuRiga
grid_db[iRg,0] dato1
grid_db[iRg,1] dato2
--- bla --- bla --- bla ---
grid_db[iRg,n] daton
4) Per conoscere in quale riga sei posizionato, là dove ne avrai bisogno, non dovrai fare altro che ripetere l'istruzione vista nella risposta 2)
Se è tutto chiaro, vuol dire che ho risposto bene, se invece non dovesse essere così, ti conviene metterti a stuidiare un bel pò prima di ordinare il prossimo piatto.
;D ;D
:ciao:
P.S.
Un consiglio. Se e quando ti capiterà di affrontare più argomenti, spalmali in successione, risolvendoli uno dopo l'altro. Potrai ricevere risposte più ragionate e quindi più dettagliate. Questa volta ho sbagliato anch'io. Avrei dovuto rispondere solo alla prima domanda, già sufficientemente articolata, rimandando la discussione delle altre alla chiara conclusione della prima.
bene bene comincia a funzionare....
ma :D :D
quando vado a creare un nuovo record mi da
Query failed: Abort due to constraint violation
il codice relativo è
MyRS = gestisci_db.$conn.Exec("insert into db (id_db) values ('" & grid_db.Rows.Max & "');") '<-------
c_var.send_row = grid_db.Rows.Max
c_var.new = True
F_nuovo.Show
Me.Close
l'errore viene sollevato alla prima riga
myrs è il risultato
gestisci_db è un modulo
$conn è la connessione
db è il nome del database
id_db è l'indice del database
grid_db è una gridview
e solo se è il secondo record creato, per il primo non ci sono problemi....
grazie in anticipo
il commit lo fa nel momento in cui io salvo il vecchio record....
Public Sub btn_salva_Click()
Dim id As Integer
Print c_var.send_row
MyRS.MoveTo(c_var.send_row)
MyRS = gestisci_db.$conn.Edit("db", "id_db=" & c_var.send_row)
' If MyRS.Available = True Then
MyRS!id_db = c_var.send_row
MyRS!cognome = tb_cognome.Text ' salvo nel record selezionato i vari campi
MyRS!nome = tb_nome.Text
MyRS!citta_m = tb_citta_m.Text
MyRS!citta_n = tb_citta_n.Text
MyRS!madre = tb_madre.Text
MyRS!moglie = tb_moglie.Text
MyRS!morto_il = tb_morto_il.Text
MyRS!nato_il = tb_nato_il.Text
MyRS!padre = tb_padre.Text
MyRS!sposato_il = tb_sposato_il.Text
MyRS!varie = tb_varie.Text
MyRS.Update ' aggiorno
gestisci_db.$conn.Commit
gestisci_db.$conn.Close
'Endif
End
:-\ :-\
ho provato
Public Sub btn_nuovo_Click()
MyRS = gestisci_db.$conn.Exec("insert into db (id_db) values ('" & grid_db.Rows.Max & "');")
gestisci_db.$conn.Commit
gestisci_db.$conn.Close
c_var.send_row = grid_db.Rows.Max
c_var.new = True
F_nuovo.Show
Me.Close
End
Public Sub btn_nuovo_Click()
MyRS = gestisci_db.$conn.Exec("insert into db (id_db) values ('" & grid_db.Rows.Max & "');")
gestisci_db.$conn.Commit
c_var.send_row = grid_db.Rows.Max
c_var.new = True
F_nuovo.Show
Me.Close
End
Public Sub btn_nuovo_Click()
gestisci_db.$conn.Commit
MyRS = gestisci_db.$conn.Exec("insert into db (id_db) values ('" & grid_db.Rows.Max & "');")
c_var.send_row = grid_db.Rows.Max
c_var.new = True
F_nuovo.Show
Me.Close
End
ma con tutti e tre da sempre errore...
ma con
MyRS = gestisci_db.$conn.Exec("insert into db (nome) values (' ');")
quando salvo mi dice che il record non è disponibile...
con tutti e tre da sempre errore...
ma con
MyRS = gestisci_db.$conn.Exec("insert into db (nome) values (' ');")
quando salvo mi dice che il record non è disponibile...
Scusa se parto da lontano, ma mi serve per capire, perchè vedo che usi SQLite3 un pò diversamente da come sono abituato io, perciò non rieso a seguirti.
Qualche post fa hai spiegato che
db è il nome del database
id_db è l'indice del database
Ho visto anche che nell'istruzione CREATE
sql = "CREATE TABLE 'db' ("
sql &= " 'id_db' INTEGER PRIMARY KEY,"
hai assunto id_db come primary key, ma "primary key" non è un valore indice, bensì l'attribuzione di un vincolo alla colonna "id_db". Tale vincolo obbliga la condizione di univocità del dato contenuto nella cella in ciascuna riga, relativa alla colonna "id_db".
Per quello che posso capire, anche da quanto letto qui (http://www.sqlite.org/lang_createtable.html#constraints), nella sezione SQL Data Vincoli, sembrerebbe che nella 1a della griglia dalla quale prelevi i dati da trascrivere nella Tabella del DB. possa ritrovarti valori già presenti nella tabella interessata di DB, oppure ripetuti in una o più righe superiori della griglia (la riga 1 sta sopra la riga 2, quest'ultima sopra la 3 e così via).
Occorre perciò una tua verifica durante il debug del programma. Solo così puoi vedere a capire dove resiste l'anomalia.
Personalmente ti posso dire che a suo tempo ho rinunziato all'uso della primary key, perchè mi dava problemi, ora non ricordo quali. Ho preferito gestirmela io stesso manualmente con un codice Id numerico autoincrementale con progressione 1. Da allora mi trovo ottimamente e non ho avuto più difficoltà. Mi resta l'onere ogni tanto di risequenziare
le righe di ciascuna tabella del DB.
Fammi sapere.
:ciao:
ho modificato così
Public Sub creatabella()
Dim n As Byte
Dim sql As String
Dim htable As Result
sql = "CREATE TABLE 'db' ("
sql &= " 'id_db' varint(10) default null," ' con 0 non cambia niente
sql &= " 'nome' varchar(20) DEFAULT NULL,"
sql &= " 'cognome' varchar(20) DEFAULT NULL,"
sql &= " 'citta_n' varchar(30) DEFAULT NULL,"
sql &= " 'nato_il' varchar(15) DEFAULT NULL,"
sql &= " 'citta_m' varchar(30) DEFAULT NULL,"
sql &= " 'morto_il' varchar(15) DEFAULT NULL,"
sql &= " 'padre' varchar(20) DEFAULT NULL,"
sql &= " 'madre' varchar(20) DEFAULT NULL,"
For n = 1 To 20
sql &= " 'figlo_n_" & n & "' varchar(20) DEFAULT NULL,"
Next
sql &= " 'moglie' varchar(20) DEFAULT NULL,"
sql &= " 'sposato_il' varchar(20) DEFAULT NULL,"
sql &= " 'varie' varchar(100) DEFAULT NULL,"
sql &= " 'foto' varchar(500) DEFAULT NULL);"
hTable = $conn.Exec(sql)
$conn.Commit
$conn.Close
End
e al momento di salvare midà
Table 'db' has no primary key
in
Public Sub btn_salva_Click()
Dim id As Integer
Print c_var.send_row
MyRS.MoveTo(c_var.send_row)
MyRS = gestisci_db.$conn.Edit("db", "id_db=" & c_var.send_row)'<--------------------qui
' If MyRS.Available = True Then
MyRS!id_db = c_var.send_row
MyRS!cognome = tb_cognome.Text ' salvo nel record selezionato i vari campi
MyRS!nome = tb_nome.Text
MyRS!citta_m = tb_citta_m.Text
MyRS!citta_n = tb_citta_n.Text
MyRS!madre = tb_madre.Text
MyRS!moglie = tb_moglie.Text
MyRS!morto_il = tb_morto_il.Text
MyRS!nato_il = tb_nato_il.Text
MyRS!padre = tb_padre.Text
MyRS!sposato_il = tb_sposato_il.Text
MyRS!varie = tb_varie.Text
MyRS.Update ' aggiorno
gestisci_db.$conn.Commit
gestisci_db.$conn.Close
'Endif
End
comunque alla riapertura del programma la riga appena creata c'è... vuota...
al momento di salvare midà
Table 'db' has no primary key
Dalla tua citazione sono andato a riguardare i "Create" delle tabelle del mio DB, dove ho trovato definita la Primary Key, solo che a suo tempo ho aggiunto un ulteriore colonna ID, come prima colonna di ciascuna tabella. L'inserimento di ciascun record però lo gestisco io manualmente.
Scusa se ti ho dato un'indicazione non esatta, ma da quando ho generato il DB è passato qualche anno ed ho dimenticato come ho aggirato l'ostacolo.
Riporto qui il codice di creazione di una delle tabelle del DB e poi quello relativamente ad un inserimento di un nuovo record in una di esse. Tieni conto che mentre io eseguo "INSERT" da campi di memoria, tu lo fai prelevando i dati dalla GridView
1):
sql = "CREATE TABLE '" & $_NomeTab & "'" '*** Contiene i Conti e sottoconti di dettaglio utilizzabili nella procedura ***"
sql = sql & "('IdMovvgg' INTEGER PRIMARY KEY AUTOINCREMENT," 'codice id obbligato dalla struttura di SQLite3, ma inutile per questo DB
sql = sql & " 'DtCoMovgg' INTEGER,"
sql = sql & " 'DtSolMovgg' INTEGER,"
sql = sql & " 'OraSolMovgg' INTEGER,"
sql = sql & " 'NuProMovvgg' INTEGER,"
sql = sql & " 'CoVocMovvgg' INTEGER,"
sql = sql & " 'DescrMovvgg' VARCHAR(100) DEFAULT NULL,"
sql = sql & " 'MonMovvgg' CHAR(1) DEFAULT NULL,"
sql = sql & " 'ImpMovvgg' FLOAT ," '
sql = sql & " 'BenefMovvgg' CHAR(1) DEFAULT NULL"
sql = sql & " );"
Try ApriDB.DB_Connection.Exec(sql)
If ApriDB.DB_Connection.Error Then
Message.ERROR("Attenzione! -> Creazione Tabella 'ContabFamdb.movimgg' --> FALLITA" & Chr(10) & Chr(10) & "Cod.Erro= " & Error.Code & "»»" & ERROR.Text & Chr(10) & Chr(10) & "Il programma verrà chiuso")
Quit
Else
ApriDB.DB_Connection.Close
Endif
2): le prime righe costituiscono il metodo pensato per incrementare il valore della colonna ID, perchè deve essere necessariamente univoco.
ApriDB.DB_Connection.Begin
RecTab = ApriDB.DB_Connection.edit("movimgg")
If RecTab.Available Then
RecTab.MoveLast ' Legge lultimo record utile della tabella
iId = RecTab!IdMovvgg + 1
Else
iId = 1
Endif
sql = "INSERT INTO movimgg VALUES("
sql = sql & iId & ", '"
sql = sql & iDataCont & "', '"
sql = sql & i_Data & "', '" 'data solare di registrazione del movimento (aaaammgg)
sql = sql & i_orario & "', '" 'ora corrente di registrazione del movimento (hhmmss)
sql = sql & i_nupro & "', '"
sql = sql & iCoVoMovCorr & "', '"
sql = sql & $_Descr & "', '"
sql = sql & $TipoValuta & "', '"
sql = sql & fImpMov & "', '"
sql = sql & $_Benef & "')"
Try ApriDB.DB_Connection.EXEC(sql)
If ( Error ) Then
Message.ERROR("Attenzione! ERRORE --> '" & ERROR.Text & "'" & Chr(10) & "alla riga " & Error.Where & Chr(10) & Chr(10) & "durante l'inserimento di un nuovo record in Tab.movimgg" & Chr(10) & Chr(10) & Space$(30) & " IL PROGRAMMA VERRÀ CHIUSO")
bSwErro = True
Quit
Endif
Però se l'esempio che citi nella tua riflessione
ma un quesito mi resta...
io ho usato come programma di esempio bibliosqlite e lì si usa proprio
MyRS = gestisci_db.$conn.Exec("insert into db (nome) values (' ');")
e funziona perfettamente...
funziona, prima di abbandonare, perchè non insisti ancora un pò, guradando con più attenzione il codice riportato nell'esempio e raffrontandolo solamente per quanto riguarda la gestione della PRIMARY KEY la logica che risulta dal codice dell'esempio con quella applicata da te?
;)
Se posso più tardi o domani al massimo lo guardo anch'io quell'esempio.
:ciao: