青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

路漫漫,長修遠(yuǎn),我們不能沒有錢
隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
數(shù)據(jù)加載中……

Linux/Unix下ODBC的編程[轉(zhuǎn)載至IBM developerWorks 中國 ]

Linux/Unix下ODBC的編程

1、使用unixODBC提供的ODBC API進(jìn)行編程:
在進(jìn)行編程之前,我們來看一下ODBC API中的常用數(shù)據(jù)類型與我們在C語言中使用的數(shù)據(jù)類型的對應(yīng)關(guān)系:

類型標(biāo)識符 ODBC數(shù)據(jù)類型 C數(shù)據(jù)類型
SQL_C_CHAR SQLCHAR * unsigned char *
SQL_C_SSHORT SQLSMALLINT short int
SQL_C_USHORT SQLUSMALLINT unsigned short int
SQL_C_SLONG SQLINTEGER long int
SQL_C_FLOAT SQLREAL float
SQL_C_DOUBLE SQLDOUBLE, SQLFLOAT double
SQL_C_BINARY SQLCHAR * unsigned char *
SQL_C_TYPE_DATE SQL_DATE_STRUCT struct tagDATE_STRUCT {SQLSMALLINT year; SQLUSMALLINT month; SQLUSMALLINT day; } DATE_STRUCT;
SQL_C_TYPE_TIME SQL_TIME_STRUCT struct tagTIME_STRUCT {SQLUSMALLINT hour; SQLUSMALLINT minute; SQLUSMALLINT second; } TIME_STRUCT;

我們這里使用的數(shù)據(jù)庫名稱為test(DSN),這個DSN使用的用戶名是root,密碼為空,表的名稱是web,字段情況如下:

字段名 數(shù)據(jù)類型
id integer
name char(40)
size integer

第一:設(shè)定ODBC環(huán)境句柄并設(shè)置參數(shù)
首先我們需要聲明一個ODBC環(huán)境句柄(SQLHENV),它可以用來獲得有關(guān)的ODBC環(huán)境信息,我們需要調(diào)用SQLAllocHandle ( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &V_OD_Env )來獲得這個句柄,V_OD_Env就是要分配的SQLHENV類型的環(huán)境句柄。分配好句柄之后,你給它需要設(shè)定所使用的ODBC版本,你可以調(diào)用SQLSetEnvAttr ( V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0 ),SQL_ATTR_ODBC_VERSION是存放你定義的ODBC版本號的變量,SQL_OV_ODBC3則說明你的程序使用的是ODBC 3.0。

第二:設(shè)定連接句柄并設(shè)置超時參數(shù)
我們需要聲明一個連接句柄(SQLHDBC),用來存放數(shù)據(jù)庫連接信息的,調(diào)用SQLAllocHandle ( SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc )獲得連接句柄,V_OD_hdbc就是要分配的SQLHDBC類型的連接句柄。分配好之后,我們可以調(diào)用SQLSetConnectAttr ( V_OD_hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0 )來設(shè)定連接超時參數(shù)。

第三:連接數(shù)據(jù)庫
調(diào)用SQLConnect ( V_OD_hdbc, (SQLCHAR*) "Test", SQL_NTS, (SQLCHAR*) "root", SQL_NTS, (SQLCHAR*) "", SQL_NTS )連接我前面提到的數(shù)據(jù)庫,需要設(shè)定三個參數(shù),就是數(shù)據(jù)庫名稱、用戶名和密碼(因為我的數(shù)據(jù)庫密碼為空,所以這里的密碼也為空),后面的SQL_NTS的位置應(yīng)該寫入這些參數(shù)的長度,如果寫的是SQL_NTS就是讓SQLConnect來決定參數(shù)的長度。

第四:分配SQL語句的句柄并進(jìn)行查詢:
需要聲明一個SQL語句的句柄(SQLHSTMT),用來存放SQL語句信息的,調(diào)用SQLAllocHandle ( SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt )來獲得這個句柄,V_OD_hstmt就是我們要分配的SQLHSTMT類型的SQL語句句柄。

我們的查詢語句是:

												
SELECT name, id FROM web ORDER BY id
										

執(zhí)行這條查詢語句之后,查詢結(jié)果可能有很多行,但每行只有兩列,分別對應(yīng)name和id,它們的數(shù)據(jù)類型為integer和char*,在ODBC中的數(shù)據(jù)類型標(biāo)識符為SQL_C_ULONG和SQL_C_CHAR。我們需要先聲明這樣的兩個變量來存貯查詢結(jié)果:

												
SQLINTEGER		V_OD_id;
char		V_OD_buffer[200];

										

然后我們需要使用SQLBindCol函數(shù)把查詢結(jié)果和我們定義的變量進(jìn)行綁定:

												
SQLBindCol(V_OD_hstmt,1,SQL_C_CHAR, &V_OD_buffer,150,&V_OD_err);
SQLBindCol(V_OD_hstmt,2,SQL_C_ULONG,&V_OD_id,150,&V_OD_err);

										

這里的V_OD_err是用來存放錯誤信息編號的變量,類型也是SQLINTEGER。
接下來,我們調(diào)用SQLExecDirect來進(jìn)行查詢:

												
SQLExecDirect ( V_OD_hstmt, "SELECT dtname,iduser FROM web order by iduser", SQL_NTS );
										

我們可以用SQLNumResultCols ( V_OD_hstmt, &V_OD_colanz )來獲得結(jié)果的列數(shù),也可以用SQLRowCount( V_OD_hstmt, &V_OD_rowanz )來獲得結(jié)果的條數(shù),V_OD_colanz和V_OD_rowanz分別存儲相應(yīng)的結(jié)果,類型分別為SQLSMALLINT和SQLINTEGER。
在讀取結(jié)果之前,我們需要調(diào)用SQLFetch ( V_OD_hstmt )語句,這個語句可以用來獲得第一條結(jié)果也可以用來都下一條,有點像next的感覺。然后我們就可以在V_OD_id和V_OD_buffer里面獲得每條記錄的結(jié)果了。

第五:關(guān)于關(guān)閉連接和釋放句柄
關(guān)閉數(shù)據(jù)庫的連接,調(diào)用SQLDisconnect ( V_OD_hdbc )就可以了,但在關(guān)閉數(shù)據(jù)庫之前需要先釋放SQL語句的句柄,而且在關(guān)閉數(shù)據(jù)庫之后應(yīng)該釋放連接句柄和ODBC環(huán)境句柄,語句如下(按正常的順序):

												
SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
SQLDisconnect(V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);

										

第六:關(guān)于上述情況中的錯誤信息處理
我們需要定義兩個變量:

												
long	V_OD_erg;
SQLINTEGER	V_OD_err;
										

SQLAllocHandle、 SQLSetEnvAttr、SQLSetConnectAttr、SQLConnect、SQLExecDirect、 SQLNumResultCols和SQLRowCount的調(diào)用結(jié)果都可以用V_OD_erg來存儲,V_OD_err可以獲得SQLBindCol中的錯誤信息。

第七:獲得本機的DSN信息
我們可以在聲明SQLHENV句柄之后,使用SQLDataSources函數(shù)來獲得本機的DSN信息。程序如下:

												
void OD_ListDSN(void)
{
char       l_dsn[100],l_desc[100];
short int  l_len1,l_len2,l_next;

l_next=SQL_FETCH_FIRST;
while( SQLDataSources(V_OD_Env,l_next,l_dsn, sizeof(l_dsn),
&l_len1, l_desc, sizeof(l_desc), &l_len2) == SQL_SUCCESS)
{
printf("Server=(%s) Beschreibung=(%s)\n",l_dsn,l_desc);
l_next=SQL_FETCH_NEXT;
}
}

										

l_next變量是用來指定我們所要獲得的DSN的類別:

SQL_FETCH_FIRST 設(shè)定SQLDataSources()函數(shù)找到第一個可用的數(shù)據(jù)源(可以是User DSN,也可以是Systerm DSN)
SQL_FETCH_FIRST_USER 設(shè)定SQLDataSources()函數(shù)找到第一個User DSN
SQL_FETCH_FIRST_SYSTEM 設(shè)定SQLDataSources()函數(shù)找到第一個System DSN
SQL_FETCH_NEXT 找到下一個數(shù)據(jù)源,至于數(shù)據(jù)源類型則要根據(jù)前面的定義

到這里,我們在Unix的C語言下面進(jìn)行ODBC編程已經(jīng)講完,上述ODBC API需要引用以下幾個頭文件(這些文件已經(jīng)安裝到/usr/include下了):

												
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
										

另外如果大家使用GTK進(jìn)行編程,由于到目前為止GTK還沒有加入專門處理數(shù)據(jù)庫的部件,所以大家可以在GTK中調(diào)用上述的ODBC API即可。

這里附上例程供大家參考學(xué)習(xí):

												
/* odbc.c
    testing unixODBC
*/
#include <stdlib.h>
#include <stdio.h>
#include <odbc/sql.h>
#include <odbc/sqlext.h>
#include <odbc/sqltypes.h>

SQLHENV			 V_OD_Env;			// Handle ODBC environment
long			 V_OD_erg;			// result of functions
SQLHDBC			 V_OD_hdbc;			// Handle connection

char			 V_OD_stat[10];		// Status SQL
SQLINTEGER		 V_OD_err,V_OD_rowanz,V_OD_id;
SQLSMALLINT		 V_OD_mlen,V_OD_colanz;
char             V_OD_msg[200],V_OD_buffer[200];


int main(int argc,char *argv[])
{
	// 1. allocate Environment handle and register version 
	V_OD_erg=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error AllocHandle\n");
		exit(0);
	}
	V_OD_erg=SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); 
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error SetEnv\n");
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
	// 2. allocate connection handle, set timeout
	V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc); 
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error AllocHDB %d\n",V_OD_erg);
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
	SQLSetConnectAttr(V_OD_hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0);
	// 3. Connect to the datasource "web" 
	V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "Test", SQL_NTS,
                                     (SQLCHAR*) "root", SQL_NTS,
                                     (SQLCHAR*) "", SQL_NTS);
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Error SQLConnect %d\n",V_OD_erg);
		SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, 
		              V_OD_stat, &V_OD_err,V_OD_msg,100,&V_OD_mlen);
		printf("%s (%d)\n",V_OD_msg,V_OD_err);
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
	printf("Connected !\n");
	V_OD_erg=SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
	if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
	{
		printf("Fehler im AllocStatement %d\n",V_OD_erg);
		SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, V_OD_stat,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
		printf("%s (%d)\n",V_OD_msg,V_OD_err);
		SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
		exit(0);
	}
    SQLBindCol(V_OD_hstmt,1,SQL_C_CHAR, &V_OD_buffer,150,&V_OD_err);
    SQLBindCol(V_OD_hstmt,2,SQL_C_ULONG,&V_OD_id,150,&V_OD_err);
	
    V_OD_erg=SQLExecDirect(V_OD_hstmt,"SELECT dtname,iduser FROM web order by iduser",SQL_NTS);   
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
       printf("Error in Select %d\n",V_OD_erg);
       SQLGetDiagRec(SQL_HANDLE_DBC, V_OD_hdbc,1, V_OD_stat,&V_OD_err,V_OD_msg,100,&V_OD_mlen);
       printf("%s (%d)\n",V_OD_msg,V_OD_err);
       SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
       SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
       SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
       exit(0);
    }
    V_OD_erg=SQLNumResultCols(V_OD_hstmt,&V_OD_colanz);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
        SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
        SQLDisconnect(V_OD_hdbc);
        SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
        SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
        exit(0);
    }
    printf("Number of Columns %d\n",V_OD_colanz);
    V_OD_erg=SQLRowCount(V_OD_hstmt,&V_OD_rowanz);
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
    {
      printf("Number of RowCount %d\n",V_OD_erg);
      SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
      SQLDisconnect(V_OD_hdbc);
      SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
      SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
      exit(0);
    }
    printf("Number of Rows %d\n",V_OD_rowanz);
    V_OD_erg=SQLFetch(V_OD_hstmt);  
    while(V_OD_erg != SQL_NO_DATA)
    {
     printf("Result: %d %s\n",V_OD_id,V_OD_buffer);
     V_OD_erg=SQLFetch(V_OD_hstmt);  
    }  ;
    SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
    SQLDisconnect(V_OD_hdbc);
    SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
    SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
    return(0);
}

										

2.QT下進(jìn)行ODBC編程
QT 3.0提供了Data Table、Data Browser和Data View三個與數(shù)據(jù)庫相關(guān)的控件。你可以在QT的Project設(shè)置你要連接的數(shù)據(jù)庫,Driver一欄中選擇QODBC3即可,其它選項你一看就明白了。上述的三個數(shù)據(jù)庫控件的使用方法可以參見QT中相應(yīng)文檔,也很好使用的。







參考資料

  1. 微軟的ODBC主頁: http://www.microsoft.com/data/odbc/
  2. UnixODBC的主頁: http://www.unixodbc.org
  3. FreeODBC的主頁: http://www.jepstone.net/FreeODBC/
  4. EasySoft的主頁: http://www.easysoft.com
  5. TrollTech的QT 3.0文檔主頁: http://doc.trolltech.com/3.0/

posted on 2006-07-28 08:13 Khan 閱讀(1336) 評論(0)  編輯 收藏 引用 所屬分類: GCC/G++跨平臺開發(fā)

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            性欧美8khd高清极品| 国内久久精品| 欧美高清在线| 国产欧美日韩在线播放| 亚洲成人资源| 国产一区二区三区在线观看免费| 亚洲精品一区久久久久久| 1024国产精品| 久久久另类综合| 性色av一区二区三区红粉影视| 欧美日韩黄色大片| 91久久精品一区二区别| 亚洲福利视频在线| 久久久噜噜噜久久中文字幕色伊伊| 亚洲一区二区在线看| 欧美精彩视频一区二区三区| 欧美电影免费观看高清完整版| 国外精品视频| 久久激情视频| 麻豆精品国产91久久久久久| 国模大胆一区二区三区| 午夜视频在线观看一区| 欧美在线免费观看| 国产日韩一区二区三区在线| 亚洲午夜在线观看视频在线| 亚洲欧美另类在线| 国产精品伊人日日| 亚洲欧美色一区| 久久福利资源站| 国产精品尤物福利片在线观看| 亚洲综合色在线| 久久99伊人| 国产一区二区精品丝袜| 欧美影院精品一区| 蜜桃av久久久亚洲精品| **欧美日韩vr在线| 欧美高清在线| 一本一本久久a久久精品综合妖精| 亚洲深夜福利网站| 国产精品久久看| 午夜亚洲福利| 玖玖国产精品视频| 日韩视频一区二区三区在线播放免费观看 | 国产精品视频yy9299一区| 亚洲午夜激情网站| 久久精品在线观看| 亚洲高清一区二区三区| 欧美日韩精品免费看| 国产精品99久久久久久久vr| 久久国产精品99国产| 在线国产精品一区| 欧美日韩午夜剧场| 欧美一区二区视频在线| 欧美国产乱视频| 一区二区三区毛片| 国模套图日韩精品一区二区| 免费在线亚洲| 亚洲午夜羞羞片| 欧美国产精品| 亚洲资源av| 亚洲二区免费| 国产精品区一区| 浪潮色综合久久天堂| 夜夜嗨av一区二区三区免费区| 亚洲免费视频网站| 亚洲成色最大综合在线| 国产精品成人va在线观看| 久久一区二区三区av| 在线午夜精品自拍| 欧美成人国产一区二区| 亚洲自拍偷拍麻豆| 亚洲国产一区在线| 国产模特精品视频久久久久| 欧美黄色大片网站| 久久久久久久精| 在线视频日韩| 欧美另类变人与禽xxxxx| 亚洲一二三四区| 91久久久国产精品| 久久综合久久久| 欧美一区2区视频在线观看| 亚洲精品久久久久久一区二区| 国产欧美日韩免费| 国产精品白丝jk黑袜喷水| 老司机精品导航| 欧美一区二区免费| 亚洲免费综合| 夜夜嗨av色综合久久久综合网 | 91久久极品少妇xxxxⅹ软件| 久久久www成人免费精品| 亚洲午夜一区| av成人天堂| 亚洲黄色一区| 亚洲国产精品传媒在线观看| 国产美女扒开尿口久久久| 国产精品成人v| 欧美日韩福利视频| 欧美日韩国产在线观看| 欧美高清在线视频| 欧美福利在线观看| 欧美激情精品久久久久久蜜臀| 久久视频这里只有精品| 久久av在线看| 久久精品欧美日韩精品| 欧美在线综合| 久久久久久久久久久久久女国产乱| 欧美亚洲午夜视频在线观看| 在线视频一区观看| 亚洲午夜久久久久久尤物| 在线午夜精品自拍| 亚洲一区久久| 先锋影音网一区二区| 午夜久久久久久| 欧美一级大片在线免费观看| 午夜电影亚洲| 久久精品国内一区二区三区| 久久精品人人做人人综合| 久久精品国产免费看久久精品| 久久国产福利| 久久天天躁狠狠躁夜夜爽蜜月| 久久成人久久爱| 免费成人在线观看视频| 欧美国产日韩在线| 亚洲午夜在线| 性久久久久久久| 久久色中文字幕| 欧美激情成人在线| 日韩午夜黄色| 亚洲免费在线电影| 久久久精品动漫| 欧美成人一品| 欧美性开放视频| 国产精品视频xxx| 尤物网精品视频| 日韩视频精品在线| 欧美在线观看天堂一区二区三区| 久久久亚洲成人| 亚洲精品视频在线播放| 亚洲影视九九影院在线观看| 久久久久成人精品免费播放动漫| 蜜臀a∨国产成人精品| 欧美午夜精品| 亚洲高清成人| 亚洲在线观看视频网站| 久久亚洲影音av资源网| 亚洲欧洲日产国码二区| 亚洲欧美成人一区二区三区| 免费不卡在线观看| 国产精品一区二区你懂的| 亚洲高清一区二区三区| 亚洲欧美一区二区三区在线| 免费视频一区二区三区在线观看| 日韩网站在线| 美女久久网站| 国产一区二区毛片| 中文av一区特黄| 欧美jizz19性欧美| 亚洲欧洲av一区二区三区久久| 欧美韩日亚洲| 在线激情影院一区| 西瓜成人精品人成网站| 最新亚洲视频| 久久最新视频| 国产日韩欧美综合| 亚洲一区国产一区| 亚洲国产一区视频| 久久人人97超碰精品888| 国产精品嫩草影院av蜜臀| 最新国产成人在线观看| 久久精品免费| 亚洲天堂视频在线观看| 欧美极品aⅴ影院| 在线看欧美日韩| 久久精品亚洲精品| 亚洲欧美一区二区激情| 欧美日韩综合在线免费观看| 最新中文字幕亚洲| 欧美高清视频| 久久免费视频网站| 黄色国产精品| 久久久人人人| 欧美一二区视频| 国产欧美日韩精品在线| 亚洲制服丝袜在线| 一区二区三区毛片| 欧美日韩专区| 亚洲午夜日本在线观看| 亚洲国产精品久久人人爱蜜臀| 久久久青草婷婷精品综合日韩| 国产一区二区三区不卡在线观看| 欧美在线免费看| 欧美一级久久久久久久大片| 国产精品一区二区视频| 午夜视频久久久久久| 亚洲自拍偷拍一区| 国产午夜精品全部视频在线播放 | 亚洲国产精品ⅴa在线观看| 香蕉精品999视频一区二区| 国产区日韩欧美| 欧美一区二区三区视频在线|