國產DM4數據庫ODBC編程指南


本章結合DM4數據庫的特點,比較全面系統的介紹ODBC的基本概念以及DM4 ODBC DRIVER的使用方法,以便用戶更好地使用DM4 ODBC編寫應用程序。
ODBC 提供給你訪問不同類型的數據庫的途徑。結構化查詢語言SQL是一種用來訪問數據庫的語言。通過使用ODBC,應用程序能夠使用相同的源代碼和各種各樣的數 據庫交互。這使得開發者不需要以特殊的數據庫管理系統DBMS爲目標,或者瞭解不同支撐背景的數據庫的詳細細節,就能夠開發和發佈客戶/服務器應用程序。
DM4 ODBC3.0遵照Microsoft ODBC3.0規範設計與開發,實現了ODBC應用程序與DM4的互連接口。用戶可以直接調用DM4 ODBC3.0接口函數訪問DM4,也可以使用可視化編程工具如C++ Builder、PowerBuilder等利用DM4 ODBC3.0訪問DM4。
在DM4客戶端軟件安裝過程中,如果選擇了安裝ODBC驅動程序的相關選項,安裝工具可完成將DM4 ODBC3.0驅動程序複製到硬盤,並在Windows註冊表中登記DM4ODBC驅動程序信息的工作。
要進一步使用DM4 ODBC驅動程序,請閱讀本章以瞭解ODBC數據源管理方法。
1 數據類型
客戶程序可以通過SQLGetTypeInfo函數來獲取DM4 ODBC3.0支持的數據類型信息。由SQLGetTypeInfo返回的數據類型是數據源所支持的數據類型,它們是預備用於DDL(DataDefinitionLanguage)語句的。
調用DM4 ODBC3.0的SQLGetTypeInfo,返回支持的數據類型如表1.1如下:
表1:數據類型列表
類型名 類型描述
char(n) 固定串長度爲n的字符串,n<=8000
Varchar(n) 最大字符串長度爲n的可變長度字符串,n<=8000
binary(n) 固定長度爲n的二進制數據,n<=8000
varbinary(n) 最大長度爲n的可變長度二進制數據,n<=8000
Image 影像數據類型,可變長度的二進制數據,最大長度爲2G-1
Text 文本數據類型,可變長度的字符數據,最大長度爲2G-1
Bit 單個二進制位數據
Tinyint 精度爲3,刻度爲0的有符號精確數字,取值範圍-128…127
Smallint 精度爲5,刻度爲0的有符號精確數字,取值範圍-32,768…32,767
Int 精度爲10,刻度爲0的有符號精確數字,取值範圍-2[31]…2[31]-1
Bigint 精度爲19,刻度爲0的有符號精確數字值,取值範圍-2[63]…2[63]-1
Real 二進制精度爲24的有符號近似數字值,取值範圍0或者絕對值爲:10[-38]…10[38]
Float 二進制精度爲53的有符號近似數字值,取值範圍0或者絕對值爲:10[-308]…10[308]
Double 二進制精度爲53的有符號近似數字值,取值範圍0或者絕對值爲:10[-308]…10[308]
decimal(p,s) 精度爲p,刻度爲s的有符號精確數字值,1≤p≤53,s≤p
numeric(p,s) 精度爲p,刻度爲s的有符號精確數字值,1≤p≤38,s≤p
Money 精度固定爲19,刻度固定爲4的精確有符號數值
Date 日期數據類型,年月日字段,格式與Gregorian(羅馬)日曆一致
Time(p) 時間數據類型,時分秒字段,精度p指定了秒的精度
timestamp(p) 時間戳數據類型,年月日時分秒字段,精度p指定了秒的精度
intervalyear(p) 年間隔,即兩個日期之間的年數字,p爲時間間隔的首項字段精度(後面簡稱爲:首精度)
intervalmonth(p) 月間隔,即兩個日期之間的月數字,p爲時間間隔的首精度
intervalyear(p)tomonth 年月間隔,即兩個日期之間的年月數字,p爲時間間隔的首精度
intervalday(p) 日間隔,即爲兩個日期/時間之間的日數字,p爲時間間隔的首精度
intervalhour(p) 時間隔,即爲兩個日期/時間之間的時數字,p爲時間間隔的首精度
intervalminute(p) 分間隔,即爲兩個日期/時間之間的分數字,p爲時間間隔的首精度
intervalsecond(p,q) 秒間隔,即爲兩個日期/時間之間的秒數字,p爲時間間隔的首精度,q爲時間間隔秒精度
intervalday(p)tohour 日時間隔,即爲兩個日期/時間之間的日時數字,p爲時間間隔的首精度
intervalday(p)to minute 日時分間隔,即爲兩個日期/時間之間的日時分數字,p爲時間間隔的首精度
Intervalday(p)tosecond(q) 日時分秒間隔,即爲兩個日期/時間之間的日時分秒數字,p爲時間間隔的首精度,q爲時間間隔秒精度
Intervallhour(p)tominute 時分間隔,即爲兩個日期/時間之間的時分數字,p爲時間間隔的首精度
intervalhour(p)tosecond(q) 時分秒間隔,即爲兩個日期/時間之間的時分秒數字,p爲時間間隔的首精度,q爲時間間隔秒精度
Intervalminute(p)tosecond(q) 分秒間隔,即爲兩個日期/時間之間的分秒間隔,p爲時間間隔的首精度,q爲時間間隔秒精度
注:要支持interval數據類型,必須在數據源中進行設置,否則將不提供對該類數據類型的支持。
2 支持的函數
客戶程序可以通過SQLGetFunctions函數來獲取DM4 ODBC3.0支持的函數信息。由SQLGetFunctions返回的函數列表是數據源所支持的函數。
以下按照類型分類列出了DM4ODBCx提供的函數。應用程序能夠通過調用SQLGetFunctions來獲得指定函數的支持信息。
1.連接到數據源
下面的函數用於連接到數據源:
(1)SQLAllocHandle:分配環境、連接、語句或者描述符句柄。
(2)SQLConnect:建立與驅動程序或者數據源的連接。訪問數據源的連接句柄包含了包括狀態、事務申明和錯誤信息的所有連接信息。
(3)SQLDriverConnect:與SQLConnect相似,用來連接到驅動程序或者數據源。但它比SQLConnect支持數據源更多的連接信息,它提 供了一個對話框來提示用戶設置所有的連接信息以及系統信息表沒有定義的數據源。
(4) SQLBrowseConnect:支持一種交互方法來檢索或者列出連接數據源所需要的屬性和屬性值。每次調用函數可以獲取一個連接屬性字符串,當檢索完 所有的屬性值,就建立起與數據源的連接,並且返回完整的連接字符串,否則提示缺少的連接屬性信息,用戶根據此信息重新輸入連接屬性值再次調用此函數進行連 接。
2.獲取驅動程序和數據源信息
下面的函數用來獲取驅動程序和數據源信息:
(1)SQLDataSources:能夠被調用多次來獲取應用程序使用的所有數據源的名字。
(2)SQLDrivers:返回所有安裝過的驅動程序清單,包括對它們的描述以及屬性關鍵字。
(3)SQLGetInfo:返回連接的驅動程序和數據源的元信息。
(4)SQLGetFunctions:返回指定的驅動程序是否支持某個特定函數的信息。
(5)SQLGetTypeInfo:返回指定的數據源支持的數據類型的信息。
設置或者獲取驅動程序屬性
下面的函數用來設置或者獲取驅動程序屬性:
(1)SQLSetConnectAttr:設置連接屬性值。
(2)SQLGetConnectAttr:返回連接屬性值。
(3)SQLSetEnvAttr:設置環境屬性值。
(4)SQLGetEnvAttr:返回環境屬性值。
(5)SQLSetStmtAttr:設置語句屬性值。
(6)SQLGetStmtAttr:返回語句屬性值。
4.設置或者獲取描述符字段
下面的函數用來設置或者獲取描述符字段:
(1)SQLGetDescField:返回單個描述符字段的值。
(2)SQLGetDescRec:返回當前描述符記錄的多個字段的值。
(3)SQLSetDescField:設置單個描述符字段的值。
(4)SQLSetDescRec:設置描述符記錄的多個字段。
5.準備SQL語句
下面的函數用來準備SQL語句:
(1)SQLPrepare:準備要執行的SQL語句。
(2)SQLBindParameter:在SQL語句中分配參數的緩衝區。
(3)SQLGetCursorName:返回與語句句柄相關的遊標名稱。
(4)SQLSetCursorName:設置與語句句柄相關的遊標名稱。
(5)SQLSetScrollOptions:設置控制遊標行爲的選項。
6.提交SQL請求
下面的函數用來提交SQL請求:
(1)SQLExecute:執行準備好的SQL語句。
(2)SQLExecDirect:執行一條SQL語句。
(3)SQLNativeSql:返回驅動程序對一條SQL語句的翻譯。
(4)SQLDescribeParam:返回對SQL語句中指定參數的描述。
(5)SQLNumParams:返回SQL語句中參數的個數。
(6)SQLParamData:與SQLPutData聯合使用在運行時給參數賦值。
(7)SQLPutData:在SQL語句運行時給部分或者全部參數賦值。
7.檢索結果集及其相關信息
下面的函數用來檢索結果集及其相關信息:
(1)SQLRowCount:返回INSERT、UPDATE或者DELETE等語句影響的行數。
(2)SQLNumResultCols:返回結果集中列的數目。
(3)SQLDescribeCol:返回結果集中列的描述符記錄。
(4)SQLColAttribute:返回結果集中列的屬性。
(5)SQLBindCol:爲結果集中的列分配緩衝區。
(6)SQLFetch:在結果集中檢索下一行元組。
(7)SQLFetchScroll:返回指定的結果行。
(8)SQLGetData:返回結果集中當前行某一列的值。
(9)SQLSetPos:在取到的數據集中設置遊標的位置。這個記錄集中的數據能夠刷新、更新或者刪除。
(10)SQLBulkOperations:執行塊插入和塊書籤操作,其中包括根據書籤更新、刪除或者取數據。
(11)SQLMoreResults:確定是否能夠獲得更多的結果集,如果能就執行下一個結果集的初始化操作。
(12)SQLGetDiagField:返回一個字段值或者一個診斷數據記錄。
(13)SQLGetDiagRec:返回多個字段值或者一個診斷數據記錄。
8.取得數據源系統表的信息
下面的函數用來取得數據源系統表的信息:
(1)SQLColumnPrivileges:返回一個關於指定表的列的列表以及相關的權限信息。
(2)SQLColumns:返回指定表的列信息的列表。
(3)SQLForeignKeys:返回指定表的外鍵信息的列表。
(4)SQLPrimaryKeys:返回指定表的主鍵信息的列表。
(5)SQLProcedureColumns:返回指定存儲過程的參數信息的列表。
(6)SQLProcedures:返回指定數據源的存儲過程信息的列表。
(7)SQLSpecialColumns:返回唯一確定某一行的列的信息,或者當某一事務修改一行的時候自動更新各列的信息。
(8)SQLStatistics:返回一個單表的相關統計信息和索引信息。
(9)SQLTablePrivileges:返回相關各表的名稱以及相關的權限信息。
(10)SQLTables:返回指定數據源中表信息。
9.終止語句執行
下面的函數用來終止語句執行:
(1)SQLFreeStmt:終止語句執行,關閉所有相關的遊標,放棄沒有提交的結果,選擇釋放與指定語句句柄相關的資源。
(2)SQLCloseCursor:關閉一個打開的遊標,放棄沒有提交的結果。
(3)SQLCancel:放棄執行一條SQL語句。
(4)SQLEndTran:提交或者回滾事務。
10.中斷連接
下面的函數處理中斷連接的任務:
(1)SQLDisconnect:關閉指定連接。
(2)SQLFreeHandle:釋放環境、連接、語句或者描述符句柄。
3 建立ODBC連接
1.申請環境與連接句柄
客戶程序要和一個遠程的服務器或數據庫進行通訊,必須首先和這個服務器或數據庫建立連接,如何通過ODBC建立一個連接以及使用連接呢?是我們下面將要介紹的內容。
爲了建立一個ODBC數據源連接,需要使用到環境句柄以及連接句柄。句柄有一個層次的概念,一個連接句柄總是和一個唯一的環境句柄相聯繫的,所有的連接句柄必須在環境句柄釋放之前釋放。
客戶程序可以通過調用函數SQLAllocHandle來申請一個環境句柄,調用函數SQLAllocHandle時必須傳入句柄選項SQL_HANDLE_ENV,當申請環境句柄成功之後,可以在此環境句柄上申請連接句柄。申請環境句柄和連接句柄的代碼示範如下:
#include
#include
#include
#include

/* 檢測返回代碼是否爲成功標誌,當爲成功標誌返回TRUE,否則返回FALSE */
#define RC_SUCCESSFUL(rc) ((rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO)
/* 檢測返回代碼是否爲失敗標誌,當爲失敗標誌返回TRUE,否則返回FALSE */
#define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc)))
HENV henv; /* 環境句柄 */
HDBC hdbc; /* 連接句柄 */
SQLRETURN sret; /* 返回代碼 */
void main(void)
{
/* 申請一個環境句柄 */
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
/* 設置環境句柄的ODBC版本 */
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3,
SQL_IS_INTEGER);
/* 申請一個連接句柄 */
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
/* 釋放連接句柄 */
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
/* 釋放環境句柄 */
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
2.如何與數據源進行連接
ODBC的連接是從數據源開始的,數據源是ODBC對一個特定的數據庫的別稱。爲了訪問由數據源提供的數據,你的程序中必須首先建立和數據源之間的連接,在環境和連接句柄正確分配之後,才能通過這些連接管理數據訪問。
爲了產生建立連接時必要的參數,必須完成以下的幾項工作:
(1)調用SQLAllocHandle申請一個環境句柄。
(2)調用SQLAllocHandle申請一個連接句柄。
(3)創建一個數據源DSN。
(4)一個有效的用戶ID。
(5)一個對應於這個用戶ID的口令。
(6)其它的一些提供給驅動程序的參數信息。
連接ODBC數據源時,ODBC提供三種不同的連接函數,即SQLConnect、SQLDriverConnect和SQLBrowseConnect,每個函數都有不同的參數以及不同級別的一致性。

表1:連接到數據源的ODBC函數
函數 ODBC版本 一致性 主要參數
SQLConnect 1.0 核心級 hdbc,數據源,用戶ID,口令
SQLDriverConnect 1.0 1級 hdbc,窗口句柄,輸入連接字符串
SQLBrowseConnect 1.0 2級 hdbc,輸入連接字符串,輸出連接字符串

SQLConnect 是連接ODBC數據源的最基本的方法,在所有的一致性級別上都支持。SQLConnect函數有以下參數:連接句柄,數據源名稱,數據源名稱長度,用戶名 (用戶ID),用戶名長度,用戶口令以及口令長度。返回代碼有:SQL_SUCCESS,SQL_SUCCESS_WITH_INFO, SQL_ERROR或者SQL_INVALID_HANDLE。使用SQLConnect函數連接數據源的代碼示範如下:
sret = SQLConnect(hdbc, (SQLCHAR *)"DM4", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS);
if (RC_SUCCESSFUL(sret)) {
/* 連接數據源失敗! */
…進行相應的錯誤處理…
exit(0);
}
SQLDriverConnect提供了比SQLConnect更的方法來建立ODBC連接。它支持:要求更多連接參數的數據源;對話框提示用戶輸入所有的連接信息;以及沒有在系統信息表中定義的數據源。
SQLDriverConnect提供以下的連接方法:
(1)用一個連接字符串建立一個連接,這個字符串包括建立連接的所有數據,如DSN,一個或多個用戶ID及其口令,以及其他的數據庫所需要的連接信息。
(2)用一個並不完整的連接字符串來建立連接,使得ODBC驅動程序管理器來提示用戶輸入所需要的連接信息。
(3)用一個沒有在系統信息表中登記的數據源建立連接,驅動程序自動提示用戶輸入連接信息。
(4)用一個連接字符串建立連接,這個字符串在DSN配置文件中是確定的。
SQLDriverConnect函數fDriverCompletion參數說明:
(1)SQL_DRIVER_PROMPT:設置此選項用來顯示一個對話框來提示用戶輸入連接信息。
(2)SQL_DRIVER_COMPLETE:如果函數調用中包含了足夠的信息,ODBC就進行連接,否則彈出對話框提示用戶輸入連接信息,此時等同於SQL_DRIVER_PROMPT。
(3)SQL_DRIVER_COMPLETE_REQUIRED:這個參數與SQL_DRIVER_COMPLETE參數唯一的不同是用戶不能改變由函數提供的信息。
(4)SQL_DRIVER_NOPROMPT:如果函數調用時有足夠的信息,ODBC就進行連接,否則返回SQL_ERROR。
使用SQLDriverConnect連接數據源的代碼示範如下:
SQLCHAR szConnStrIn[256] = "DSN=DM4;DRIVER=DM ODBC DRIVER;
DATABASE=SYSTEM;UID=SYSDBA;PWD=SYSDBA";
SQLCHAR szConnStrOut[256];
SQLSMALLINT cbConnStrOut;
sret = SQLDriverConnect(hdbc, hwnd, szConnStrIn, SQL_NTS, szConnStrOut, 256, &cbConnStrOut, SQL_DRIVER_PROMT);
if (RC_SUCCESSFUL(sret)) {
/* 連接數據源失敗! */
…進行相應的錯誤處理…
exit(0);
}
SQLBrowseConnect函數與SQLDriverConnect函數相似,但是調用SQLBrowseConnect函數時,程序在運行時可以再形成一個連接字符串,使用這個函數可以用一個交互的方式來決定連接到數據源時所需要的一些信息。
使用SQLBrowseConnect函數連接數據源的代碼示範如下:
SQLCHAR szConnStrIn[256] = "DSN=DM4;DRIVER=DM ODBC DRIVER;
DATABASE=SYSTEM;UID=SYSDBA;PWD=SYSDBA;";
SQLCHAR szConnStrOut[256];
SQLSMALLINT cbConnStrOut;
sret = SQLBrowseConnect(hdbc, szConnStrIn, SQL_NTS, szConnStrOut, 256, &cbConnStrOut);
if (RC_SUCCESSFUL(sret)) {
/* 連接數據源失敗! */
…進行相應的錯誤處理…
exit(0);
}
設置與取得連接的屬性
建立連接之後,應用程序可以通過調用SQLSetConnectAttr函數來設置連接屬性,對連接進行全方面的管理。下面列出了一些常用的連接屬性。
表2:常用的連接屬性
屬性 描述
SQL_ATTR_ACCESS_MODE 用來設置訪問模式,即只讀或者讀寫連接模式,可以用來優化併發控制策略。不支持
SQL_ATTR_ASYNC_ENABLE 是否支持異步執行
SQL_ATTR_AUTOCOMMIT 是否使用自動提交功能。
SQL_ATTR_CONNECTION_TIMEOUT 設定連接超時。(不支持)
SQL_ATTR_CURRENT_CATALOG 當前連接使用的編目。
SQL_ATTR_LOGIN_TIMEOUT 設定登錄超時。不支持
SQL_ATTR_ODBC_CURSORS 設置驅動程序管理器使用遊標的方式。
SQL_ATTR_PACKET_SIZE 設置網絡傳輸包的大小。不支持
SQL_ATTR_QUIET_MODE 使彈出對話框有效/無效。
更多的連接屬性,用戶可以參考《Microsoft ODBC3.0程序員參考手冊》,在這裏不做介紹了。
應用程序可以通過調用SQLGetConnectAttr函數來取得當前連接的屬性。
設置與取得連接屬性的代碼示範如下:
SQLINTEGER AUTOCOMMIOT_MODE;
/* 設置連接句柄屬性,關閉自動提交功能 */
SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF,
SQL_IS_INTEGER);
/* 取得連接句柄屬性,取得提交的模式 */
SQLGetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)&AUTOCOMMIOT_MODE,
Sizeof(SQLINTEGER), NULL);
4.斷開與數據源之間的連接
如果要終止客戶程序與服務器之間的連接,客戶程序應當完成以下的幾個操作:
(1)調用SQLFreeHandle釋放語句句柄,關閉所有打開的遊標,釋放相關的語句句柄資源。(在非自動提交模式下,需事先提交當前的事務)
(2)調用函數SQLDisconnect關閉所有的連接。
(3)調用SQLFreeHandle釋放連接句柄及其相關的資源。
(4)調用SQLFreeHandle釋放環境句柄及其相關的資源。
一個完整的連接管理示範代碼如下:
#include
#include
#include
#include

/* 檢測返回代碼是否爲成功標誌,當爲成功標誌返回TRUE,否則返回FALSE */
#define RC_SUCCESSFUL(rc) ((rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO)
/* 檢測返回代碼是否爲失敗標誌,當爲失敗標誌返回TRUE,否則返回FALSE */
#define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc)))

HENV henv; /* 環境句柄 */
HDBC hdbc; /* 連接句柄 */
HSTMT hsmt; /* 語句句柄 */
SQLRETURN sret; /* 返回代碼 */
SQLINTEGER AUTOCOMMIOT_MODE;
void main(void)
{
/* 申請一個環境句柄 */
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
/* 設置環境句柄的ODBC版本 */
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3,
SQL_IS_INTEGER);
/* 申請一個連接句柄 */
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
sret = SQLConnect(hdbc, (SQLCHAR *)"DM4", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS);
if (RC_SUCCESSFUL(sret)) {
/* 連接數據源失敗! */
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(0);
}
/* 設置連接句柄屬性,關閉自動提交功能 */
SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF,
SQL_IS_INTEGER);
/* 取得連接句柄屬性,取得提交的模式 */
SQLGetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)&AUTOCOMMIOT_MODE,
sizeof(SQLINTEGER), NULL);
/* 申請一個語句句柄 */
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hsmt);
…在這裏可以使用語句句柄進行相應的數據庫操作…
/* 釋放語句句柄 */
SQLFreeHandle(SQL_HANDLE_STMT, hsmt);
/* 提交連接上的事務 */
SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
/* 斷開與數據源之間的連接 */
SQLDisconnect(hdbc);
/* 釋放連接句柄 */
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
/* 釋放環境句柄 */
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
4 ODBC應用程序編程的基本步驟
4.1 創建ODBC資源
在客戶使用ODBC方法訪問一個DM4數據庫服務器之前,必須先對自己的應用程序所用的ODBC資源進行配置。本節將介紹如何爲你的應用程序安裝和配置ODBC資源。
在客戶機上配置ODBC資源的步驟:
1.在控制面板上訪問ODBC構件,顯示ODBC數據源管理器對話框,如圖4.1所示。ODBC數據源管理器對話框包含的標籤如下:
(1)用戶DSN:添加、刪除或配置本機上的數據源,它們只可由當前用戶使用。
(2)系統DSN:添加、刪除或配置本機上的數據源,它們可由任何用戶使用。
(3)文件DSN:添加、刪除或配置在分離文件中的數據源。這些文件可以被安裝了同樣數據庫驅動器的用戶共享。
(4)驅動程序:列出了安裝在客戶機上的數據庫驅動器。
(5)跟蹤:用於測試你的數據庫應用程序。它跟蹤客戶機和數據庫服務器之間的ODBCAPI的調用。
(6)連接池:允許不同的應用程序自動複用多個連接。這有助於限制和數據庫服務器的通信過載。
(7)關於:顯示主要ODBC組件的版本。

圖4.1ODBC數據源管理器對話框
2.設置和配置一個系統DSN,請單擊系統DSN標籤,單擊添加按鈕增加一個新的DSN,顯示如圖4.2所示的對話框。

圖4.2創建新數據源對話框
3.選擇DM4 ODBC3.0驅動程序即DMODBCDRIVER,單擊完成按鈕,顯示如圖4.3所示的DM4 ODBC3.0數據源配置對話框。

圖4.3創建新的DM4數據源對話框
4. 輸入數據源的名稱,一個簡單的描述,並選擇你想要連接的數據庫服務器的名字,使用的端口號,缺省使用的DB,驗證登錄用戶ID真僞的方式,如果使用 DMServer驗證方式則需要輸入登錄數據源的ID以及密碼等信息,選擇系統提示信息的語種,以及選擇是否使用DMServer的增強選項。
5.單擊測試按鈕測試你配置的數據源是否正確,得到數據源測試報告如圖4.4所示,如果測試成功,可以單擊確定按鈕以保存你設置的新的系統數據源,如圖4.5所示。

圖4.4數據源測試報告

圖4.5完成系統數據源的設置
6.單擊確定按鈕關閉ODBC數據源管理器對話框。
4.2 ODBC應用程序編寫的基本步驟
應用程序使用ODBC訪問數據源,可以按照以下幾個基本步驟進行:
1. 調用函數SQLAllocHandle申請環境、連接句柄,調用函數SQLSetEnvAttr設置環境句柄屬性,調用函數 SQLSetConnectAttr設置連接句柄屬性,調用連接函數SQLConnect、SQLDriverConnect或 SQLBrowseConnect連接相關的數據源。
2.調用函數SQLAllocHandle申請語句句柄,通過語句句柄應用程序可以執行 SQL語句進行相關的SQL操作。調用函數SQLPrepare對SQL語句和操作進行準備,調用SQLDescribeCol、 SQLDescribeParam等函數取得相關的描述信息,依據描述信息調用SQLBindCol、SQLBindParam等函數綁定相關的列和參 數,然後調用SQLExecute執行SQL語句,實現相關的SQL操作。應用程序也可以調用函數SQLExecDirect直接執行SQL語句進行相關 的SQL操作。
3.應用程序可以通過調用ODBC編目函數SQLTables、SQLColumns、SQLStatistics等取得數據源相關的字典信息。
4.如果連接屬性自動提交選項設置爲手動提交狀態,應用程序可以調用函數SQLEndTran來提交或回滾事務,進行相關的事務處理。
5.調用函數SQLFreeHandle來釋放申請的語句句柄。
6.調用函數SQLDisconnect來斷開應用程序與數據源之間的連接。
7.調用函數SQLFreeHandle來釋放申請的連接、環境句柄。
使用ODBC編程的基本步驟如圖4.6所示。

圖4.6直接使用ODBC函數開發應用程序的基本步驟

下面是一個調用DM4 ODBC3.0的簡單實例:
#include
#include
#include
#include
#include

/* 檢測返回代碼是否爲成功標誌,當爲成功標誌返回TRUE,否則返回FALSE */
#define RC_SUCCESSFUL(rc) ((rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO)
/* 檢測返回代碼是否爲失敗標誌,當爲失敗標誌返回TRUE,否則返回FALSE */
#define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc)))

HENV henv; /* 環境句柄 */
HDBC hdbc; /* 連接句柄 */
HSTMT hsmt; /* 語句句柄 */
SQLRETURN sret; /* 返回代碼 */
char szcode[6]; /* 廠商編號 */
long cbcode = 0;
char szname[21]; /* 廠商名 */
long cbname = 0;
char szasset[13]; /* 資產總值 */
long cbasset = 0;
char szaddress[11];/* 廠商地址 */
long cbaddress = 0;
void main(void)
{
/* 申請一個環境句柄 */
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
/* 設置環境句柄的ODBC版本 */
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
/* 申請一個連接句柄 */
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
SQLConnect(hdbc, (SQLCHAR *)"DM4", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS);
/* 申請一個語句句柄 */
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hsmt);
/* 立即執行查詢廠商登記表的語句 */
SQLExecDirect(hsmt, (SQLCHAR *)"SELECT 廠商編號, 廠商名, 資產總值, 廠商地址 FROM 廠商登記;", SQL_NTS);
/* 綁定數據緩衝區 */
SQLBindCol(hsmt, 1, SQL_C_CHAR, szcode, sizeof(szcode), &cbcode);
SQLBindCol(hsmt, 2, SQL_C_CHAR, szname, sizeof(szname), &cbname);
SQLBindCol(hsmt, 3, SQL_C_CHAR, szasset, sizeof(szasset), &cbasset);
SQLBindCol(hsmt, 4, SQL_C_CHAR, szaddress, sizeof(szaddress), &cbaddress);
/* 取得數據並且打印數據 */
printf("廠商編號 廠商名 資產總值 廠商地址/n");
for (;;) {
sret = SQLFetchScroll(hsmt, SQL_FETCH_NEXT, 0);
if (sret == SQL_NO_DATA_FOUND)
break;
printf("%s %s %s %s/n", szcode, szname, szasset, szaddress);
}
/* 釋放語句句柄 */
SQLFreeHandle(SQL_HANDLE_STMT, hsmt);
/* 斷開與數據源之間的連接 */
SQLDisconnect(hdbc);
/* 釋放連接句柄 */
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
/* 釋放環境句柄 */
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
4.3 在C++Builder中通過ODBC訪問DM4
C++ Builder是由目前比較流行的數據庫應用程序開發工具,能夠通過ODBC進行可視化的數據庫編程,下面通過一個實例簡單的介紹一下如何使用C++ Builder進行可視化的數據庫應用編程。
首先啓動DM4服務器,創建一個名爲DM4的ODBC數據源,啓動C++ Builder5.0集成開發環境,如圖4.7所示。

圖4.7C++Builder集成開發環境
如圖4.8所示,在Form1窗體中添加TTable、TDataSource、TDBGrid、TDBNavigator組件Table1、DataSource1、DBGrid1、DBNavigator1。

圖4.8添加Table、DataSource等控件
選 中Table1,設置屬性DatabaseName爲DM4,設置屬性TableName爲廠商登記,置屬性Active爲TRUE。選中 DataSource1,設置屬性DataSet爲Table1。選中DBGrid1,設置屬性DataSource爲DataSource1。選中 DBNavigator1,設置屬性DataSource爲DataSource1。得到結果如圖4.9所示。

圖4.9C++Builder可視化編程
點擊運行命令,得到的運行結果如圖4.10所示。

圖4.10C++Builder編程實例運行結果
用C++ Builder開發工具可以開發各種各樣的數據庫應用系統,大大地簡化了數據庫應用系統的開發,界面美觀,開發成本低,週期短,這些應用系統已經被廣泛地應用於諸如金融、消防、醫院、地理、天文等等大型綜合數據服務系統中。
而這一切正因爲ODBC,學習與掌握好ODBC,對於數據庫應用系統的開發可以起到很好的幫助作用。
如何使用C++ Builder進行更廣泛深入的數據庫編程不在本手冊的談論範圍之內,讀者感興趣可參考C++ Builder編程指南。
4.4 在PowerBuilder中通過ODBC訪問DM4
PowerBuilder也是目前廣泛使用的數據庫應用系統主流開發工具,下面我們通過圖例介紹如何在PowerBuilder中通過ODBC訪問DM4數據庫管理系統。
運行PowerBuilder8.0,其集成開發環境界面如圖4.11所示。

圖4.11PowerBuilder集成開發環境
點擊DBProfile命令,得到如圖4.12所示的對話框。

圖4.12DBProfile對話框
選中ODBODBC,點擊New按鈕,如圖4.13所示進行ODBCDBProfile的配置。

圖4.13DBProfile配置
點擊OK按鈕,創建DM4DBProfile成功,如圖4.14所示。

圖4.14DBProfile配置成功
選中DM4,點擊Connect按鈕,點擊Database命令,得到如圖4.15所示的界面。

圖4.15連接DM4數據源成功
客戶就可以對DM4數據庫進行訪問了,如訪問商場登記表,如圖4.16所示。

圖4.16瀏覽DM4數據源中的表數據
也可以瀏覽數據庫的一些元信息,如圖4.17所示。

圖4.17瀏覽數據庫元信息
這裏簡要介紹了在PowerBuilder中如何通過ODBC訪問DM4數據庫。PowerBuilder同樣也是一個功能十分強大的數據庫可視化開發工具,掌握它對設計與開發應用系統有着十分重要的幫助。讀者如果感興趣,可以參考PowerBuilder開發指南。
5 使用存儲過程和函數
DM4允許用戶創建和使用存儲模塊,下面介紹如何在DM4ODBC應用中使用存儲過程和函數。
5.1 存儲過程與函數字典信息的獲取
DM4 ODBC3.0支持字典函數SQLProcedures的調用,用戶可以調用此函數來獲取DM4存儲過程與函數的字典信息。
調用方法如下:
SQLProcedures(stmt,“SYSTEM”,SQL_NTS,“SYSDBA”,SQL_NTS,“TEST_PROC”,SQL_NTS);
返回字典信息格式如表5.1。
表5.1:字典信息說明表
編號 字典項 相關說明
1 PROCEDURE_CAT 存儲模塊編目信息
2 PROCEDURE_SCHEM 存儲模塊模式信息
3 PROCEDURE_NAME 存儲模塊名
4 NUM_INPUT_PARAMS DM4暫時沒有返回此項信息
5 NUM_OUTPUT_PARAMS DM4暫時沒有返回此項信息
6 NUM_RESULT_SETS DM4暫時沒有返回此項信息
7 REMARKS DM4暫時沒有返回此項信息
8 PROCEDURE_TYPE 存儲模塊的類型

DM4 ODBC3.0支持字典函數SQLProcedureColums的調用,用於返回存儲模塊的參數信息。
調用方法如下:
SQLProcedureColumns(stmt,“SYSTEM”,SQL_NTS,“SYSDBA”,SQL_NTS,“TEST_PROC”,SQL_NTS,NULL,0);
返回字典信息格式如表5.2。
表5.2:字典信息說明表
編號 字典項 相關說明
1 PROCEDURE_CAT 存儲模塊編目信息
2 PROCEDURE_SCHEM 存儲模塊模式信息
3 PROCEDURE_NAME 存儲模塊名
4 COLUMN_NAME 參數名
5 COLUMN_TYPE 參數的類型,即爲輸入參數還是輸出參數
6 DATA_TYPE 參數的SQL數據類型
7 TYPE_NAME 參數的類型名
8 COLUMN_SIZE 參數的精度
9 BUFFER_LENGTH 參數所佔用的字符長度
10 DECIMAL_DIGITS 參數的刻度
11 NUM_PREC_RADIX 僅對數值類型有效,僅爲10或者2,如果爲10表示爲精確數字,如果爲2表示爲非精確數字
12 NULLABLE 參數是否接收空值標誌
13 REMARK 參數說明
14 COLUMN_DEF 參數的缺省值
15 SQL_DATA_TYPE 參數的SQL數據類型
16 SQL_DATETIME_SUB 日期時間類型或者時間間隔類型的子代碼
17 CHAR_OCTET_LENGTH 字符數據類型以字節計算的最大長度,非字符類型返回空值
18 ORDINAL_POSITION 參數的順序
19 IS_NULLABLE 參數是否包含空值
5.2 存儲模塊的創建
用戶可以使用SQLExecDirect函數執行創建存儲模塊的SQL語句來創建存儲模塊,如下例所示:
SQLExecDirect(stmt, (SQLCHAR *)“create or replace procedure test_proc (c1 in int) ”
“as ”
“declare c2 int ”
“begin ”
“c2 := c1 + 100 ”
“end;”, SQL_NTS);
5.3 存儲模塊的調用
調用存儲模塊的方法可以分爲兩種情況。
1.立即調用
如果存儲過程需要設置參數,那麼在調用存儲模塊的時候就已經爲爲所有的IN、INOUT類型的參數進行了賦值,帶有OUT屬性的參數的值是通過取得存儲過程結果集的方法獲取的。立即執行存儲過程的示例如下:
SQLExecDirect(stmt,(SQLCHAR*)”calltest_proc(123);”,SQL_NTS);
2.參數調用
這種調用方法指的是在調用模塊的時候,其參數值用問號來代替,發送給服務器之後,服務器返回參數的準備信息,用戶依據服務器返回的參數描述信息進行參數綁定,然後執行,其參數的處理方法與普通的參數處理方法相同。
DM4支持存儲模塊返回多個結果集的處理,多結果集的切換通過SQLMoreResult函數切換,下面通過一個實例來說明如何使用。
#include
#include
#include
#include
#include
HENV env;
HDBC dbc;
HSTMT stmt;
RETCODE ret;
short i;
short cols;
char colname[129];
char coldata[256];

void main(void)
{
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &env);
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
SQLConnect(dbc, (SQLCHAR *)"DM4", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS);
SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
SQLExecDirect(stmt, (SQLCHAR *)"drop table test_table1;", SQL_NTS);
SQLExecDirect(stmt, (SQLCHAR *)"drop table test_table2;", SQL_NTS);
SQLExecDirect(stmt, (SQLCHAR *)"create table test_table1 (t1col int);", SQL_NTS);
SQLExecDirect(stmt, (SQLCHAR *)"insert into test_table1 values(100);", SQL_NTS);
SQLExecDirect(stmt, (SQLCHAR *)"create table test_table2 (t2col varchar(10));", SQL_NTS);
SQLExecDirect(stmt, (SQLCHAR *)"insert into test_table2 values('hello!');", SQL_NTS);
SQLExecDirect(stmt, (SQLCHAR *)"create or replace procedure test_proc as begin select * from test_table1 select * from test_table2 end;", SQL_NTS); SQLExecDirect(stmt, (SQLCHAR *)"call test_proc;", SQL_NTS);
SQLNumResultCols(stmt, &cols);
for (i=1; i<=cols; i++)
{
SQLDescribeCol(stmt, i, (SQLCHAR *)colname, 129, NULL, NULL, NULL, NULL, NULL);
printf("%s ", colname);
}
printf("/n");
for ( ; ; )
{
ret = SQLFetch(stmt);
if (ret == SQL_NO_DATA_FOUND) break;
for (i=1; i<=cols; i++)
{
SQLGetData(stmt, i, SQL_C_CHAR, coldata, 256, NULL);
printf("%s ", coldata);
}
printf("/n");
} SQLMoreResults(stmt);
SQLNumResultCols(stmt, &cols);
for (i=1; i<=cols; i++)
{
SQLDescribeCol(stmt, i, (SQLCHAR *)colname, 129, NULL, NULL, NULL, NULL, NULL);
printf("%s ", colname);
}
printf("/n");
for ( ; ; )
{
ret = SQLFetch(stmt);
if (ret == SQL_NO_DATA_FOUND) break;
for (i=1; i<=cols; i++)
{
SQLGetData(stmt, i, SQL_C_CHAR, coldata, 256, NULL);
printf("%s ", coldata);
}
printf("/n");
} SQLFreeHandle(SQL_HANDLE_STMT, stmt);
SQLDisconnect(dbc);
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
}
6 多字符多語言的支持
實現多字符集/多語言的支持需要客戶端和服務器的協調工作。DM4服務器能夠以多種字符集來存儲數據,爲了能夠把數據庫中的數據以正確的方式顯示出來,還需要客戶端使用適當的字符集。如果不指定字符集,那麼服務器和客戶端都自動採用系統默認的字符集。
DM4 ODBC3.0擴充了標準函數SQLSetConnectAttr的參數值,提供了設置客戶端字符集的方法,用戶利用這些函數設置客戶端的字符集之後,就由DM4 ODBC3.0自動實現其與服務器所採用的字符集之間的轉換。
調用示例如下:
SQLSetConnectAttr(dbc, 123456, (SQLPOINTER)0, SQL_IS_INTEGER);
在調用DM4 ODBC3.0函數SQLSetConnectAttr時,第二個參數值取123456表示設置字符集,第三個參數的取值參見表6.1。
DM4現在支持的編碼方式以及所對應的編碼代號如表所示:

表6.1:編碼方式及編碼代號表
宏定義 編碼取值
PG_INVALID_CODE 0
PG_UTF8 1
PG_GBK 2
PG_BIG5 3
PG_ISO_8859_9 4
PG_EUC_JP 5
PG_EUC_KR 6
PG_KOI8R 7
PG_ISO_8859_1 8

在 設置字符集時,要考慮字符之間的兼容性。目前,支持國際化的應用程序大多采用Unicode編碼。Unicode標準爲全球商業領域中廣泛使用的大部分字 符定義了一個單一編碼方案,不用擔心繫統是否會錯誤地翻譯位模式。UTF-8是目前應用最廣泛的Unicode編碼方式,推薦用戶採用這種編碼方式。


http://tb.blog.csdn.net/TrackBack.aspx?PostId=1500505
發佈了8 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章