CISA FotoGallery

Statistiche

Tot. visite contenuti : 928358
Home Articoli tecnici Query e viste Query Parametriche con parametro flessibile

Query Parametriche con parametro flessibile

Query Parametriche:
Come si può passare ad una query parametrica un parametro in modo da filtrare dati Null
oppure NullString o a piacere...?

Partiamo dalla base di una Tabella così costituita:
ID PrimaryKey Counter
DESC Campo Descrizione Testo(255)

Scopo
Estrarre a piacimento tutti i Records potendo applicare questi criteri al campo
testo(DESC):

1) DESC= Null
2) DESC= NullString
3) DESC= CriterioTestuale (es: "abc")

Per farlo usiamo una Query Parametrica di questo tipo:

Nome Query: "Qry_SB" (prende il nome da chi ha sollecitato il problema)


SELECT * FROM Prova
WHERE (DESC=[Ricerca:]) Or
((DESC Is Null) And ([Ricerca:] Is Null)) Or
((DESC="") And ([Ricerca:]=""""));


Purtroppo la sola sintassi SQL non è in grado di risolvere il problema poichè
l'inghippo deriva da NullString che se passato tramite QBE viene reinterpretato
da JET, ma passandolo via codice deve essere un DoubleQuote, quindi """" oppure
si può usare il chr(34) affinchè non venga interpretato come NULL.

Da codice è comodo individuare se una stringa è Null oppure vbNullString, quindi
gestendo la condizione del raddoppio dei doppi apici in caso di vbNullString viene restituito il Record corretto.

CODICE

Dim varINPUT As variant
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset
' Assumiamo nella variabile di tipo VARIANT il parametro
varINPUT=Me!NomeTextBoxInserimentoCriterio
Set qdf = CurrentDb.QueryDefs("Qry_SB")
Select Case VarType(varINPUT)
    ' Nel caso sia NullString aplichiamo il DoubleQuote
    
Case vbEmpty
            varINPUT = """"
End select
' Passiamo il parametro alla Query
qdf.Parameters![Ricerca:] = varINPUT
Set rs = qdf.OpenRecordset
' Verifichiamo che il Recordset Risultante non sia vuoto
If rs.EOF And rs.BOF Then
        
MsgBox "Nessun Movimento per questo Cliente"
        Exit Sub
End If
Do
Untilrs.EOF
        Msgbox rs!id & " - " & rs!DESC
        rs.MoveNext
Loop
rs.Close


Al fine di ottimizzare i piani di esecuzione della Query e quindi di renderla più performante la modifichiamo in questo modo:

Nome Query: "Qry_SB"

SELECT * FROM Prova
WHERE (DESC=[Ricerca:])
UNION
SELECT * FROM Prova
WHERE ((DESC Is Null) And ([Ricerca:] Is Null))
UNION
SELECT * FROM Prova
WHERE ((DESC="") And ([Ricerca:]=""""));


Nota
Ricordo che la differenza prestazionale dalla query Standard vista inizialmente è aprezzabile solo in caso di una discreta mole di dati, ciò non toglie che possa essere usata sempre...!


Alessandro Baraldi