Jump to content
nedo

[C++] Clasa simpla pentru ODBC

Recommended Posts

Posted (edited)

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

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...