Query pass through native di Access

di il
27 risposte

Query pass through native di Access

Buongiorno a tutti,

sto cercando di imparare l'uso delle query in oggetto, ma non riesco a costruire un predicato SQL dinamico che possa essere interpretato dal server esterno PostgreSQL.

Il collegamento al server funziona ed infatti se inserisco la stringa:

SELECT public.events.machine_id, public.events.order, public.events.start_time, public.events.duration, public.events.program FROM public.events where machine_id='1'

mi restituisce un recordset corretto.

Il problema e' se invece del valore '1' voglio associare un valore dinamico basato su un controllo ad opzioni; sto seguendo quanto scritto nel post seguente:

https://www.iprogrammatori.it/forum-programmazione/access/ricerca-tabelle-collegate-t47714.html

Nell'esempio @Alex mostra come costruire la stringa passando il valore dell'oggetto e non l'oggetto stesso, ma l'esempio e' sviluppato con VBA, mentre l'interfaccia nativa della query PT espone una finestra dove scrivere la stringa SQL; ho fatto diversi tentativi ma senza risultato. Nello specifico:


SELECT public.events.machine_id, public.events.order, public.events.start_time, public.events.duration, public.events.program FROM public.events where machine_id= '" & [Forms]![frmGMgiornalieromacchine]![frmGMOPselezionemacchina] & "'

Restituisce un recordset vuoto

SELECT public.events.machine_id, public.events.order, public.events.start_time, public.events.duration, public.events.program FROM public.events where machine_id= '& [Forms]![frmGMgiornalieromacchine]![frmGMOPselezionemacchina] & '

Anche qui restituisce un recordset vuoto

SELECT public.events.machine_id, public.events.order, public.events.start_time, public.events.duration, public.events.program FROM public.events where machine_id=" & [Forms]![frmGMgiornalieromacchine]![frmGMOPselezionemacchina] & "

Questa da errore perche' non trova la colonna " & [Forms]![frmGMgiornalieromacchine]![frmGMOPselezionemacchina] & "

Di seguito la Query pass through

[img]https://i.imgur.com/2N85Wxt.jpeg[/img]

Sto sbagliando io a costruire la stringa (molto probabile) o forse l'interfaccia della query PT non e' in grado di estrapolare il valore dall'oggetto?

27 Risposte

  • Re: Query pass through native di Access

    La QPT Può essere parametrica, usando Parameters, oppure accedi alla proprietà SQL di Queeydef e cambi il costrutto.

  • Re: Query pass through native di Access

    27/11/2024 - @Alex ha scritto:

    La QPT Può essere parametrica, usando Parameters, oppure accedi alla proprietà SQL di Queeydef e cambi il costrutto.

    Buongiorno @Alex, l'interfaccia nativa di Access per le QPT non permette l'inserimento di parametri. Come vedi nell'immagine allegata, il comando e' disabilitato.

    https://imgur.com/DFQduL8

    Probabilmente dovro' passare da VBA...

  • Re: Query pass through native di Access

    eppure era molto chiaro...

    Dim qdf As DAO.Recordset
    Dim sSQL As String
    sSQL="SELECT * FROM T1 WHERE Codice=" & [Forms]![Articoli]![cercacodice]
    CurrentDb.QueryDefs("Q1").SQL=sSQL

    sostituisci 

    "select bla bla..." 

    con la tua select e 

    [Forms]![Articoli]![cercacodice] 

    con 

    [Forms]![frmGMgiornalieromacchine]![frmGMOPselezionemacchina]

  • Re: Query pass through native di Access

    Giusto per escludere l'errore banale: la maschera è aperta al momento dell'uso della query? Se nella finestra immediata scrivi

    ? [Forms]![frmGMgiornalieromacchine]![frmGMOPselezionemacchina]

    cosa ottieni?

    (Machine_id è testo? l'hai messo tra apici)

  • Re: Query pass through native di Access

    27/11/2024 - sihsandrea ha scritto:

    eppure era molto chiaro...

    Non ho detto che non e' stato chiaro, so come si scrive una stringa SQL in VBA...

    il problema e' che nell'interfaccia di Access per la QPT non la accetta scritta in quel modo...

  • Re: Query pass through native di Access

    27/11/2024 - Philcattivocarattere ha scritto:

    cosa ottieni?

    (Machine_id è testo? l'hai messo tra apici)

    In base all'opzione che seleziono ottengo un numero da 1 a 7.

    Il campo machine_id e' un campo varchart (quindi testo): devo formattare il valore del mio controllo?

  • Re: Query pass through native di Access

    Ma cosa dici...?

    Si usa il VBA, si crea un predicato SQL con tanto di PARAMETER non la where conditon solamente PARAMETER... è un oggetto DAO...poi apri la query e che sia standard quindi LOCALE o PassTrough con connessione si passa il parametro e si recupera il recordset...

    Sei certo di aver cercato bene...?

    Dim qdf As DAO.QueryDef
    Dim rst As DAO.Recordset
    Dim Sql As String 
    
    Set qdf = CurrentDb.CreateQueryDef("")
    qdf.Connect = "ODBC;Driver=SQL Server;Server=.\SQLEXPRESS;Trusted_Connection=Yes;"
    Sql="PARAMETERS [EnterID] Long;"
    Sql=Sql+"Select * FROM T1 WHERE ID=[EnterID]"
    qdf.SQL = Sql
    qdf.Parameters("EnterID")=TuoValore
    qdf.ReturnsRecords = True
    Set rst = qdf.OpenRecordset
    '..... qui hai il rs con i dati
    '..... ci giochi e lo chiudi 
    rst.Close
    Set rst = Nothing
    Set qdf = Nothing

    Ad esempio....

  • Re: Query pass through native di Access

    Con un po' di ritardo posto la soluzione che ho adottato (non me ne voglia @Alex ma ho optato per una stringa SQL senza parametri ma passando direttamente i valori di filtro presi dalla form, debitamente formattati):

    Private Sub frmGMcmdesegui_Click()
    On Error GoTo Err_frmGMcmdesegui_Click
    Dim strsql As String
    Dim strcnn As String
    
        If Me.frmGMctrtxtdatainizioperiodo.Value = Null Then
            MsgBox "Inserire Data Inizio Periodo", vbOKOnly
            Me.frmGMctrtxtdatainizioperiodo.SetFocus
            GoTo Exit_frmGMcmdesegui_Click
        ElseIf Me.frmGMctrtxtdatafineperiodo.Value = Null Then
            MsgBox "Inserire Data Fine Periodo", vbExclamation, vbOKOnly
            Me.frmGMctrtxtdatafineperiodo.SetFocus
            GoTo Exit_frmGMcmdesegui_Click
        End If
        
        strcnn = "ODBC;DSN=PostgreSQL30;SERVER=***.***.***.***;PORT=****;Database=***;UID=***;PWD=***;"
        
        strsql = "SELECT public.events.id, public.events.machine_id, public.events.order, to_char(public.events.start_time,'DD/MM/YYYY') as datainizio, SUM(public.events.duration) as durata, public.events.value, public.events.program " & _
        "FROM public.events WHERE public.events.machine_id='" & frmGMOPselezionemacchina & "'"
        
        strsql = strsql & " and public.events.start_time>='" & Format$(frmGMctrtxtdatainizioperiodo, "YYYY/MM/DD") & "'"
        
        strsql = strsql & " and public.events.start_time<'" & Format$(frmGMctrtxtdatafineperiodo + 1, "YYYY/MM/DD") & "'"
        
        strsql = strsql & " GROUP BY public.events.id, public.events.machine_id, public.events.value, to_char(public.events.start_time,'DD/MM/YYYY'), public.events.order, public.events.program"
        
        strsql = strsql & " ORDER BY public.events.id DESC"
        Call ExecuteSPT(strsql, strcnn)
        
    Exit_frmGMcmdesegui_Click:
        Exit Sub
    
    Err_frmGMcmdesegui_Click:
        MsgBox Err.Number & " " & Err.Description
        Resume Exit_frmGMcmdesegui_Click
        
    End Sub
    
    Function ExecuteSPT(sqltext As String, connectstring As String)
                            ' Esegue query pass-through temporanea
                            ' Argomenti della funzione: sqltext: Stringa SQL da eseguire, connectstring: Stringa di connessione al DB esterno
    
    Dim mydb As DAO.Database, myq As DAO.QueryDef
    
    Set mydb = CurrentDb
        On Error Resume Next
        Set myq = mydb.QueryDefs("qryPTGMgiornalieromacchineappoggio")
        If Err.Number <> 0 Then
        Set myq = mydb.CreateQueryDef("qryPTGMgiornalieromacchineappoggio")
        End If
        On Error GoTo 0
    
    myq.Connect = connectstring
    
    myq.SQL = sqltext
    myq.ReturnsRecords = True
    DoCmd.OpenQuery ("qryPTGMgiornalieromacchine")
    Set mydb = Nothing
    Set myq = Nothing
    
    End Function
  • Re: Query pass through native di Access

    Lo sai che i PARAMETERS evitano, formattazioni e SQL INJECTION...? per il resto se sei contento tu...

  • Re: Query pass through native di Access

    X @Mailman: Personalmente avrei cercato di implementare quanto consigliato da @Alex non fosse altro che è una tra le persone più preparate del forum per l'argomento Access.

    Non so in quale ambiente devi usare l'applicazione e se puoi fidarti ciecamente degli utenti ma in linea generale l'applicativo in questione potrebbe essere a rischio SQL Injection come giustamente ti ha fatto notare @Alex. L'utilizzo dei parametri è la prima difesa in tal senso.

    Tempo fa avevo pubblicato un articolo che spiega cosa sono le SQL Injection:

    https://www.iprogrammatori.it/articoli/cyber-security/sql-injection-cosa-sono-come-difendersi-consigli-utili

    Se poi l'argomento è già di tua conoscenza e sai che nel tuo contesto di utilizzo non ci sono rischi, meglio così.

  • Re: Query pass through native di Access

    Ho provato a testare la soluzione suggerita da @Alex ma ottengo un errore quando passo i parametri della query: "Errore di run-time '3265': Elemento non trovato in questa raccolta".

    Di seguito il codice che utilizzo, ho evidenziato dove da' errore:

    ...
    Dim mydb As DAO.Database, myq As DAO.QueryDef
    Dim strsql As String
    
    ...
        
        Set mydb = CurrentDb
        On Error Resume Next
        Set myq = mydb.QueryDefs("qryPTGMgiornalieromacchineappoggio")
        If Err.Number <> 0 Then
        Set myq = mydb.CreateQueryDef("qryPTGMgiornalieromacchineappoggio")
        End If
        On Error GoTo 0
        
    	myq.Connect = "ODBC;DSN=PostgreSQL30;SERVER=192.168.0.99;PORT=5432;Database=costamp_prod;UID=costamp_edit;PWD=CostampSecret!;"
    	
        strsql = "PARAMETERS [intmacchina] integer,[dateinizio] date,[datefine] date; "
        
        strsql = strsql + "SELECT public.events.id, public.events.machine_id, public.events.order, to_char(public.events.start_time,'DD/MM/YYYY') as datainizio, SUM(public.events.duration) as durata, public.events.value, public.events.program " & _
        "FROM public.events WHERE public.events.machine_id=[intmacchina]"
        
        strsql = strsql & " and public.events.start_time>=[dateinizio]"
        
        strsql = strsql & " and public.events.start_time<([datefine]+1)"
        
        strsql = strsql & " GROUP BY public.events.id, public.events.machine_id, public.events.value, to_char(public.events.start_time,'DD/MM/YYYY'), public.events.order, public.events.program"
        
        strsql = strsql & " ORDER BY public.events.id DESC"
        
        myq.SQL = strsql
        myq.Parameters("intmacchina") = Me.frmGMOPselezionemacchina.Value
        myq.Parameters("dateinizio") = Me.frmGMctrtxtdatainizioperiodo.Value
        myq.Parameters("datefine") = Me.frmGMctrtxtdatafineperiodo.Value
    
        myq.ReturnsRecords = True
        DoCmd.OpenQuery ("qryPTGMgiornalieromacchineappoggio")

    Cosa sto sbagliando?

    Grazie in anticipo

  • Re: Query pass through native di Access

    Sei certo di aprire la Query nel modo corretto...? Come ti avevo scritto sopra...? Vedo un OpenQuery che non ha alcun senso...!!!

  • Re: Query pass through native di Access

    La soluzione suggerita da' lo stesso errore nello stesso punto: "myq.Parameters("intmacchina") elemento non trovato in questa raccolta"

    Set myq = CurrentDb.CreateQueryDef("")
    
        myq.Connect = "ODBC;DSN=PostgreSQL30;SERVER=192.168.0.99;PORT=5432;Database=costamp_prod;UID=costamp_edit;PWD=CostampSecret!;"
        
        strsql = "PARAMETERS [intmacchina] integer,[dateinizio] date,[datefine] date; "
        
        strsql = strsql + "SELECT public.events.id, public.events.machine_id, public.events.order, to_char(public.events.start_time,'DD/MM/YYYY') as datainizio, SUM(public.events.duration) as durata, public.events.value, public.events.program " & _
        "FROM public.events WHERE public.events.machine_id=[intmacchina]"
        
        strsql = strsql & " and public.events.start_time>=[dateinizio]"
        
        strsql = strsql & " and public.events.start_time<([datefine]+1)"
        
        strsql = strsql & " GROUP BY public.events.id, public.events.machine_id, public.events.value, to_char(public.events.start_time,'DD/MM/YYYY'), public.events.order, public.events.program"
        
        strsql = strsql & " ORDER BY public.events.id DESC"
        
        myq.SQL = strsql
        myq.Parameters("intmacchina") = Me.frmGMOPselezionemacchina.Value
        myq.Parameters("dateinizio") = Me.frmGMctrtxtdatainizioperiodo.Value
        myq.Parameters("datefine") = Me.frmGMctrtxtdatafineperiodo.Value
    
        myq.ReturnsRecords = True
        Set rst = myq.OpenRecordset
        rst.Close
        Set myq = Nothing
  • Re: Query pass through native di Access

    Il Type del campo Data nelle Tabelle, e quindi dei Parameter... sei sicuro sia Date...?

    Prova con:

    strsql = "PARAMETERS [intmacchina] integer,[dateinizio] DateTime,[datefine] DateTime; "
Devi accedere o registrarti per scrivere nel forum
27 risposte