?? 用visual c++開發(fā)數據庫應用程序.txt
字號:
SQLDisconnect(hdbc);
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
SQLDriveConnect
函數SQLDriveConnect用一個連接字符串建立至數據源的連接。它可以提供比SQLConnect函數的三個參數更多的信息,可以讓用戶輸入必要的連接信息。
如果連接建立,該函數返回完整的字符串,應用程序可使用該連接字符串建立另外的連接。
函數格式:
SQLRETURN SQLDriverConnect(SQLHDBC ConnectionHandle,SQLHWND WindowHandle,SQLCHAR InConnectionString,SQLSMALLINT StringLength1,SQLCHAR OutConnetionString,SQLSMALLINT BufferLength,SQLSMALLINT *StringLength2Ptr,SQLSMALLINT DriverCompletion);
參數:
ConnectionHandle 連接句柄
WindowHandle 窗口句柄,應用程序可以用父窗口的句柄,或用NULL指針
InConnectionString 連接字符串長度
OutConnectionString 一個指向連接字符中的指針
BufferLength 存放連接字符串的緩沖區(qū)的長度
StringLength2Ptr 返回的連接字符串中的字符數
DriverCompletion 額外連接信息,可能取值有:SQL_DRIVER_PROMPT,
SQL_DRIVER_COMPLETE,
SQL_DRIVER_COMPLETE_REQUIRED, or
SQL_DRIVER_NOPROMPT.
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
成功返回SQL_SUCCESS,如果返回值為SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函數SQLGetDiagRec獲取相應SQLSTATE的值。
SQLBrowseConnect
函數SQLBrowseConnect支持以一種迭代的方式獲取到數據源的連接,直到最后建立連接。它是基于客房機/服務器的體系結構,因此,本地數據庫不支持該函數。
一般,我們提供部分連接信息,如果足以建立到數據源的連接,則成功建立連接,否則返回SQL__NEED__DATA,并在OutConnectionString參數中返回所需要的信息。
函數格式:
SQLRETURN SQLBrowseConnect(SQLHDBC ConnectionHandle,SQLCHAR* InConnectionString,SQLSAMLLINT StringLength1,SQLCHAR* OutConnectionString,SQLSMALLINT BufferLength,SQLSMALLINT *StringLength2Ptr);
參數:
ConnectionHandle 連接句柄
InConnectionString 指向輸出字符串的指針
StringLength1 輸出字符串的指針長度
OutConnectionString 指向輸出字符串的指針
BufferLength 用于存放輸出字符串的緩沖區(qū)的長度
StringLength2Ptr 實際返回的字符串的長度
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.
成功返回SQL_SUCCESS,如果返回值為SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函數SQLGetDiagRec獲取相應SQLSTATE的值。
下面的代碼講述了如何使用ODBC API的SQLBrowseConnect函數建立同數據源的連接。
#define BRWS_LEN 100SQLHENV
henv;SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLCHAR szConnStrIn[BRWS_LEN], szConnStrOut[BRWS_LEN];
SQLSMALLINT cbConnStrOut;/* Allocate the environment handle. */
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
/* Set the version environment attribute. */
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3, 0);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
/* Allocate the connection handle. */
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
/* Call SQLBrowseConnect until it returns a value other than */
/* SQL_NEED_DATA (pass the data source name the first time). */
/* If SQL_NEED_DATA is returned, call GetUserInput (not */
/* shown) to build a dialog from the values in szConnStrOut. */
/* The user-supplied values are returned in szConnStrIn, */
/* which is passed in the next call to SQLBrowseConnect. */
lstrcpy(szConnStrIn, "DSN=Sales"); do {
retcode = SQLBrowseConnect(hdbc, szConnStrIn, SQL_NTS,
szConnStrOut, BRWS_LEN, &cbConnStrOut);
if (retcode == SQL_NEED_DATA)
GetUserInput(szConnStrOut, szConnStrIn);
} while (retcode == SQL_NEED_DATA);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){
/* Allocate the statement handle. */
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
/* Process data after successful connection */ ...;
SQLFreeHandle(SQL_HANDLE_STMT, hstmt); }
SQLDisconnect(hdbc); } }
SQLFreeHandle(SQL_HANDLE_DBC, hdbc); }}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
2.24 SQL操作
構造和執(zhí)行SQL語句
構造SQL語句
可以通過三種方式構造SQL語句:在程序開發(fā)階段確定、在運行時確定或由用戶輸入SQL語句。
在程序開發(fā)時確定的SQL語句,具有易于實現(xiàn)、且可在程序編碼時進行測試的優(yōu)勢。
在程序運行時確定SQL語句提供了極大靈活性,但給程序高度帶來了困難,且需更多的處理時間。由用戶輸入的SQL語句,極大的增強了程序的功能,但是,程序必須提供友好的人機界面,且對用戶輸入的語句執(zhí)行一定程序的語法檢查,能夠報告用戶錯誤。
執(zhí)行SQL語句
應用程序的絕大部分數據庫訪問工作都是通過執(zhí)行SQL語句完成的,在執(zhí)行SQL語句之前,必須要先分配一個語句句柄,然后設置相應語句的語句屬性,再執(zhí)行SQL語句。當一個語句句柄使用完成后,調用函數SQLFreeHandle()釋放該句柄。
SQLExecute()
SQLExecute用于執(zhí)行一個準備好的語然,當語句中有參數時,用當前綁定的參數變量的值。
函數格式:
SQLRETURN SQLExecute(SQLHSTMT StatementHandle);
參數:
StatementHandle 標識執(zhí)行SQL語句的句柄,可以用SQLAllocHandle()來獲得。
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值為SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函數SQLGetDiagRec獲取相應SQLSTATE的值。
SQLExecDiret()
SQLExecDirect直接執(zhí)行SQL語句,對于只執(zhí)行一次的操作來說,該函數是速度最快的方法。
函數格式:
SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle,SQLCHAR *StatementText,SQLINTEGER TextLength);
參數:
StatementHandle 語句句柄
StatementText 要執(zhí)行的SQL語然
StatementText SQL語句的長度。
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值為SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函數SQLGetDiagRec獲取相應SQLSTATE的值。
SQLPripare()
對于需多次執(zhí)行的SQL語句來說,除了使用SQLExecDirect函數之外,我們也可以在執(zhí)行SQL語句之前,先準備SQL語句的執(zhí)行。對于使用參數的語句,這可大提高程序執(zhí)行速度。
函數格式:
SQLRETURN SQLPrepare(SQLHSTMT StatementHandle,SQLCHAR* StatementText,SQLINTEGER TextLength);
參數:
StatementHandle 語句句柄
StatementText 要執(zhí)行的SQL語然
StatementText SQL語句的長度。
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值為SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函數SQLGetDiagRec獲取相應SQLSTATE的值。
使用參數
使用參數可以使一條SQL語句多次執(zhí)行,得到不同結果
SQLBindParameter
函數SQLBindParameter負責為參數定義變量,實現(xiàn)參數值的傳遞。
函數格式如下:
SQLRETURNSQLBindParameter(SQLHSTMT StatementHandle,SQLUSMALLINT ParameterNumber,SQLSMALLINT InputOutputType,SQLSMALLINT ValueType,SQLSMALLINT ParameterType,SQLUINTEGER ColumnSize,SQLSMALLINT DecimalDigits,SQLPOINTER ParameterValuePtr,SQLINTEGER BufferLength,SQLINTEGER *StrLen_or_IndPtr);
參數:
StatementHandle 語句句柄
ParameterNumber 綁定的參數在SQL語句中的序號,在SQL中,所有參數從左到右順序編號,從1開始。SQL語句執(zhí)行之前,應該為每個參數調用函數SQLBindParameter綁定到某個程序變量。
InputOutputType 參數類型,可為SQL_PARA_INPUT, SQL_PARAM_INPUT_OUTPUT, SQL_PARAM_OUTPUT。
ParameterType 參數數據類型
ColumnSIze 參數大小
DecimalDigits 參數精度
ParameterValutePtr 指向程序中存放參數值的緩沖區(qū)的指針
BufferLength 程序中存放參數值的緩沖區(qū)的字節(jié)數
StrLen_or_IndPtr 指向存放參數ParameterValuePtr的緩沖區(qū)指針
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值為SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函數SQLGetDiagRec獲取相應SQLSTATE的值。
執(zhí)行時傳遞參數
對于某些文本文檔或位圖文件,要占用大量的存儲空間。因此,在數據源傳遞這些數據時,可以分開傳遞。有兩個函數可完成這個工作。
函數格式:
SQLRETURN SQLPutData(SQLHSTMT StatementHandle,
SQLPOINTER DataPtr,SQLINTEGER StrLen_or_Ind);
參數:
StatementHandle 參數句柄
DataPtr 指向包含實際數據的緩沖區(qū)指針。
StrLen_or_Lnd 緩沖區(qū)長度
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值為SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函數SQLGetDiagRec獲取相應SQLSTATE的值。
函數格式:
SQLRETURNSQLParamData(SQLHSTMT StatementHandle,SQLPOINTER *ValuePtrPtr);
參數:
StatementHandle 參數句柄
ValuePtrPtr 指向緩沖區(qū)地址的指針
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值為SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函數SQLGetDiagRec獲取相應SQLSTATE的值。
下面的代碼展示如何使用這兩個函數
#define MAX_DATA_LEN 1024
SQLINTEGER cbPartID = 0, cbPhotoParam, cbData;
SQLUINTEGER sPartID; szPhotoFile;
SQLPOINTER pToken, InitValue;
SQLCHAR Data[MAX_DATA_LEN];
SQLRETURN retcode;
SQLHSTMT hstmt;
retcode = SQLPrepare(hstmt, "INSERT INTO PICTURES (PARTID, PICTURE) VALUES
(?, ?)", SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
/* Bind the parameters. For parameter 2, pass */
/* the parameter number in ParameterValuePtr instead of a buffer */
/* address. */ SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG,
SQL_INTEGER, 0, 0, &sPartID, 0, &cbPartID);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT,
SQL_C_BINARY, SQL_LONGVARBINARY,
0, 0, (SQLPOINTER) 2, 0, &cbPhotoParam);
/* Set values so data for parameter 2 will be */
/* passed at execution. Note that the length parameter in */
/* the macro SQL_LEN_DATA_AT_EXEC is 0. This assumes that */
/* the driver returns "N" for the SQL_NEED_LONG_DATA_LEN */
/* information type in SQLGetInfo. */
cbPhotoParam = SQL_LEN_DATA_AT_EXEC(0);
sPartID = GetNextID(); /* Get next available employee ID */
/* number. */ retcode = SQLExecute(hstmt);
/* For data-at-execution parameters, call SQLParamData to */
/* get the parameter number set by SQLBindParameter. */
/* Call InitUserData. Call GetUserData and SQLPutData */
/* repeatedly to get and put all data for the parameter. */
/* Call SQLParamData to finish processing this parameter */
while (retcode == SQL_NEED_DATA) {
retcode = SQLParamData(hstmt, &pToken);
if (retcode == SQL_NEED_DATA) {
InitUserData((SQLSMALLINT)pToken, InitValue);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -