Jump to content
nedo

[C++] Clasa simpla pentru ODBC

Recommended Posts

Clasa de mai jos este scrisa de mine pentru a ajuta la conectarea si inserarea de date intr-o baza de date de tip acces(mdb - access 2003, accdb - access 2007).

Clasa am scris-o deoarece nu am gasit nici una existenta in acest moment, poate si datorita faptului ca se doreste renuntarea la conectivitatea prin odbc.

Momantan clasa nu este 100% completa si voi revenii cu unele modificari.

To Do list:

Metoda pentru error raporting

Metoda pentru executare dinamica a query-urilor atat insert cat si select.

Metoda pentru selectarea si afisarea dinamica a tabelelor

Cele 3 obiective vor fi terminate dupa ce termin programelul la care lucrez momentan pentru care nu am nevoie decat de metodele existente.

Pentru a putea utiliza aceasta functie este necesar sa legati libraria libodbc32.a - cei care utilizeaza code blocks o vor avea - si sa adaugati cele 2 fisiere proiectului vostru.

odbc.h


/**
* Aceasta clasa faciliteaza conexiunea la un fisier de tip mdb sau accdb(Acces 2003 respectiv 2007)
* Functia este creeata pentru a facilita inserarea conectarea si inserarea intr-o baza de date acces
* Metodele pentru care este necesara verificarea executarii executiei vor avea ca valoare de return un int
* Acesta va fii fie 1 fie -1, 1 pentru succes, -1 pentru esec
* Pentru ca aceasta clasa sa fie compilata cu succes aveti nevoie de libraria libodbc32.a
*/
#ifndef ODBC_H_INCLUDED
#define ODBC_H_INCLUDED

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>

using namespace std;

class Codbc
{
public:
Codbc(); /** constructorul default */
Codbc(string dns); /** Constructorul pentru conexiune, preia un string cu adresa bazei de date */
string verificare(string nume); /** functie ce verifica daca un nume exista in baza de date, detalii in implementare */
int inserare(string date); /** functia de inserare a datelor - aceasta o puteti modifica pentru propriile necesitati */
void close(); /** functia pentru inchiderea conexiunii */
~Codbc(); /** destructor */
private:
HENV hEnv; /** handle pentru mediul de lucru */
HDBC hDbc; /** handle pentru conexiune */
HSTMT hStmt; /** handle pentru statement-urile pe care le vom executa */
RETCODE rc; /** va tine codul pe care il returneaza functiile native odbc gasite in libraria libodbc32.a */
char szConnStrOut[255];
int iConnStrLength2Ptr;

};

#endif // ODBC_H_INCLUDED

odbc.cpp


#include "odbc.h"

/**
* Constructorul gol trebuie definit deoarece daca utilizatorul defineste un alt destructor
* C++ nu mai defineste automat un constructor gol
*/
Codbc::Codbc(){}


/**
* destructorul
* inchide conexiunea la baza de date si elibereaza handle-urile
*/
Codbc::~Codbc()
{
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}



/**
* Constructorul costum prin care se creeaza toate cele necesare si se efectueaza conexiunea la baza de date.
* Contine si datele pentru conectarea la baza de date cat si verifica daca s-a conexiunea s-a efectuat cu succes.
* Preia sub forma unui string adresa catre baza de date
*/
Codbc::Codbc(string dns)
{
char szDSN[255] = "Driver={Microsoft Access Driver (*.mdb)};DSN='';DBQ=";
strcat(szDSN, dns.c_str());
rc = SQLAllocEnv(&hEnv);
rc = SQLAllocConnect(hEnv, &hDbc);
rc = SQLDriverConnect(hDbc, NULL, (unsigned char*)szDSN,
SQL_NTS, (unsigned char*)szConnStrOut,
255, (SQLSMALLINT*)&iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
if(SQL_SUCCEEDED(rc))
{
cout << "Conexiune efectuata cu succes.\n\n";
}
else
{
cout << "Conexiunea nu s-a putut efectua.\n\n";
close();
}
}


/**
* Functia care verifica existenta unui nume si returneaza numele la care se adauga un indice
* pe baza numarului de identificari + 1, in baza de date a numelui respectiv
* Spre exemplu daca un nume exista de 3 ori in baza de date la care suntem conectati
* functia va returna nume 4
*/
string Codbc::verificare(string nume)
{
SQLCHAR valoareCustomers[128];
int counter = 0;
int returnCode;
string linieTemporara;
string tempQuerry = "Select Customers.ContactLastName FROM Customers;";
unsigned char* tempQuery = (unsigned char*)tempQuerry.c_str();
rc = SQLAllocStmt(hDbc, &hStmt);
rc = SQLPrepare(hStmt, tempQuery, SQL_NTS);
rc = SQLBindCol(hStmt, 1, SQL_C_CHAR, valoareCustomers, 128, (SQLINTEGER*)&returnCode);
rc = SQLExecute(hStmt);
if(SQL_SUCCEEDED(rc))
{
rc = SQLFetch(hStmt);
while(SQL_SUCCEEDED(rc))
{
linieTemporara = (char*)valoareCustomers;
if((linieTemporara.find(nume) != string::npos) && (linieTemporara.size() <= (nume.size() + 2)))
{
if(((linieTemporara[linieTemporara.size() - 1] < '9') && (linieTemporara[linieTemporara.size() - 1] > '0')))
{
counter++;
}
else if(linieTemporara == nume)
{
counter++;
}
}
rc = SQLFetch(hStmt);
}
}
if(counter == 0)
{
rc = SQLFreeStmt(hStmt, SQL_DROP);
return nume;
}
else
{
stringstream sstemp;
string temp;
sstemp << counter;
sstemp >> temp;
nume = nume + " " + temp;
rc = SQLFreeStmt(hStmt, SQL_DROP);
return nume;
}
return nume;
}



/**
* Functia de inserare a datelor, va prelua un strig ce va contine:
* indicator judet, nume, strada/numar/bloc/apartament smd, sat si sau comuna, judet, data comanda, telefon, oferta
* aceasta o puteti modifica pentru a se potrivi nevoilor voastre
* in cazul in care inserarea se efectueaza cu succes atunci se returneaza 1
* in cazul incare inserarea a esuat se returneaza -1
*/
int Codbc::inserare(string date)
{
string tempQuerry1 = "INSERT INTO Customers(ContactFirstName, ContactLastName, BillingAddress, City, StateOrProvince, PostalCode, PhoneNumber, Extension) Values (";
string tempQuerry2 = tempQuerry1 + date + ");";

rc = SQLAllocStmt(hDbc, &hStmt);
rc = SQLPrepare(hStmt, (unsigned char*)tempQuerry2.c_str(), SQL_NTS);
rc = SQLExecute(hStmt);
if(SQL_SUCCEEDED(rc))
{
cout << "Inserarea s-a efectuat cu succes.\n";
rc = SQLFreeStmt(hStmt, SQL_DROP);
return 1; // succes
}
else
{
cout << "Inserarea nu s-a putut face pentru " << endl;
cout << date << endl;
rc = SQLFreeStmt(hStmt, SQL_DROP);
return -1; // eroare
}
return -1;
}


/**
* Aceasta functie va inchide conexiunea cu baza de date si va elibera handle-urile necesare
*/
void Codbc::close()
{
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
cout << "Clean up done.";
}

Oricine poate lua aceasta clasa si o poate utiliza cum doreste.

Daca aveti sugestii in orice privinta va ascult.

Le: Aceasta clasa nu a fost facuta tocmai bine, prezinta un memory leak destul de mare. Utilizati functiile de aiciSunt mai bune, mai generale si mai bine scrise.

Edited by nedo
  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...