C/Visual C - Querys con parametros variables

 
Vista:

Querys con parametros variables

Publicado por Wolfgang Kling (2 intervenciones) el 04/10/2002 03:37:39
Por favor, si alguien me puede colocar un codigo de ejemplo de lo siguiente.

1) Utilizacion del metodo CDatabase::ExecuteSQL con un query con parametros variables, que no sean concatenados mediante cadenas. Quiero poder ejecutar sentencias UPDATE y DELETE sin hacerlo a traves del Recordset y con parametros variables.

2) Utilizacion del la clase CRecordset con parametros variables. Se que debo definirle unos nuevos atributos que representen cada uno un parametro. Pero que pasa si a veces le debo mandar un query con 3 parametros y luego otro con 5 y no son del mismo tipo?. Los atributos para cada parametro no me servirian.

Si existe alguna forma diferente de hacer esto sera bien recibida.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Alejandro

Ejemplos de uso de CDatabase::ExecuteSQL y CRecordset con parámetros variables

Publicado por Alejandro (913 intervenciones) el 24/03/2025 21:42:41
Wolfgang, aquí tienes ejemplos de código para cada uno de los casos que mencionaste, utilizando MFC y ODBC en C++.

1) Utilización del método `CDatabase::ExecuteSQL` con un query con parámetros variables



Para ejecutar sentencias `UPDATE` y `DELETE` sin usar `CRecordset` y sin concatenar cadenas, puedes utilizar parámetros en una consulta SQL. Sin embargo, `CDatabase::ExecuteSQL` noadmite parámetros directamente. En su lugar, puedes usar `CRecordset` para ejecutar consultas parametrizadas. Aquí hay un ejemplo de cómo hacerlo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <afxdb.h> // Asegúrate de incluir la biblioteca de MFC para bases de datos
 
void ejecutarConsultaConParametros(CDatabase& db, const CString& sql, const CString& param1, const int param2) {
    CRecordset recordset(&db);
    recordset.m_nFields = 0; // No necesitamos campos para UPDATE/DELETE
 
    // Preparamos la consulta
    recordset.m_strSQL.Format(sql, param1, param2);
 
    // Ejecutamos la consulta
    if (recordset.Open(CRecordset::dynaset) == FALSE) {
        AfxMessageBox(_T("Error al abrir el recordset."));
        return;
    }
 
    // Cerrar el recordset
    recordset.Close();
}
 
// Ejemplo de uso
void ejemploUso() {
    CDatabase db;
    db.OpenEx(_T("DSN=mi_dsn;UID=usuario;PWD=contraseña;"));
 
    // Ejecutar un UPDATE
    ejecutarConsultaConParametros(db, _T("UPDATE MiTabla SET Columna1 = ? WHERE Columna2 = ?"), _T("NuevoValor"), 123);
 
    // Ejecutar un DELETE
    ejecutarConsultaConParametros(db, _T("DELETE FROM MiTabla WHERE Columna2 = ?"), 123);
 
    db.Close();
}

2) Utilización de la clase `CRecordset` con parámetros variables



Para manejar consultas con un número variable de parámetros, puedes usar un enfoque más flexible. Una opción es definir un solo atributo para cada tipo de parámetro y luego usar un método para establecer los valores según el tipo de consulta que estés ejecutando. Aquí hay un ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <afxdb.h>
 
class MiRecordset : public CRecordset {
public:
    CString m_parametro1; // Para el primer parámetro
    int m_parametro2;     // Para el segundo parámetro
    double m_parametro3;  // Para el tercer parámetro
 
    MiRecordset(CDatabase* pDatabase) : CRecordset(pDatabase) {}
 
    virtual CString GetDefaultSQL() { return _T("SELECT * FROM MiTabla WHERE Columna1 = ? AND Columna2 = ?"); }
 
    virtual void DoFieldExchange(CFieldExchange* pFX) {
        // Intercambiar los campos
        RFX_Text(pFX, _T("Columna1"), m_parametro1);
        RFX_Int(pFX, _T("Columna2"), m_parametro2);
 RFX_Double(pFX, _T("Columna3"), m_parametro3);
    }
};
 
// Ejemplo de uso
void ejecutarConsultaConRecordset(CDatabase& db, const CString& valor1, int valor2) {
    MiRecordset recordset(&db);
    recordset.m_parametro1 = valor1;
    recordset.m_parametro2 = valor2;
 
    if (recordset.Open(CRecordset::dynaset) == FALSE) {
        AfxMessageBox(_T("Error al abrir el recordset."));
        return;
    }
 
    // Procesar los resultados aquí...
 
    recordset.Close();
}
 
// Ejemplo de uso
void ejemploUsoRecordset() {
    CDatabase db;
    db.OpenEx(_T("DSN=mi_dsn;UID=usuario;PWD=contraseña;"));
 
    // Ejecutar una consulta con 2 parámetros
    ejecutarConsultaConRecordset(db, _T("Valor1"), 123);
 
    db.Close();
}

Notas


- En el primer ejemplo, se utiliza `CRecordset` para ejecutar consultas `UPDATE` y `DELETE` con parámetros, ya que `CDatabase::ExecuteSQL` no permite parámetros directamente.
- En el segundo ejemplo, se define una clase derivada de `CRecordset` que puede manejar varios tipos de parámetros. Puedes ajustar la lógica para manejar diferentes números y tipos de parámetros según sea necesario.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar