ODBC配置及程式碼
資料庫作業需要使用ODBC介面,但是網上的各種說法不一,並且有些方法嘗試後沒有用,於是將自己的配置過程發出來~
1、ODBC:
ODBC(Open Database Coonnectivity,開放資料庫互連)標準定義了一個API,應用程式用它來開啟一個數據庫連線、傳送查詢和更新,以及獲取返回結果等。應用程式(例如圖形介面、統計程式包或者電子表格)可以使用相同的ODBC API來訪問任何一個支援ODBC標準的資料庫。
每一個支援ODBC的資料庫系統都提供一個和客戶端程式相連線的庫,但客戶端發出一個ODBC API請求,庫中的程式碼就可以和伺服器通訊來執行被請求動作並取回結果。
2、建立ODBC資料來源
在控制面板->管理工具中找到ODBC資料來源管理程式
新增新資料來源。(新增在使用者DSN中)
注意Data Source Name和Database都一定得是英文的,之前因為這兩個是中文的,改了很久,不是連線不上資料庫,就是連線上了在VS中無法執行SQL命令,將這兩個都換成英文後終於連線成功。
新增後進行測試,顯示 則表示連線成功。
3、配置VS環境
①新建一個工程OBDC;
②將C:/Program Files\MySQL\MySQL Server 5.7\lib下的libmysql.dll複製到工程的debug資料夾裡面;
③設定引用檔案的環境變數,在專案->屬性->VC++目錄下,”include”目錄中把C:\Program File\MySQL\MySQL Server 5.7\include加進來,”lib”目錄中把C:\Program File\MySQL\MySQL Server 5.7\lib加進來。
④利用SQLExecDirect語句,實現資料庫應用程式對資料庫的建立、查詢、修改、刪除等操作,檢索查詢結果集。
查閱官網資料知道,在ODBC3.x中取代了ODBC2.x中的SQLAllocConnect, SQLAllocEnv, and SQLAllocStmt,改為用SQLAllocHandle 分配環境控制代碼、連線控制代碼、語句控制代碼或者描述符控制代碼。
到此就配置好啦!
附上自己ODBC程式碼:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "sql.h"
#include "sqltypes.h"
#include "sqlext.h"
#include"sqlucode.h"
#include"odbcinst.h"
#include<iostream>
#include<string>
using namespace std;
RETCODE retcode;//結果返回集
SQLHDBC hdbc;//定義連結控制代碼
void SQL(string);//執行 SQL 語句子程式
int main()
{
string str;
SQLHANDLE henv; //定義環境控制代碼
unsigned char db[] = "mysql";//ODBC 資料來源名稱
unsigned char user[] = "root";//使用者名稱
unsigned char password[] = "password";//密碼
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);//宣告環境
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); //分配連線控制代碼
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
retcode = SQLConnect(hdbc, db, SQL_NTS, user, SQL_NTS, password, SQL_NTS);//連結到資料庫
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) //成功連線到資料庫
{
cout << "成功連線資料庫!"<<endl;
while (1)
{
cout << "please input the quary:" << endl;
getline(cin, str);
if (str == "exit") return 0;
SQL(str);
}
}
SQLFreeConnect(hdbc); ////釋放連結控制代碼
SQLFreeEnv(henv); // 釋放 ODBC 環境控制代碼
system("pause");
return 0;
}
void SQL(string str)
{
char L1[50] = { '\0' }; char L2[50] = { '\0' }; char L3[50] = { '\0' }; char L4[50] = { '\0' }; char L5[50] = { '\0' }; char L6[50] = { '\0' };
SQLLEN lenOut1, lenOut2, lenOut3, lenOut4, lenOut5, lenOut6;
SQLHSTMT hstmt;//定義語句控制代碼
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); //分配語義控制代碼
if (retcode == SQL_SUCCESS)
{
retcode = SQLExecDirect(hstmt, (SQLCHAR *)(str.c_str()), SQL_NTS); // 把SQL語句送到資料庫伺服器,請求執行由SQL語句定義的資料庫訪問
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
cout << "語句執行成功!" << endl;
//將結果集中的屬性列一一繫結至變數
retcode = SQLBindCol(hstmt, 1, SQL_C_CHAR, L1, sizeof(L1), &lenOut1);
retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, L2, sizeof(L2), &lenOut2);
retcode = SQLBindCol(hstmt, 3, SQL_C_CHAR, L3, sizeof(L3), &lenOut3);
retcode = SQLBindCol(hstmt, 4, SQL_C_CHAR, L4, sizeof(L4), &lenOut4);
retcode = SQLBindCol(hstmt, 5, SQL_C_CHAR, L5, sizeof(L5), &lenOut5);
retcode = SQLBindCol(hstmt, 6, SQL_C_CHAR, L6, sizeof(L6), &lenOut6); //把所有捆綁過的資料欄位的資料拷貝到相應的緩衝區
retcode = SQLFetch(hstmt); //將遊標移動到到查詢結果集的第一行
while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
if (L2[0] == '\0')
cout << (string)L1 << endl;
else if (L3[0] == '\0')
cout << (string)L1 << "\t" << (string)L2 << endl;
else if (L4[0] == '\0')
cout << (string)L1 << " " << (string)L2 << " " << (string)L3 << endl;
else if (L5[0] == '\0')
cout << (string)L1 << " " << (string)L2 << " " << (string)L3 << " " << (string)L4 << endl;
else if (L6[0] == '\0')
cout << (string)L1 << " " << (string)L2 << " " << (string)L4 << " " << (string)L4 << " " << (string)L5 << endl;
else
cout << (string)L1 << " " << (string)L2 << " " << (string)L4 << " " << (string)L4 << " " << (string)L5 << " " << (string)L6 << endl;
retcode = SQLFetch(hstmt); //將遊標移動到到查詢結果集的下一行
}
}
}
SQLFreeStmt(hstmt, SQL_DROP); //釋放語句控制代碼
}