Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1

    Delphi, errore nella Query di inserimento MariaDB

    Ciao,
    non riesco ad eseguire una semplice insert nel mio database creato con MariaDB e collegato con libreria Zeos in Delphi XE3 come consigliato da franzauker2.0.

    Tutto funziona davvero bene e riesco ad inserire nel campo del database una stringa scritta nella Query stessa, ma non riesco a far inserire il contenuto di un DBEdit.

    Premetto che il campo del DB è NOT NULL e il contenuto del DBEdit è ad esempio "ciao" e prendo in considerazione solo un campo del record della tabella clienti.


    with TZClienti do
    begin Active:=False;
    SQL.Clear;
    SQL.add('insert into clienti (codicefiscale) values ('+bcodicefiscale.Text+')');
    ExecSQL;
    end;


    Online trovo varie "ipotesi" che non mi portano al risultato che voglio:

    values (''bcodicefiscale.Text'')'); (Con questa sintassi mi dice che il campo codicefiscale non può contenere un testo così lungo, praticamente cerca di inserire il testo scritto tra gli apici e non il contenuto di TEXT)

    values (@dbcodicefiscale.Text)'); (con questa sintassi anche se il DBEdit è scritto mi dice che il campo codicefiscale non può essere NULL)

    ecc.....

    Solo nella sintassi scritta in corsivo mi da un messaggio strano, praticamente riconosce il contenuto di TEXT e mi dice che il la tabella del DB non ha una colonna chiamata "ciao", quindi non aggiunge il valore alla colonna codicefiscale, ma cerca una colonna chiamata "ciao".
    Come è possibile? Qual'è la sintassi giusta?

    Vorrei sapere anche la sintassi per inserire tutto il record (quindi inteso tutti i vari campi compilati nel DBgrid) senza dover specificare tutti i nomi dei campi e relativi valori.
    Grazie

  2. #2
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Francamente non è che abbia capito benissimo.
    Iniziamo a dire che il TDBGRID (collegato a una TABELLA) scrive i suoi dati tranquillamente senza necessità di dover far nulla.

    Se la domanda è "come inserisco i dati da codice" la risposta è:
    ci sono un 4 o 5 metodi.

    Se hai una TABELLA allora niente Insert e blablabla, bensì
    (supponiamo si chiami miatabella : Ttable o Tztable o quello che vuoi)
    codice:
    with miatabella do
    begin
        Append; // oppure edit
        fieldbyname('campo1').asstring:='ciao';
        fieldbyname('campo2').asinteger:=35;
        fieldbyname('campo3').asfloat:=100.3;
        Post; // ovviamente una cosa fatta bene prevede try...except
    end;
    Attenzione ai campi data (datetime), spesso - dipende dalla libreria - ti tocca fare una funzione data2datasql, che converte una TDATE (Delphi) in una stringa in formato adatto per SQL (tipicamente anno-mese-giorno).
    In questo caso (ZEOS) non dovrebbe essere necessario

    Le istruzioni INSERT (di SQL) non si specificano nelle TABELLE, bensì nelle QUERY (TZQUERY in particolare), se le hai.
    Anche qui ci sono 4 o 5 metodi diversi, personalmente creo la query sotto forma di stringa "vera", compilata di tutto.
    Ed ho una funzione XSQL che le esegue.
    Personalmente sconsiglio l'utilizzo di "sostituzioni volanti" per il semplice fatto che rendi molto più difficile il debug (è questione di abitudini); nel caso ti basta mettere nella XSQL un banale
    codice:
    if G_MODO_DEBUG then clipboard.astext:=querydaeseguire;
    Per avere negli appunti tutte le query che vengono eseguite.

    Se vuoi fare qualcosa di un pochino più furbo potresti anche utilizzare una funzione di query "universale" (non specifica di ZEOS)

    codice:
    procedure UNIXSQL(var i_tabellaQuery:Tobject;i_comandodiretto:string;i_silent:boolean=true);
    begin
       if i_tabellaQuery=nil then
       begin
         loggaErrore('ERRORE: itabellauqery NIL!',TRUE);
         exit;
       end;
       if uppercase(i_tabellaquery.classname)='TZQUERY' then
           ZXSQL(TZQuery(i_tabellaQuery),i_comandodiretto,i_silent);
    /// questi sono esempi con altre librerie di accesso a DB
    
       if uppercase(i_tabellaquery.classname)='TMYQUERY' then
           DACXSQL(TmyQuery(i_tabellaQuery),i_comandodiretto,i_silent);
    
       if uppercase(i_tabellaquery.classname)='TSOLCAZZOQUERY' then
           SOLCAZZOXSQL(TsolcazzoQuery(i_tabellaQuery),i_comandodiretto,i_silent);
    
    end;
    codice:
    procedure ZXSQL(var i_tabellaQuery:TZQuery;i_comandodiretto:string;i_silent:boolean=true);
    var	
       s:string;
       i:integer;
      cursore:tcursor;
    begin
    	
       cursore:=screen.cursor;
       Screen.Cursor := crHourGlass;
    
       try
    // questo è tristissimo, serve per raddoppiare le \
    // in realtà potresti fare anche un while con stringreplace
    // ma cambia poco
          s:='';
          for i:=1 to length(i_comandodiretto) do
           begin
             s:=s+i_comandodiretto[i];
             if i_comandodiretto[i]='barra-che-sparisce-scrivendo' then
                 s:=s+'barra-che-sparisce-scrivendo';
            end;
    
       i_comandodiretto:=s;
       {
       if G_MODO_DEBUG then
           clipboard.astext:=s;
           }
        with I_tabellaquery do
        begin
              if active then
                Close;
           SQL.Text:=i_comandodiretto;
           try
               if pos('SELECT',uppercase(trim(i_comandodiretto)))=1 then
                    open
               Else
                  ExecSQL;
    
           except
                 on E: Exception do
                   if not i_silent then
                   begin
                       frmgurumeditation.i_messaggio:='ZQUERY errata :'+sql.text+'|'+E.Message;
                       frmgurumeditation.showmodal;
    
                   end;
    
           end;
       end;
       except
       end;
       Screen.Cursor:=cursore;
    
    end;

  3. #3
    Grazie per l'esaustiva risposta...

    Allora..... ho su una form sia il DBGrid che i componenti DBEdit che utilizzo come campi per l'inserimento da parte di chi utilizza l'applicazione. Dopo aver inserito tutti i dati, l'utilizzatore cliccherà su un button per confermare l'inserimento nel DB quindi.

    Alla luce di quello che hai scritto, credo che vada bene questo tipo di metodo:

    with miatabella do
    begin
    Append; // oppure edit fieldbyname('campo1').asstring:='ciao'; fieldbyname('campo2').asinteger:=35;
    fieldbyname('campo3').asfloat:=100.3;
    Post; // ovviamente una cosa fatta bene prevede try...except
    end;
    Come posso far "azzerare" tutti i DBEdit che contengono inizialemente la riga selezionata nel DBGrid per poi permettere il nuovo inserimento? come posso spostare l'indice del DB dopo l'ultima riga?

    GRAZIE MAESTRO

  4. #4
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Originariamente inviato da gianni73na
    Grazie per l'esaustiva risposta...

    Allora..... ho su una form sia il DBGrid che i componenti DBEdit che utilizzo come campi per l'inserimento da parte di chi utilizza l'applicazione. Dopo aver inserito tutti i dati, l'utilizzatore cliccherà su un button per confermare l'inserimento nel DB quindi.
    Devi mettere un Tnavigator, o in alternaativa un bottone "salva".
    O meglio ancora un bottone salva che viene enablato quando c'è un cambio di stato nel datasource

    Supponi di voler mettere un bottone "salva" che è normalmente disabilitato, e che diventa abilitato (cliccabile) quando ci sono dati da salvare nel db.
    Allora farai qualcosa tipo
    codice:
    procedure tform1.btnSalvaClick(Sender: TObject);
    
    procedure PostaDataSet(i_dataset:TDataSet);
    begin
       if i_dataset=nil then exit;
       if (i_dataset.state=dsedit) or (i_dataset.state=dsinsert)  then
           i_dataset.Post;
    end;
    begin
      // esempio: salvo due dataset (faccio il POST) in un colpo solo
       PostaDataSet(dsrprimodatasource.dataset);
       PostaDataSet(dsrsecondodatasource.dataset);
       btnsalva.enabled:=False;
    end;
    Invece nel tdatasource (o NEI, plurale) nell'evento statechange metterai
    codice:
    procedure tform1.dsrnomedatasourceStateChange(Sender: TObject);
    begin
       if TDataSource(Sender).state=dsedit then
           btnsalva.enabled:=TRUE;
    end;
    In pratica quando "qualcosa" modifica il datasource (ad esempio sei in fase di editing di un record, o di aggiunta), viene "attivato" questo evento, che attiva (rende enabled) il bottone salva.

    Cliccando il bottone salva scriverai tutti i vari dataset che sono in stato edit o insert.
    Ovviamente è uno scheletro, poi sono fatti tuoi adattarlo alla situazione

    Come posso far "azzerare" tutti i DBEdit che contengono inizialemente la riga selezionata nel DBGrid per poi permettere il nuovo inserimento? come posso spostare l'indice del DB dopo l'ultima riga?
    Non puoi, ovviamente.
    Devi inserire un nuovo record.
    Che puoi fare in vari modi
    1) sempre col tnavigator
    2) mettendo un bottone "+" o "aggiungi nuovo record" nel quale metterai, nell'onclick, un brutale
    codice:
    Tabella.Append;

  5. #5
    Avevo già scritto la gestione del tasto SALVA (enabled o not enabled) senza il DBNavigator, però mentre con il DBNavogator clicco sul simbolo "+" e l'indice del DB sposta su una nuova riga per permettere l'inserimento di un nuovo record, se utilizzo il tasto BUTTON "+" o "NUOVO" e inserisco il codice Tabella.append mi compaiono ugualmente nei campi DBEdit, che dovrei popolare, tutti i valori presenti in quella posizione del DB (visibile nel DBGRID) e non campi vuoti.

    Insomma l'indice del DB, pur eseguendo l'istruzione APPEND non si sposta su una riga nuova....
    Come posso fare?

  6. #6
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Si sposta... si sposta...

  7. #7
    La parte di codice interessata è la seguente.

    codice:
    with TZQpazienti do
      begin
       append; 
       fieldbyname('codicefiscale').asstring:=dbcodicefiscale.Text;
       Post;
      end;
    la situazione di preciso è la seguente, sono riuscito a capire bene il problema per esporlo:

    I campi risultano compilati già con i dati di un paziente in archivio (quello sul quale sono posizionato) ma solo in maniera visuale infatti se non inserisco dati il Dataset risulta vuoto (pur avendo a video un DBEdit pieno.

    Se tra i campi già compilati ne modifico solo uno, il nuovo record che si crea avrà effettivamente solo un campo compilato e tutti gli altri vuoti; è come se i dati che risultano inseriti sono solo inseriti a video ma non nel DB alla posizione nuova.

    Confermo che con DBNavigator non ho questo problema, ma non vorrei usarlo.....
    Spero di essere riuscito a spiegare.........

  8. #8
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Originariamente inviato da gianni73na
    La parte di codice interessata è la seguente.

    codice:
    with TZQpazienti do
      begin
       append; 
       fieldbyname('codicefiscale').asstring:=dbcodicefiscale.Text;
       Post;
      end;
    dbcodicefiscale cos'è? Un TEdit o un TDBEdit?

  9. #9
    dbcodicefiscale cos'è? Un TEdit o un TDBEdit?
    è un TDBEdit... per questo non mi spiego il motivo di questa situazione e anche il DBGrid non si sposta dopo l'istruzione append o edit o insert.....

  10. #10
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Originariamente inviato da gianni73na
    è un TDBEdit... per questo non mi spiego il motivo di questa situazione e anche il DBGrid non si sposta dopo l'istruzione append o edit o insert.....
    Io invece me lo spiego, soprattutto se è relativo al medesimo dataset.
    prova con
    codice:
       append; 
       fieldbyname('codicefiscale').asstring:='antani';
       Post;

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.