Imprimir página | Cerrar ventana

Consultas con parámetros

Impreso de: Foro de Access y VBA
Categoría: Access y VBA
Nombre del foro: Tus Funciones Favoritas & Aportaciones & Artí­culos
Descripción del foro: Para publicar código interesante, aportaciones y artículos
URL: http://www.mvp-access.com/foro/forum_posts.asp?TID=77249
Fecha de impresión: 08/Abril/2020 a las 05:03


Tema: Consultas con parámetros
Publicado por: buho
Asunto: Consultas con parámetros
Fecha de publicación: 09/Agosto/2013 a las 23:14
Por Happy ( Juan Afán de Ribera)

Link Original: http://accessvbafaq.mvps.org/item.asp?pagina=25" rel="nofollow - http://accessvbafaq.mvps.org/item.asp?pagina=25

Y por éste falla en un futuro:

(En este pequeño artículo tomaré como ejemplo la tabla Pedidos de la base de datos Neptuno.mdb, que viene de "fábrica" con la instalación de Access)

A menudo aparece en los grupos de noticias una pregunta sobre alguien que tiene problemas a la hora de construir los criterios de una sentencia SQL, ya sea porque en esos criterios se utilizan fechas, o bien porque a lo mejor hay algún campo de texto que contiene una comilla simple, o tal vez porque hace servir campo de tipo doble (con su coma decimal, lo cual es interpretado erróneamente por el motor de base de datos como un separador de campos o argumentos)

En el caso de las fechas debemos saber que internamente Access sólo entiende el formato americano, es decir "mm/dd/yyyy". Pero el hecho es que nosotros estamos utilizamos el formato "dd/mm/yyyy". Un lío, vamos... Para evitar problemas debemos formatear nuestras fechas al formato americano.

Por ejemplo, construyamos una sentencia SQL con un criterio de selección basado en fechas:
SQL = "SELECT * FROM Pedidos " _
& "WHERE FechaPedido Between #" _
& Format("04-07-1996", "mm/dd/yyyy") _
& "# And #" & Format("06-05-1998", "mm/dd/yyyy") & "#"
Esa es una forma de resolverlo, pero si nuestra sentencia SQL es larga todo ese abrir y cerrar comillas, poner símbolos de almohadilla "#", etc, acaba llevándonos a cometer más de un fallo.

Otra situación en la que nos podemos encontrar es un campo de texto que contenga un apóstrofe (comilla simple). Por ejemplo:
sDestinatario = "B's Beverages"

SQL = "SELECT * FROM Pedidos " _
& "WHERE Destinatario = '" & sDestinatario & "'"
Esa sentencia producirá un error de "error de sintaxis, falta operador...". Para resolverlo debemos sustituir la comilla simple por un par de comillas, así:
sDestinatario = "B's Beverages"
' reemplazamos las comillas simples por un par 
' de comillas
sDestinatario = Replace(sDestinatario, "'", "''")

SQL = "SELECT * FROM Pedidos " _
& "WHERE Destinatario = '" & sDestinatario & "'"
Otro lío resuelto. Vamos a por el tercero:

Otro caso que se nos puede presentar es utilizar un criterio que usa un valor doble o moneda, cosa muy normal en un país que utiliza la coma como separador decimal. Pero lo que Access entiende es, otra vez, la configuación americana, es decir, la coma como separador de miles y el punto como separador decimal. Esta dificultad la resolveríamos de manera análoga a la anterior, pero en este caso reemplazaríamos la coma por un punto. Por ejemplo:
Dim nCargo As Double
Dim sCargo As String

    ' esto se representa en nuestra configuración
    ' regional como "100,01"
    nCargo = 100.01
    ' reemplazamos la coma por un punto
    sCargo = Replace(nCargo, ",", ".")
    SQL = "SELECT * FROM Pedidos " _
    & "WHERE Cargo > " & sCargo
Por fin hemos resuelto nuestros problemas. Ahora veamos una sentencia SQL que prevea las 3 circunstancias anteriores:
Dim SQL As String
Dim sDestinatario As String
Dim nCargo As Double
Dim sCargo As String

    sDestinatario = "B's Beverages"
    sDestinatario = Replace(sDestinatario, "'", "''")
    
    nCargo = 100.01
    sCargo = Replace(nCargo, ",", ".")
    
    SQL = "SELECT * FROM Pedidos " _
    & "WHERE FechaPedido Between #" _
    & Format("04-07-1996", "mm/dd/yyyy") _
    & "# And #" & Format("06-05-1998", "mm/dd/yyyy") & "#" _
    & " AND Destinatario = '" & sDestinatario & "'" _
    & " AND Cargo > " & sCargo

etc ...
Todo esto hará que nuestro código funcione correctamente.

Pero tenemos otra alternativa, en mi opinión, más limpia, elegante y rápida, y es dejar al motor Jet que haga el trabajo sucio y se encargue él de entenderse con los tipos de datos que necesita y nuestra configuración regional (que tantos dolores de cabeza nos ha causado).

Cogeremos el ejemplo que estábamos desarrollando y lo desarrollaremos dentro de una consulta con parámetros:
Dim SQL As String
Dim sDestinatario As String
Dim fecha1 As String, fecha2 As String
Dim nCargo As Double
Dim qdf As QueryDef
Dim rst As DAO.Recordset
    
    ' construimos una cadena de consulta con
    ' 4 parámetros
    SQL = "SELECT * FROM Pedidos " _
    & "WHERE FechaPedido Between parametro1 And parametro2 " _
    & "AND Destinatario Like parametro3 " _
    & "AND Cargo > parametro4"
    
    ' creamos una consulta temporal
    Set qdf = CurrentDb.CreateQueryDef("", SQL)
    
    ' damos valor a las variables con los datos
    fecha1 = "04-07-1996"
    fecha2 = "06-05-1998"
    sDestinatario = "B's Beverages"
    nCargo = 100.01
    
    ' damos valor a los parámetros, fijaros que
    ' no necesitamos encerrarlos entre "#" ni
    ' convertirlos al formato de fecha americano
    ' ni importará que un parámetro contenga una
    ' comilla simple o una coma como separador
    ' decimal . El motor Jet sabrá qué hacer
    ' en cada uno de los casos
    qdf.Parameters("parametro1") = fecha1
    qdf.Parameters("parametro2") = fecha2
    qdf.Parameters("parametro3") = sDestinatario
    qdf.Parameters("parametro4") = nCargo
    
    ' abrimos un recordset de la consulta
    Set rst = qdf.OpenRecordset
    While Not rst.EOF
        ' imprimimos los resultados
        Debug.Print rst!IdPedido, rst!Destinatario, _
                    rst!FechaPedido, rst!Cargo
        rst.MoveNext
    Wend
    
    rst.Close
    Set rst = Nothing
    Set qdf = Nothing
Pregunta : Es muy interesante lo que comentas... Pero yo estoy trabajando con ADO y me gustaría saber cómo desarrollar una consulta con parámetros en ADO ¿Podrías poner un ejemplo?
Respuesta : Naturalmente. Ahí tienes la misma consulta, pero desarrolada en ADO
Dim SQL As String
Dim sDestinatario As String
Dim fecha1 As String, fecha2 As String
Dim nCargo As Double
Dim cmd As ADODB.Command
Dim rst As ADODB.Recordset
    
    ' construimos una cadena de consulta con
    ' 4 parámetros
    SQL = "SELECT * FROM Pedidos " _
    & "WHERE FechaPedido Between parametro1 And parametro2 " _
    & "AND Destinatario Like parametro3 " _
    & "AND Cargo > parametro4"
    
    ' damos valor a las variables con los datos
    fecha1 = "04-07-1996"
    fecha2 = "06-05-1998"
    sDestinatario = "B's Beverages"
    nCargo = 100.01
    
    ' abrimos una nueva consulta
    Set cmd = New ADODB.Command
    With cmd
        .ActiveConnection = CurrentProject.Connection
        .CommandText = SQL
        .Parameters("parametro1") = fecha1
        .Parameters("parametro2") = fecha2
        .Parameters("parametro3") = sDestinatario
        .Parameters("parametro4") = nCargo
        ' abrimos un recordset de la consulta
        Set rst = .Execute
    End With
    
    While Not rst.EOF
        ' imprimimos los resultados
        Debug.Print rst!IdPedido, rst!Destinatario, _
                    rst!FechaPedido, rst!Cargo
        rst.MoveNext
    Wend
    
    rst.Close
    Set rst = Nothing
    Set cmd = Nothing


-------------
Por fin he hecho algo bueno, ser abuelo ¡y porque no lo he hecho yo!



Imprimir página | Cerrar ventana