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

    [DELPHI]passare parametri in una query

    Ciao a tutti!
    Uso un db Firebird e i componenti dbExpress per l'accesso ai dati.
    Ho scelto il SimpleDataset e un DBGrid per visualizzare i risultati di una query select sul mio db. In questa query ho due parametri il cui valore viene determinato dinamicamente tramite la scelta di un valore in due combobox diverse (cmbArgomento e cmbLettera).
    Fino ad adesso sto lavorando solo tramite le proprietà elencate nell'Object Inspector.
    Per il componente SimpleDataset ho quindi inserito questa query (proprietà Dataset->CommandText)
    codice:
    select * from TB_INDICE_PAGINE where PAGINA_ARGOMENTO=:argomento and PAGINA_LETTERA=:lettera
    poi in Dataset->(TParams) ho creato due parametri:
    1)argomento (Value:cmbArgomento.KeyField)
    2)lettera (Value:cmbLettera.KeyField)
    Il tutto mi dà errore quando cerco di compilarlo:
    "Application Error
    Exception EOLEException in module...exe at 000DB3E1.
    Database Server Error:Incorrect values within SQLDA structure."
    Con la proprietà KeyField pensavo di estrarre l'indice corrispondente al valore selezionato nella combobox, ma forse così non va. O l'errore è da un'altra parte? (Ho fatto già innumerevoli prove...)Grazie mille!

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,296
    Se hanno la proprietà KeyField, allora suppongo che si tratti di controlli DBLookupComboBox.

    La proprietà KeyField è di tipo TField ed è un riferimento al campo da cui viene estratto il valore usato per le assegnazioni al campo FieldName della tabella cui fa riferimento il componente nella proprietà DataSource.

    Quando si lavora con controlli "data aware", quindi tutti i controlli appartenenti alla pagina Data Controls della Palette dei Componenti (o Toolbox), in genere si ottengono sempre i dati selezionati, visualizzati o elencati (a seconda del controllo) facendo riferimento al DataSet cui questi "puntano" tramite la proprietà DataSource.

    Se, ad esempio, il controllo TDBLookupComboBox ha le proprietà ListSource, KeyField e ListField assegnate, provvederà ad elencare i valori provenienti dalla tabella collegata al componente in ListSource, visualizzando i valori del campo ListField nell'elenco; selezionare uno dei valori dell'elenco significa far spostare il puntatore del record della tabella collegata a ListSource sul record corrispondente al valore selezionato; basterà quindi accedere a quella tabella per conoscere tale valore, oppure il valore di un altro campo usando il metodo FieldByName.

    In sostanza, quando viene selezionato un valore nella casella, il record corrente nel DataSet cui fa riferimento il ListSource è quello selezionato; basta usare il metodo FieldByName del DataSet per ottenere i valori dei campi.

    In linea di massima, quindi, si utilizzano sempre e solo i DataSet per ottenere i dati, poichè lo stato dei componenti che rappresentano la sorgente dei dati varia in base alle selezioni e alle operazioni effettuate sui controlli "data aware" ad essi agganciati.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Ti ringrazio per aver mi risposto
    Ma non potresti essere un pochino più chiaro visto che io è da poco che mi sto addentrando in questo linguaggio di programmazione. Ho letto e riletto il tuo post...
    Comunque è vero che si tratta di TDBLookupCombobox dove ho inserito il legame con il Datasource corrispondente tramite le proprietà ListSource, ListField e KeyField. Per quello pensavo che il parametro da inserire nella query select che prelevava i valori selezionati nelle combobox per estrarre un nuovo dataset fosse corrispondente al KeyField (l'Id della tabella cui si riferisce la combo). Dal tuo discorso non capisco dove è lo sbaglio.

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,296
    Originariamente inviato da vicky
    Ma non potresti essere un pochino più chiaro visto che io è da poco che mi sto addentrando in questo linguaggio di programmazione. Ho letto e riletto il tuo post...
    Più chiaro e dettagliato non potevo essere.
    Cercherò di essere invece più pratico.

    Originariamente inviato da vicky
    Comunque è vero che si tratta di TDBLookupCombobox dove ho inserito il legame con il Datasource corrispondente tramite le proprietà ListSource, ListField e KeyField. Per quello pensavo che il parametro da inserire nella query select che prelevava i valori selezionati nelle combobox per estrarre un nuovo dataset fosse corrispondente al KeyField (l'Id della tabella cui si riferisce la combo). Dal tuo discorso non capisco dove è lo sbaglio.
    KeyField contiene, appunto, un riferimento ad un campo che viene utilizzato dalla ComboBox per i propri scopi, e non il valore del campo che ti serve.

    Quando selezioni un valore dalla ComboBox, selezioni di conseguenza anche un determinato record dal DataSet cui il ComboBox è collegato attraverso il DataSource specificato nella proprietà ListSource.

    Se ListSource punta, in definitiva, ad un DataSet da cui vengono prelevati i valori da elencare, a fronte di una selezione dalla ComboBox avrai nel DataSet la selezione (lo spostamento del cursore del record corrente) su tale record.

    In sostanza, ti basta quindi usare
    codice:
    SelectedID := ListSourceSimpleDataSet.FieldByName('ID').AsInteger;
    per ottenere il valore del campo ID per il record corrente del DataSet cui punta la proprietà ListSource (attraverso il DataSource) della ComboBox; il record corrente sul DataSet corrisponde alla selezione nella ComboBox.

    Riepilogando, il DataSet contiene i dati da elencare; attraverso il componente TDataSource e la proprietà ListSource della TDBLookupComboBox, indichi al controllo dove prelevare i dati da elencare; quando viene fatta una selezione dalla casella, viene anche selezionato il record corrispondente nel DataSet sorgente menzionato prima; basta usare FieldByName e specificare il campo desiderato per ottenere il valore in merito al record selezionato da utilizzare per altri scopi.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  5. #5
    Chiarissimo! Quindi ho inserito questa stringa
    codice:
    dsLettere.FieldByName('Lettera_id').AsInteger
    nel campo Value del Parametro 'Lettera' riferito alla query nel dataset "finale" (che nel mio caso si chiama 'Immagini').
    La query è:
    codice:
    select * from TB_INDICE_PAGINE where Pagina_lettera=:Lettera
    Però quando cerco di attivare il Dataset Immagini ottengo un errore che dice:
    Could not convert variant of type (OleStr)into type (Boolean).
    Cosa potrebbe significare?

  6. #6
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,296
    Il fatto che subentri un Boolean mi preoccupa.

    Non userei la proprietà Value di tipo Variant, in generale, ma piuttosto le proprietà di accesso AsXXX.

    codice:
    Query.ParamByName('NAME').AsInteger := Table.FieldByName('NAME').AsInteger;
    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  7. #7
    Allora, ho cancellato nell'ObjectInspector il Parameter 'Lettera', poi sono andata nel codice ed ho scritto in corrispondenza del pulsante "Invio" questa stringa:
    codice:
     ElencoLettere.Params.ParamByName('Lettera_id').AsInteger := ElencoLettere.FieldByName('Lettera_id').AsInteger;
    Pensando di sbagliare ho anche provato con Lettera_nome al posto di Lettera_id ( ) ma il risultato è sempre il medesimo:
    Il messaggio di errore è:
    Could not convert variant of type (OleStr)into type (Boolean).
    In realtà tu avevi scritto
    Query.ParamByName('NAME').AsInteger := Table.FieldByName('NAME').AsInteger;
    ma non ho capito se al posto di Query dovevo mettere il mio dataset (ElencoLettere)oppure no.
    Hai ancora un po' di pazienza?

  8. #8
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,296
    C'è un po' di confusione...

    In primo luogo, attraverso l'Object Inspector si dovrebbero solamente "valorizzare" i parametri (Params) nel caso in cui serva per fare test in fase di progettazione (non in fase di esecuzione), ma non andrebbero mai cancellati, poichè credo tra l'altro sia un'operazione ininfluente dato che essi vengono generati dinamicamente dall'interpretazione della query SQL impostata sul componente.

    In secondo luogo, dal codice che hai postato, stai facendo riferimento sempre alla stessa tabella cui assegni come valore del parametro da usare per la query un valore che proviene dal record selezionato nella tabella stessa, il ché non ha apparentemente molto senso.


    Suppongo che tu, in realtà, abbia a che fare con due tabelle logiche, una che elenca record da visualizzare e una seconda che, invece, fornisce altri record da cui occorre estrarre un determinato valore selezionato che funga da filtro sulla prima.

    Ciò che devi fare, quindi, è impostare il parametro che determina il filtro sulla prima query al valore proveniente dalla seconda tabella (o query, è ininfluente, si tratta sempre di un recordset di dati, o DataSet) che, eccezionalmente, ha come record corrente quello selezionato attraverso una DBLookupComboBox poichè quest'ultima è collegato alla tabella per via della proprietà ListSource e di un componente intermediario TDataSource.

    Riassumendo, devi avere due tabelle, o query, o DataSet che dir si voglia, A e B, di cui il primo (A) attinge dati attraverso una query parametrica e il secondo (B) fornisce un altro elenco di dati da cui prelevare una chiave per filtrare la prima.

    Ciò che va fatto, in sostanza, è aprire la seconda tabella B da cui selezionare un record attraverso la DBLookupComboBox collegata; in seguito, assegnare al parametro corrispondente del filtro nel primo DataSet (A) il valore ottenuto dal DataSet secondario (B) ed aprire il primo DataSet (A) ottenendo i dati che soddisfano la query in base al parametro specificato, con una sintassi simile alla seguente:
    codice:
    DataSetA.ParamByName('PARAMETRO').AsInteger := DataSetB.FieldByName('ID').AsInteger;
    DataSetA.Open;
    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  9. #9
    Direi che con un parametro funziona.
    Aggiungo il secondo parametro in questo modo:
    codice:
    Immagini.Params.ParamByName('Lettera').asInteger:=ElencoLettere.FieldByName('LETTERA_ID').asInteger;
      Immagini.Params.ParamByName('Argomento').asInteger:=ElencoArgomenti.FieldByName('ARGOMENTO_ID').asInteger;
      Immagini.open;
    Poi la query del Dataset A la trasformo così:
    codice:
    select * from TB_INDICE_PAGINE where PAGINA_LETTERA=:Lettera and PAGINA_ARGOMENTO=:Argomento
    Quando vado in esecuzione e seleziono Lettera ed Argomento dalle combobox ottengo
    "Immagini:Parameter 'Argomento' not found!"
    Come è possibile? Forse con due parametri bisogna cambiare il codice e non basta aggiungere la stringa per il secondo parametro?

  10. #10
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,296
    La query e l'impostazione mi sembrano corrette.

    Forse hai accidentalmente cancellato un parametro, quello che hai detto di aver rimosso nel messaggio precedente.

    Prova a verificare questa condizione.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

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 © 2024 vBulletin Solutions, Inc. All rights reserved.