日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql odbc c语言_C语言ODBC操作MySQL数据库(示例代码)

發(fā)布時間:2023/12/8 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql odbc c语言_C语言ODBC操作MySQL数据库(示例代码) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

數(shù)據(jù)庫及其編程API來源于不同的背景,開發(fā)人員可以從眾多的數(shù)據(jù)庫中選擇一種,每種數(shù)據(jù)庫都有自己的一套編程API,這就為數(shù)據(jù)庫編程造成了很大的局限性。SQL是標準化數(shù)據(jù)庫編程接口的一種嘗試,然而各種數(shù)據(jù)庫所支持的SQL又有所不同。

ODBC的設計目的是允許訪問多種數(shù)據(jù)庫,ODBC為數(shù)據(jù)庫供應商提供了一致的ODBC驅動程序標準,遵循這個標準開發(fā)的數(shù)據(jù)庫驅動程序,都可以被開發(fā)人員通過ODBC

API透明地訪問,而不必關心實際的數(shù)據(jù)庫是什么。在這里,ODBC所做的,就是接收開發(fā)人員的數(shù)據(jù)庫操作指令,調用相應的ODBC驅動程序,向一個數(shù)據(jù)庫或者向多個數(shù)據(jù)庫發(fā)送數(shù)據(jù),并可接收來自數(shù)據(jù)庫的數(shù)據(jù)。

ODBC提供了訪問數(shù)據(jù)庫的標準,這使得開發(fā)人員將精力集中在應用程序以及用戶接口的開發(fā)上,而不必考慮與之相連的數(shù)據(jù)庫。為了進一步簡化開發(fā)工作,ODBC把API層實現(xiàn)為SQL的映射器。通常數(shù)據(jù)庫開發(fā)人員將標準的SQL語句發(fā)送給ODBC驅動程序,再由ODBC驅動程序將這個SQL語句映射成數(shù)據(jù)庫可以支持的SQL語句。

本章首先對ODBC API的概貌進行簡要介紹,然后講述利用ODBC API進行數(shù)據(jù)庫開發(fā)的技巧,最后將通過具體數(shù)據(jù)庫開發(fā)實例,詳細講述通過ODBC API開發(fā)數(shù)據(jù)庫應用程序的方法和過程。

1了解ODBC API

ODBC是一種使用SQL的程序設計接口。使用ODBC讓應用程序的編寫者避免了與數(shù)據(jù)源相聯(lián)的復雜性。這項技術目前已經得到了大多數(shù)DBMS廠商們的廣泛支持。ODBC是一種使用SQL 的程序設計接口。使用ODBC讓應用程序的編寫者避免了與數(shù)據(jù)源相聯(lián)的復雜性。這項技術目前已經得到了大多數(shù)DBMS廠商們的廣泛支持。

Microsoft Developer Studio為大多數(shù)標準的數(shù)據(jù)庫格式提供了32位ODBC驅動器。這些標準數(shù)據(jù)格式包括有:SQL Server,Access,Paradox,dBase,FoxPro,Excel,Oracle 以及Microsoft Text。如果用戶希望使用其他數(shù)據(jù)格式,用戶需要相應的ODBC驅動器及DBMS。

ODBC API是一個內容豐富的數(shù)據(jù)庫編程接口,包括60多個函數(shù)、SQL數(shù)據(jù)類型以及常量的聲明。ODBC API 是獨立于DBMS和操作系統(tǒng)的,而且它與編程語言無關。ODBC API 以X/Open和ISO/IEC中的CLI規(guī)范為基礎,ODBC 3.0完全實現(xiàn)了這兩種規(guī)范,并添加了基于視圖的數(shù)據(jù)庫應用程序開發(fā)人員所需要的共同特性,例如可滾動光標。ODBC API中的函數(shù)由特定DBMS驅動程序的開發(fā)人員實現(xiàn),應用程序用這些驅動程序調用函數(shù),以獨立于DBMS的方式訪問數(shù)據(jù)。

ODBC API涉及了數(shù)據(jù)源連接與管理、結果集檢索、數(shù)據(jù)庫管理、數(shù)據(jù)綁定、事務操作等內容,目前的最高版本是3.0。

通常使用ODBC API開發(fā)數(shù)據(jù)庫應用程序需要經過如下步驟:

·??????連接數(shù)據(jù)源。

·??????分配語句句柄。

·??????準備并執(zhí)行SQL語句。

·??????獲取結果集。

·??????提交事務。

·??????斷開數(shù)據(jù)源連接并釋放環(huán)境句柄。

下面對上述步驟做詳細的介紹。

步驟1:連接數(shù)據(jù)源

為了連接數(shù)據(jù)源,必須要建立一個數(shù)據(jù)源連接的環(huán)境句柄。通過調用SQLAllocEnv函數(shù)實現(xiàn)對環(huán)境句柄的分配,在ODBC 3.0里,這個函數(shù)已經被SQLAllocHandle取代,但是熟悉ODBC API的開發(fā)人員還是習慣用這個函數(shù)建立環(huán)境句柄,因為VC++開發(fā)平臺有一個映射服務,這個服務將程序代碼對函數(shù)SQLAllocEnv的調用轉向對函數(shù)SQLAllocHandle的調用。

這里有必要對“環(huán)境句柄”這個概念進行說明。句柄是指向一個特殊結構的指針,而環(huán)境指的是驅動程序管理器需要為該驅動程序存儲的有關系統(tǒng)和數(shù)據(jù)源的一般信息。由于這個時候還沒有建立同數(shù)據(jù)源的連接,驅動程序還并不知道該使用哪一個驅動程序來完成這個任務,所以這個任務只能由驅動程序管理器來完成,利用這個環(huán)境句柄保留信息直到被使用。

使用函數(shù)SQLAllocEnv創(chuàng)建環(huán)境句柄的語法如下:

HENV? henv;

RETCODE?rcode;

rcode = ::SQLAllocEnv(SQL_HANDLE_ENV, SQL_NULL,& henv);

if(rcode == SQL_SUCCESS)?? // 環(huán)境句柄創(chuàng)建成功

{

// 執(zhí)行其它操作

…………

}

完成了環(huán)境句柄的創(chuàng)建以后,還要建立一個連接句柄。連接句柄的創(chuàng)建函數(shù)是SQLAllocConnect,其調用語法如下:

HDBC?? hdbc;

retcode = ::SQLAllocConnect( m_henv, & hdbc);

if(rcode == SQL_SUCCESS)?? // 連接句柄創(chuàng)建成功

{

// 執(zhí)行其它操作

…………

}

完成了環(huán)境句柄和連接句柄的創(chuàng)建以后,就可以進行實際的數(shù)據(jù)源連接了。完成數(shù)據(jù)源連接的函數(shù)是SQLConnect,其調用語法如下:

m_retcode = :: SQLConnect( m_hdbc,

(PUCHAR)pszSourceName,SQL_NTS,

(PUCHAR)pszUserId,wLengthUID,

(PUCHAR)pszPassword,wLengthPSW );

if(rcode == SQL_SUCCESS)?? // 數(shù)據(jù)源連接成功

{

// 執(zhí)行其它操作

…………

}

到此,應用程序同數(shù)據(jù)源的連接已經完成。

有些時候,ODBC數(shù)據(jù)源并不是事先在用戶的計算機里安裝好了的,這時就需要應用程序能夠動態(tài)創(chuàng)建ODBC數(shù)據(jù)源。ODBC API提供了動態(tài)創(chuàng)建數(shù)據(jù)源的函數(shù)SQLConfigDataSource。該函數(shù)的語法如下:

BOOL SQLConfigDataSource(HWND? hwndParent,

WORD? fRequest,

LPCSTR? lpszDriver,

LPCSTR? lpszAttributes);

參數(shù)hwndParent用于指定父窗口句柄,在不需要顯示創(chuàng)建數(shù)據(jù)源對話框時,可以將該參數(shù)指定為NULL;參數(shù)fRequest用于指定函數(shù)的操作內容,函數(shù)SQLConfigDataSource能夠實現(xiàn)的操作內容由參數(shù)fRequest制定,參數(shù)fRequest取值如下:

ODBC_ADD_DSN:創(chuàng)建數(shù)據(jù)源;

ODBC_CONFIG_DSN:配置或者修改已經存在的數(shù)據(jù)源;

ODBC_REMOVE_DSN:刪除已經存在的數(shù)據(jù)源;

ODBC_ADD_SYS_DSN:創(chuàng)建系統(tǒng)數(shù)據(jù)源;

ODBC_CONFIG_SYS_DSN:配置或者修改已經存在的系統(tǒng)數(shù)據(jù)源;

ODBC_REMOVE_SYS_DSN:刪除已經存在的系統(tǒng)數(shù)據(jù)源;

ODBC_REMOVE_DEFAULT_DSN:刪除缺省的數(shù)據(jù)源。

參數(shù)lpszDriver用于指定ODBC數(shù)據(jù)源的驅動程序類別,例如,為了指定Access數(shù)據(jù)源,該參數(shù)應賦以字符串“MicrosoftAccess Driver (*.mdb)\0”。 參數(shù)lpszAttributes用于指定ODBC數(shù)據(jù)源屬性,例如:

“DSN=MYDB\0DBQ=D:\\Database\\Friends.mdb\0DEFAULTDIR=D:\\DATABASE\0\0”

該字符串指定數(shù)據(jù)源名稱(DSN)為MYDB,數(shù)據(jù)庫文件(DBQ)為D:\Database\Friends.mdb,缺省數(shù)據(jù)庫文件路徑(DEFAULTDIR)為D:\DATABASE。

通過調用如下代碼可以通過應用程序動態(tài)創(chuàng)建數(shù)據(jù)源MYDB:

BOOL CreateDSN()

{

char*szDesc;

intmlen;

szDesc=newchar[256];

sprintf(szDesc,"DSN=%s:DESCRIPTION=TOC support source: \

DBQ=%s:FIL=MicrosoftAccess: \

DEFAULTDIR=D:\\Database::","TestDB","D:\\Friends.mdb");

mlen= strlen(szDesc);

for(int i=0; i

if(szDesc[i] == ‘:‘)?????? ? szDesc[i] = ‘\0‘;

}

if (FALSE ==SQLConfigDataSource(NULL,ODBC_ADD_DSN,

"MicrosoftAccess Driver (*.mdb)\0",

(LPCSTR)szDesc))

returnFALSE; // 創(chuàng)建數(shù)據(jù)源失敗。

else

returnTRUE; // 創(chuàng)建數(shù)據(jù)源成功。

}

步驟2:分配語句句柄

通常將ODBC中的語句看作SQL語句。前面已經提到,ODBC同數(shù)據(jù)庫的SQL接口通信,驅動程序將ODBC的SQL映射到驅動程序的SQL。但是ODBC的SQL還攜帶了一些屬性信息,用于定義數(shù)據(jù)源連接的上下文,有些語句要求特殊的參數(shù)以便能夠執(zhí)行,因此,每個語句都有一個指向定義語句所有屬性結構的句柄。

語句句柄的分配同環(huán)境句柄的分配相似,通過函數(shù)SQLAllocStmt實現(xiàn),該函數(shù)的調用語法如下:

HSTMT ???hstmt;

RETCODE?rcode;

m_retcode = :: SQLAllocStmt(hdbc, ?&hstmt );

if(rcode == SQL_SUCCESS)?? // 連接句柄創(chuàng)建成功

{

// 執(zhí)行其它操作

…………

}

步驟3:準備并執(zhí)行SQL語句

對于不同的應用程序需求,要準備的SQL語句也一定不一樣。通常的SQL語句包括SELECT、INSERT、UPDATA、DELETE、DROP等。

準備和執(zhí)行一個SQL語句的方法有兩種,第一種是使用SQLExecDirect函數(shù),可以一次執(zhí)行一個SQL語句。很多請求都可以使用這個方法。調用SQLExecDirect函數(shù)的語法如下:

LPCSTR pszSQL;

strcpy(pszSQL, “SELECT * FROM EMPLOYEES”);

retcode = ::SQLExecDirect(hstmt, ?(UCHAR*)pszSQL, ?SQL_NTS );

if(rcode == SQL_SUCCESS)?? // SQL語句執(zhí)行成功

{

// 執(zhí)行其它操作

…………

}

但是有些請求需要多次執(zhí)行同一條語句,為此,ODBC提供了SQLPrepare函數(shù)和SQLExecute函數(shù)。調用的時候,只需要調用一次SQLPrepare函數(shù),然后調用若干次SQLExecute函數(shù)。實際上,函數(shù)SQLExecDirect將SQLPrepare和SQLExecute的功能集中到了一起,多次調用SQLExecDirect顯然比調用一次SQLPrepare再調用若干次SQLExecute效率高。調用SQLPrepare和SQLExecute函數(shù)的語法如下:

LPCSTR pszSQL;

strcpy(pszSQL, “SELECT * FROM EMPLOYEES”);

m_retcode = ::SQLPrepare( hstmt, ?(UCHAR*)pszSQL, ?SQL_NTS );

if(rcode == SQL_SUCCESS)?? // SQL語句準備成功

{

// 執(zhí)行其它操作

…………

}

retcode = :: SQLExecute (hstmt, ?(UCHAR*)pszSQL, ?SQL_NTS );

if(rcode == SQL_SUCCESS)?? // SQL語句執(zhí)行成功

{

// 執(zhí)行其它操作

…………

}

步驟4:獲取結果集

SQL語句執(zhí)行成功以后,應用程序必須準備接收數(shù)據(jù),應用程序需要把SQL語句執(zhí)行結果綁定到一個本地緩存變量里。但是SQL執(zhí)行語句執(zhí)行的結果并不是直接傳送給應用程序,而是在應用程序準備接收數(shù)據(jù)的時候通知驅動程序其已經準備好接收數(shù)據(jù),應用程序通過調用SQLFetch函數(shù)返回結果集的一行數(shù)據(jù)。

由于返回的數(shù)據(jù)是存放在列中的,因此應用程序必須調用SQLBindCol函數(shù)綁定這些列。通常接收結果集時需要依次進行以下操作:

·??????返回列的個數(shù),執(zhí)行SQLNumResultCols函數(shù)。

·??????給出列中數(shù)據(jù)的有關信息,例如列的名稱、數(shù)據(jù)類型和精度等,執(zhí)行SQLDescribeCol函數(shù)。

·??????把列綁定到應用程序的變量里,執(zhí)行SQLBindCol函數(shù)。

·??????獲取數(shù)據(jù),執(zhí)行SQLFetch函數(shù)。

·??????獲取長數(shù)據(jù),執(zhí)行SQLGetData函數(shù)。

應用程序首先調用SQLNumResultCols函數(shù),獲知每個記錄里有多少列,調用SQLDescribeCol函數(shù)取得每列的屬性,然后調用SQLBindCol函數(shù)將列數(shù)據(jù)綁定到指定的變量里,最后調用SQLFetch函數(shù)或者SQLGetData函數(shù)獲取數(shù)據(jù)。

對于其它的SQL語句,應用程序重復這個過程。這個過程代碼如下:

retcode = ::SQLNumResultCols( m_hstmt,&wColumnCount );

if( m_retcode != SQL_SUCCESS ) // 列舉結果集列的個數(shù)不成功

{

// 釋放操作

…………

return;

}

LPSTR?? pszName;

UWORD? ???????? URealLength;

SWORD? ???????? wColumnCount;

UWORD? ???????? wColumnIndex = 0;

SWORD? ???????? wColumnType;

UDWORD ??????? dwPrecision;

SWORD? ???????? wScale;

SWORD? ???????? wNullable;

m_retcode = ::SQLDescribeCol( m_hstmt,

wColumnIndex,?// 列的索引

pszName,??? // 列的名稱

256, ???// 存放列名稱的緩沖區(qū)大小

& nRealLength, ?// 實際得到列名稱的長度

&wColumnType,? // 列的數(shù)據(jù)類型

&dwPrecision,? // 精度

&wScale, // 小數(shù)點位數(shù)

&wNullable );? // 是否允許空值

if(retcode != SQL_SUCCESS ) // 執(zhí)行不成功

{

// 釋放操作

…………

return;

}

retcode = ::SQLBindCol( m_hstmt,

uCounter, // 列索引

wColumnType, // 列數(shù)據(jù)類型

FieldValue, // 綁定的變量

dwBufferSize, // 變量內存大小

&BytesInBuffer); // 存放將來返回數(shù)據(jù)的大小的變量

if(retcode != SQL_SUCCESS ) // 執(zhí)行不成功

{

// 釋放操作

…………

return;

}

::SQLFetch( m_hstmt );

// 此后可以從綁定的變量里讀取列的值。

…………

步驟5:提交事務

當所有的SQL語句都被執(zhí)行并接收了所有的數(shù)據(jù)以后,應用程序需要調用SQLEndTran提交或者回退事務。如果提交方式為手工(應用程序設置)方式,則需要應用程序執(zhí)行這個語句以提交或者回退事務,如果是自動方式,當SQL語句執(zhí)行后,該命令自動執(zhí)行。

事務是為了維護數(shù)據(jù)的一致性和完整性而設計的概念,事務要求:要么提交,將事務里包含的更新操作都提交到數(shù)據(jù)庫里;要么回退,數(shù)據(jù)庫恢復到事務前的狀態(tài),不會影響數(shù)據(jù)庫的一致性和完整性。通常情況下,檢索類SQL語句不涉及數(shù)據(jù)的更新,不會對數(shù)據(jù)的一致性和完整性產生影響,因此通常將檢索類SQL語句設置提交方式為自動,而將更新類SQL語句的提交方式設置為手工方式,便于通過代碼在事務處理中執(zhí)行事務的提交或者回退,以維護數(shù)據(jù)庫的一致性和完整性。在大型的商業(yè)應用中,這個設置非常有用。

調用SQLEndTran函數(shù)的語法如下:

:: SQLEndTran(SQL_HANDLE_DBC , hdbc,? SQL_COMMIT); // 提交事務

:: SQLEndTran(SQL_HANDLE_DBC , hdbc,? SQL_ROLLBACK); // 回退事務

步驟6:斷開數(shù)據(jù)源連接并釋放環(huán)境句柄

當應用程序使用完ODBC以后,需要使用SQLFreeHandle函數(shù)釋放所有語句句柄、連接句柄、環(huán)境句柄。這里需要注意操作的順序,應該是先釋放所有語句句柄,調用SQLDisconnect函數(shù)解除與數(shù)據(jù)源的連接,然后釋放所有連接句柄,最后釋放環(huán)境句柄,使應用程序同ODBC管理器的連接徹底解除。

一個封裝好的C語言odbc操作mysql的源碼分享給大家,這里需要注意的是我們的工程需要選擇使用多字節(jié)字符集

odbc.h

typedef char CHAR;

typedef signed int INT32;

typedefunsigned long U_LONG;

#defineSUCCESS1

#defineFAILURE0

#ifndef __ODBD_H__

#define __ODBC_H__

#ifdef __cplusplus

extern "C" {

#endif

#define CONLEN sizeof(CONSTR)-1

#define SQL_QUERY_BUFF_SIZE 512

#define CON_STR_LEN 255

#ifdef ODBC_PUBLIC

SQLHENV hEnv = 0;

SQLHDBC hDBC = 0;

SQLHSTMT hStmt = 0;

SQLRETURN retcode;

SQLCHAR szConStr[CON_STR_LEN];

SQLCHAR szStmt[SQL_QUERY_BUFF_SIZE];

INT16 cbConLen;

#endif

/*

* Function protypes are declared here

*/

void InitAndConnectToDBS(void);

CHAR InsertRowIntoDBS(CHAR *tName, CHAR *queryStr, INT32 queryStrLen);

CHAR** GetFieldValuesFromDBS(CHAR* qStr, INT32 noOfCols, INT32 len, U_LONG **resultPtrLen);

void CloseConnectionToDBS(void);

CHAR UpdateColumnsInDBS(CHAR *tName, CHAR* queryStr, INT32 queryStrLen);

void FreeDBSResultPtr(CHAR **ptr, INT32 cnt, U_LONG *ptrLen);

void PrintDBSError(void);

CHAR DeleteRowFromDBS(CHAR* queryStr, INT32 queryStrLen);

#ifdef __cplusplus

}

#endif

#endif /* ifndef __ODBC_H__ */odbc.c

#ifdef __cplusplus

extern "C" {

#endif

#include

#include

#include

#include

#include

#define ODBC_PUBLIC

#include "odbc.h"

/**************************************************************************

*Function Name: InitAndConnectToDBS()

*

*Args: Nothing

*

*Returns: Nothing

*

*Task: Establishes connection with database server.

*

*See Also:

*

*Docs: Yes.

*

*Bugs:

*****************************************************************************/

void InitAndConnectToDBS(void)

{

/*RETCODE rc;

rc = SQLAllocEnv(&hEnv) ;

if( rc != SQL_SUCCESS)

{

PrintDBSError();

DEBUGMSG1("Unable to connect with database 1\n");

return;

}

rc = SQLAllocConnect(hEnv,&hDBC);

if( rc != SQL_SUCCESS)

{

PrintDBSError();

DEBUGMSG1("Unable to connect with database 2\n");

return;

}

rc = SQLDriverConnect(hDBC,NULL,CONSTR,CONLEN,

szConStr,sizeof(szConStr), &cbConLen,SQL_DRIVER_NOPROMPT);

if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)

{

PrintDBSError();

DEBUGMSG1("Unable to connect with database 3\n");

return;

}*/

/*Step 1 定義句柄和變量 */

// 分配環(huán)境句柄

retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);

if (retcode != SQL_SUCCESS)

{

printf("SQLAllocHandle error!");

return -1;

}

// 設置環(huán)境句柄

retcode = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);

if (retcode != SQL_SUCCESS)

{

printf("SQLSetEnvAttr error!");

return -2;

}

// 分配連接句柄

retcode = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDBC);

if (retcode != SQL_SUCCESS)

{

printf("SQLAllocHandle error!");

return -3;

}

/*之上的程序代碼讀者直接粘貼即可,無限修改;至于具體語句或函數(shù)的功能,沒有必要深入了解,只要清楚每一步的作用(注釋給出)即可*/

/* 連接ODBC數(shù)據(jù)庫,主要函數(shù)中第二個參數(shù)test為操作的數(shù)據(jù)源的名稱;第四個參數(shù)是操作數(shù)據(jù)庫的用戶名;第六個參數(shù)是操作數(shù)據(jù)庫的密碼*/

retcode = SQLConnect(hDBC, (SQLCHAR *)"videodetectodbc", SQL_NTS, (SQLCHAR *)"root",

SQL_NTS, (SQLCHAR *)"root", SQL_NTS);

if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)

{

printf("SQLConnect error!");

return -4;

}

DEBUGMSG1("Successfully Connected........\n");

}/* End of InitAndConnectToDBS */

/**************************************************************************

* Fucntion Name: CloseConnectionToDBS()

*

*Args: Nothing

*

*Returns: Nothing

*

*Task: Closes connection with database server .

*

*See Also:

*

*Docs: Yes.

*

*Bugs:

*****************************************************************************/

void CloseConnectionToDBS(void)

{

if (hDBC)SQLDisconnect(hDBC);

if (hDBC)SQLFreeConnect(hDBC);

if (hEnv)SQLFreeEnv(hEnv);

}/* End of CloseConnectionToDBS */

/**************************************************************************

*Function Name: GetFieldValuesFromDBS()

*

*Args: 1. SQL query string(IN).

* 2. Number of columns(IN).

* 3. Length of each columns(OUT).

*

*Returns: Column values.

*

*Task: Retrives all column values from database for the given

* SQL select query string.

*

*See Also:

*

*Docs: Yes.

*

*Bugs:

*****************************************************************************/

CHAR** GetFieldValuesFromDBS(CHAR* queryStr, INT32 noOfCols, INT32 len, U_LONG **resultPtrLen)

{

INT32 i;

CHAR **resultPtr;

LONG *lengths;

RETCODE rc;

resultPtr = (CHAR**)__Malloc(sizeof(CHAR*)*noOfCols);

if (resultPtr == NULL)

{

DEBUGMSG1("Memory allocation failed\n");

return NULL;

}

lengths = (LONG *)__Malloc(sizeof(LONG)*noOfCols);

if (lengths == NULL)

{

DEBUGMSG1("Memory allocation failed\n");

__Free(resultPtr);

return NULL;

}

*resultPtrLen = (U_LONG*)__Malloc(sizeof(U_LONG)*noOfCols);

if (*resultPtrLen == NULL)

{

DEBUGMSG1("Memory allocation failed\n");

return NULL;

}

rc = SQLAllocStmt(hDBC, &hStmt);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return NULL;

}

for (i = 0; i

DEBUGMSG2("%c", queryStr[i]);

DEBUGMSG1("\n");

rc = SQLPrepare(hStmt, queryStr, __Strlen(queryStr));

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return NULL;

}

for (i = 0; i < noOfCols; i++)

{

resultPtr[i] = (CHAR *)__Malloc(255);

if (resultPtr[i] == NULL)

{

DEBUGMSG1("Memory allocation failed\n");

while (--i >= 0) __Free(resultPtr[i]);

__Free(resultPtr);

__Free(lengths);

return NULL;

}

rc = SQLBindCol(hStmt, i + 1, SQL_C_CHAR, (PTR)resultPtr[i], 255, &lengths[i]);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return NULL;

}

}

rc = SQLExecute(hStmt);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return NULL;

}

rc = SQLFetch(hStmt);

if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)

{

for (i = 0; i < noOfCols; i++)

{

(*resultPtrLen)[i] = lengths[i];

resultPtr[i][lengths[i]] = '\0';

}

if (hStmt)SQLFreeStmt(hStmt, SQL_DROP);

__Free(lengths);

return resultPtr;

}

else

{

DEBUGMSG1("Error in fetching values......\n");

if (hStmt)SQLFreeStmt(hStmt, SQL_DROP);

__Free(lengths);

return NULL;

}

}/* End of GetFieldValuesFromDBS */

/**************************************************************************

*Function Name: InsertRowIntoDBS()

*

*Args: 1. Table Name (IN).

* 2. Query string(IN).

*

*Returns: SUCCESS/FAILURE.

*

*Task: Adds new row in a given table.

*

*See Also:

*

*Docs: Yes.

*

*Bugs:

*****************************************************************************/

CHAR InsertRowIntoDBS(CHAR* tName, CHAR* queryStr, INT32 queryStrLen)

{

RETCODE rc;

CHAR szStmt[SQL_QUERY_BUFF_SIZE];

INT32 i;

INT32 tempLen;

sprintf(szStmt, "insert into %s values(", tName);

tempLen = __Strlen(szStmt);

__Memcpy(szStmt + tempLen, queryStr, queryStrLen);

tempLen = tempLen + queryStrLen;

szStmt[tempLen] = '\0';

for (i = 0; i

{

DEBUGMSG2("%c", szStmt[i]);

}

DEBUGMSG1("\n");

rc = SQLAllocStmt(hDBC, &hStmt);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return FAILURE;

}

rc = SQLPrepare(hStmt, szStmt, SQL_NTS);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return FAILURE;

}

rc = SQLExecute(hStmt);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return FAILURE;

}

if (hStmt)SQLFreeStmt(hStmt, SQL_DROP);

return SUCCESS;

}/* End of InsertRowIntoDBS */

/**************************************************************************

*Function Name: UpdateColumnsInDBS()

*

*Args: 1. Table Name(IN).

* 2. Query string(IN).

*

*Returns: SUCCESS/FAILURE.

*

*Task: Updates a row in a given table.

*

*See Also:

*

*Docs: Yes.

*

*Bugs:

*****************************************************************************/

CHAR UpdateColumnsInDBS(CHAR* tName, CHAR* queryStr, INT32 queryStrLen)

{

RETCODE rc;

CHAR szStmt[SQL_QUERY_BUFF_SIZE];

INT32 i;

INT32 tempLen;

sprintf(szStmt, "update %s set ", tName);

tempLen = __Strlen(szStmt);

__Memcpy(szStmt + tempLen, queryStr, queryStrLen);

tempLen = tempLen + queryStrLen;

szStmt[tempLen] = '\0';

for (i = 0; i

{

DEBUGMSG2("%c", szStmt[i]);

}

DEBUGMSG1("\n");

rc = SQLAllocStmt(hDBC, &hStmt);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return FAILURE;

}

rc = SQLPrepare(hStmt, szStmt, SQL_NTS);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return FAILURE;

}

rc = SQLExecute(hStmt);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return FAILURE;

}

if (hStmt)SQLFreeStmt(hStmt, SQL_DROP);

return SUCCESS;

}/* End of UpdateColumnsInDBS */

/**************************************************************************

*Function Name: DeleteRowFromDBS()

*

*Args: 1. Table Name(IN).

* 2. Query string(IN).

*

*Returns: SUCCESS/FAILURE.

*

*Task: Deletes a row in a given table.

*

*See Also:

*

*Docs: Yes.

*

*Bugs:

*****************************************************************************/

CHAR DeleteRowFromDBS(CHAR* queryStr, INT32 queryStrLen)

{

RETCODE rc;

INT32 i;

for (i = 0; i

DEBUGMSG2("%c", queryStr[i]);

DEBUGMSG1("\n");

rc = SQLAllocStmt(hDBC, &hStmt);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return FAILURE;

}

rc = SQLPrepare(hStmt, queryStr, SQL_NTS);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return FAILURE;

}

rc = SQLExecute(hStmt);

if (rc != SQL_SUCCESS)

{

PrintDBSError();

return FAILURE;

}

if (hStmt)SQLFreeStmt(hStmt, SQL_DROP);

return SUCCESS;

}

/**************************************************************************

*Function Name: FreeDBSResultPtr()

*

*Args: 1. References to be freed.

* 2. Number of references to be free.

* 3. References to be freed for length.

*

*Returns: Nothing.

*

*Task: Frees memory.

*

*See Also:

*

*Docs: Yes.

*

*Bugs:

*****************************************************************************/

void FreeDBSResultPtr(CHAR** ptr, INT32 cnt, U_LONG *ptrLen)

{

INT32 i;

for (i = 0; i

{

__Free(ptr[i]);

}

__Free(ptr);

__Free(ptrLen);

}

/**************************************************************************

*Function Name: PrintDBSError()

*

*Args: Nothing

*

*

*Returns: Nothing.

*

*Task: Prints error message.

*

*See Also:

*

*Docs: Yes.

*

*Bugs:

*****************************************************************************/

void PrintDBSError(void)

{

CHAR szState[6];

CHAR szMsg[255];

INT32 sdwNative;

INT16swMsgLen;

SQLError(hEnv, hDBC, hStmt, szState, &sdwNative,

szMsg, sizeof(szMsg), &swMsgLen);

DEBUGMSG3("%s\n%s\n", szState, szMsg);

}

#ifdef __cplusplus

}

#endif

/**************************************************************************

* End of odbc.c

**************************************************************************/CSDN源碼下載:http://download.csdn.net/detail/davebobo/9521546

總結

以上是生活随笔為你收集整理的mysql odbc c语言_C语言ODBC操作MySQL数据库(示例代码)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。