登录注册
上海交通大学论坛 > 数据库 > 浏览当前帖子 手机版 关闭左侧栏
用VC开发数据库(二)*转载*
返回本版】  【发表帖子】  【回复帖子 浏览量  4354      回帖数 0
老女孩    等级  

楼主 发表于  2011/10/14 18:17:22    编 辑   


2、 使用ODBC API 
Microsoft 开放数据库互连(ODBC,Open DataBase Connectivity)是Microsoft Windows 
 开放服务体系(WOSA)的一部分,是一个数据库访问的标准接口。使用这一标准接口, 
我们可以不关心具体的数据库管理系统(DBMS)的细节,而只要有相应类型数据库的OD 
BC驱动程序,就可以实现对数据库的访问。 
ODBC编程接口为我们提供了极大的灵活性,我们可以通过这一个接口访问不同种类的数 
据库。而且,通过相应的ODBC驱动程序,我们可以方便地实现不同数据类型之间的转换 
。 
2.1 ODBC API 概述 
ODBC是一个应用广泛的数据库访问应用编程接口(API),使用标准的SQL(结构化查询 
语言)作为其数据库访问语言。 
2.11体系结构 
ODBC的结构是建立在客户机/服务器体系结构之上,它包含如下四个部分: 
应用程序(Application ): 
应用程序即用户的应用,它负责用户与用户接口之间的交互操作,以及调用ODBC函数以 
给出SQL请求并提取结果以及进行错误处理。 
ODBC驱动程序管理器(Driver Manager)
ODBC驱动程序管理器为应用程序加载和调用驱动程序,它可以同时管理多个应用程序和 
多个驱动程序。它的功能是通过间接调用函数和使用动态链接库(DLL)来实现的,因此 
它一般包含在扩展名为”DLL”的文件中。 
ODBC驱动程序(Driver) 
ODBC 驱动程序执行ODBC函数调用,呈送 SQL 请求给指定的数据源,并将结果返回给应 
用程序。驱动程序也负责与任何访问数据源的必要软件层进行交互作用,这种层包括与 
底层网络或文件系统接口的软件。 
数据源 
数据源由数据集和与其相关联的环境组成,包括操作系统、DBMS 和网络(如果存在的话 
)。ODBC 通过引入“数据源”的概念解决了网络拓扑结构和主机的大范围差异问题,这 
样,用户看到的是数据源的名称而不必关心其它东西。 
2.12数据类型 
ODBC使用两类数据类型:SQL数据类型和C数据类型。SQL数据类型用于数据源,C数据类 
型用于应用程序代码中。 
2.13句柄 
ODBC API 实现数据库操作的手段是语句,这是一个强有力的手段。ODBC语句除了能执行 
SQL语句和完成查询操作之外,还能实现大多数数据库操作。 
在ODBC中,使用不同的句柄(HANDLE)来标志环境(ENVIRONMENT)、连接(CONNECTION)、 
语句(STATEMENT)、描述器(DESCRIPTOR)等。 
句柄就是一个应用程序变量,系统用它来存储关于应用程序的上下文信息和应用程序所 
用到的一些对象。它和 Windows 编程中的概念类似,不过ODBC 更加完善了句柄的作用 
。 
1、 环境句柄是 ODBC 中整个上下文的句柄,使用 ODBC 的每个程序从创建环境句柄开 
始,以释放环境句柄结束。所有其它的句柄(这一应用程序所有的联接句柄和语句句柄 
)都由环境句柄中的上下文来管理。环境句柄在每个应用程序中只能创建一个。 
2、联接句柄管理有关联接的所有信息。联接句柄可以分配多个,这不仅合法而且很有用 
;但不要生成不必要的句柄以免资源的浪费。但是,不同的驱动程序支持的联接情况有 
所不同,有的驱动程序在一个应用程序中仅支持一个联接句柄,有的驱动程序仅支持一 
个语句句柄。在应用程序中,可以在任何适当的时候联接或脱离数据源,但不要轻易地 
建立或脱离联接。 
3、语句句柄是 ODBC API 真正发挥重要作用的,它被用来处理 SQL 语句及目录函数, 
每个语句句柄只与一个联接有关。当驱动程序接收一个来自应用程序的函数调用指令而 
该指令包含一个语句句柄时,驱动程序管理器将使用存储在语句句柄中的联接句柄来将 
这一函数调用发送给合适的驱动程序。 
4、描述器句柄是元数据的集合,这些元数据描述了SQL语句的参数、记录集的列等信息 
。当有语句被分配内存之后,描述器自动生成,称为自动分配描述器。在程序中,应用 
程序也可调用SQLAllocHandle分配描述器。 
当应用程序调用API函数SQLAllocHandle时,驱动管理器或者ODBC驱动程序将为所声明的 
句柄类型分配内部结构,返回句柄值。 
2.14异常处理 
为了在程序开发过程中调试程序,发现程序错误,ODBC API通过两种方式返回有关ODBC 
 API函数执行的的信息:返回码和诊断记录。返回码返回函数执行的返回值,说明函数 
执行成功与否。诊断记录说明函数执行的详细信息。 
返回码(Return Code) 
每一个ODBC API函数都返回一个代码——返回码,指示函数执行的成功与否。如果函数 
调用成功,返回码为SQL_SUCCESS或SQL_SUCCESS_WITH_INFO。SQL_SUCCESS指示可通过诊 
断记录获取有关操作的详细信息,SQL_SUCCESS_WITH_INFO指示应用程序执行结果带有警 
告信息,可通过诊断记录获取详细的信息。如果函数调用失败,返回码为SQL_ERROR。 
下面的一段代码根据函数SQLFetch()执行的返回码,判断函数执行的成功与否,从而据 
此进行相应的处理。 
SQLRETURN rtcode; 
SQLHSTMT hstmt; 
While(rtcode=SQLFetch(hstmt)!=SQL_NO_DATA) 

if(rtcode==SQL_SUCCESS_WITH_INFO) 

//显示警告信息 

else 

//显示出错信息 
break; 

//函数调用成功,进行处理 

如果程序执行错误,返回码为SQL_INVALID_HANDLE,程序无法执行,而其它的返回码都 
带有程序执行的信息。 
诊断记录(Diagnostic Records) 
每个ODBC API函数都能够产生一系列的反映操作信息的诊断记录。这些诊断记录放在相 
关连的ODBC句柄中,直到下一个使用同一个句柄的函数调用,该诊断记录一直存在。诊 
断记录的大小没有限制。 
诊断记录有两类:头记录(Head Record)和状态记录(Status Record)。头记录是第 
一版权法记录(Record 0),后面的记录为状态记录。诊断记录有许多的域组成,这些域 
在头记录和状态记录中是不同的。 
可以用SQLGetDiagField函数获取诊断记录中的特定的域,另外,可以使用SQLGetDiagR 
ec()获取诊断记录中一些常用的域,如SQLSTATE、原始错误号等。 
头记录 
头记录的各个域中包含了一个函数执行的通用信息,无论函数执行成功与否,只要不返 
回SQL_INVALID_HANDLE,都会生成头记录。 
状态记录 
状态记录中的每个域包含了驱动管理器、ODBC驱动程序或数据源返回的特定的错误或警 
告信息,包括SQLSTATE、原始错误码、诊断信息、列号和行号等。只有函数执行返回SQ 
L_ERROR,SQL_STILL_EXEUTING、SQL_SUCCESS_WITH_INFO、SQL_NEED_DATA或SQL_NO_DAT 
A时,才会生成诊断记录。 
使用SQLGetDiagRec和SQLGetDiagField 
应用程序可以调用函数SQLGetDiagRec或SQLGetDiagField获取诊断信息。对于给定的句 
柄,这两个函数返回最近使用该句柄的函数的诊断信息。当有使用该句柄的函数执行时 
,句柄记录所记录的原有的诊断信息被覆盖。如果函数执行后产生多个状态记录,程序 
必须多次调用这两个函数以获取信息。 
2.2 应用ODBC API建立应用程序 
虽然直接应用ODBC API编制应用程序相对来说较为繁琐,但是,由于直接使用ODBC API 
编写的程序相对要简洁、高效。所以,我们有必要学习直接使用ODBC API编程。 
一般地,编写ODBC程序主要有以下几个步骤: 
分配ODBC环境 
分配连接句柄 
连接数据源 
构造和执行SQL语句 
取得执行结果 
断开同数据源的连接 
释放ODBC环境 
2.21 分配ODBC环境 
对于任何ODBC应用程序来说,第一步的工作是装载驱动程序管理器,然后初始化ODBC环 
境,分配环境句柄。 
首先,程序中声明一个SQLHENV类型的变量,然后调用函数SQLAllocHandle,向其中传递 
分配的上述SQLHENV类型的变量地址和SQL_HANDLE_ENV选项。如下代码所示: 
SQLHENV henv; 
SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv); 
执行该调用语句后,驱动程序分配一个结构,该结构中存放环境信息,然后返回对应于 
该环境的环境句柄。 
2.22分配连接句柄 
分配环境句柄后,在建立至数据源的连接之前,我们必须分配一个连接句柄,每一个到 
数据源的连接对应于一个连接句柄。 
首先,程序定义了一个SQLHDBC类型的变量,用于存放连接句柄,然后调用SQLAllocHan 
dle函数分配句柄。如下代码所示: 
SQLHDBC hdbc; 
SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc); 
henv为环境句柄。 
2.23 连接数据源 
当连接句柄分配完成后,我们可以设置连接属性,所有的连接属性都有缺省值,但是我 
们可以通过调用函数SQLSetConnectAttr()来设置连接属性。用函数SQLGetConnectAttr 
()获取这些连接属性。 
函数格式如下: 
SQLRETURN SQLSetConnectAttr(SQLHDBC ConnectionHandle,SQLINTEGER Attribute,SQ 
LPOINTER valuePtr,SQLINTEGER StringLength); 
SQLRETURN SQLGetConnectAttr(SQLHDBC ConnectionHandle,SQLINTEGER Attribute,SQ 
LPOINTER valuePtr,SQLINTEGER StringLength); 
应用程序可以根据自己的需要设置不同的连接属性。 
完成对连接属性的设置之后,就可以建立到数据源的连接了。对于不同的程序和用户接 
口,可以用不同的函数建立连接:SQLConnect、SQLDriverConnect、SQLBrowseConnect 
。 
SQLConnect 
该函数提供了最为直接的程序控制方式,我们只要提供数据源名称、用户ID和口令,就 
可以进行连接了。 
函数格式
SQLRETURN SQLConnect(SQLHDBC ConnectionHandle,SQLCHAR ServerName,SQLSMALLINT 
 NameLength1,SQLCHAR UserName,SQLSMALLINT NameLength2,SQLCHAR *Authenticatio 
n,SQLSMALLINT NameLength3); 
参数
ConnectionHandle 连接句柄 
ServerName 数据源名称 
NameLength1 数据源名称长度 
UserName 用户ID 
NameLength2 用户ID长度 
Authentication 用户口令 
NameLength3 用户口令长度 
返回值
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE. 
成功返回SQL_SUCCESS,如果返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函数 
SQLGetDiagRec获取相应SQLSTATE的值。 
  
下面的代码演示了如何使用ODBC API的SQLConnect函数建立同数据源SQLServer的连接。 

  
#include “sqlext.h” 
SQLHENV henv;; 
SQLHDBC hdbc; 
SQLHSTMT hstmt; 
SQLRETURN retcode; 
/*Allocate environment handle */ 
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); 
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { 
/* Set the ODBC version environment attribute */ 
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0) 

if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { 
/* Allocate connection handle */ 
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); 
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { 
/* Set login timeout to 5 seconds. */ 
SQLSetConnectAttr(hdbc, (void*)SQL_LOGIN_TIMEOUT, 5, 0); 
/* Connect to data source */ 
retcode = SQLConnect(hdbc, (SQLCHAR*) "Sales", SQL_NTS, 
(SQLCHAR*) "JohnS", SQL_NTS, 
(SQLCHAR*) "Sesame", SQL_NTS); 
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){ 
/* Allocate statement handle */ 
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { 
/* Process data */; 
SQLFreeHandle(SQL_HANDLE_STMT, hstmt); 

SQLDisconnect(hdbc); 

SQLFreeHandle(SQL_HANDLE_DBC, hdbc); 


SQLFreeHandle(SQL_HANDLE_ENV, henv); 
SQLDriveConnect 
函数SQLDriveConnect用一个连接字符串建立至数据源的连接。它可以提供比SQLConnec 
t函数的三个参数更多的信息,可以让用户输入必要的连接信息。 
如果连接建立,该函数返回完整的字符串,应用程序可使用该连接字符串建立另外的连 
接。 
函数格式
SQLRETURN SQLDriverConnect(SQLHDBC ConnectionHandle,SQLHWND WindowHandle,SQL 
CHAR InConnectionString,SQLSMALLINT StringLength1,SQLCHAR OutConnetionString 
,SQLSMALLINT BufferLength,SQLSMALLINT *StringLength2Ptr,SQLSMALLINT DriverCo 
mpletion); 
参数: 
ConnectionHandle 连接句柄 
WindowHandle 窗口句柄,应用程序可以用父窗口的句柄,或用NULL指针 
InConnectionString 连接字符串长度 
OutConnectionString 一个指向连接字符中的指针 
BufferLength 存放连接字符串的缓冲区的长度 
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* InConnectionStr 
ing,SQLSAMLLINT StringLength1,SQLCHAR* OutConnectionString,SQLSMALLINT Buffe 
rLength,SQLSMALLINT *StringLength2Ptr); 
参数: 
ConnectionHandle 连接句柄 
InConnectionString 指向输出字符串的指针 
StringLength1 输出字符串的指针长度 
OutConnectionString 指向输出字符串的指针 
BufferLength 用于存放输出字符串的缓冲区的长度 
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操作 
构造和执行SQL语句 
构造SQL语句 
可以通过三种方式构造SQL语句:在程序开发阶段确定、在运行时确定或由用户输入SQL 
语句。 
在程序开发时确定的SQL语句,具有易于实现、且可在程序编码时进行测试的优势。 
在程序运行时确定SQL语句提供了极大灵活性,但给程序高度带来了困难,且需更多的处 
理时间。由用户输入的SQL语句,极大的增强了程序的功能,但是,程序必须提供友好的 
人机界面,且对用户输入的语句执行一定程序的语法检查,能够报告用户错误。 
执行SQL语句 
应用程序的绝大部分数据库访问工作都是通过执行SQL语句完成的,在执行SQL语句之前 
,必须要先分配一个语句句柄,然后设置相应语句的语句属性,再执行SQL语句。当一个 
语句句柄使用完成后,调用函数SQLFreeHandle()释放该句柄。 
SQLExecute() 
SQLExecute用于执行一个准备好的语然,当语句中有参数时,用当前绑定的参数变量的 
值。 
函数格式: 
SQLRETURN SQLExecute(SQLHSTMT StatementHandle); 
参数
StatementHandle 标识执行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直接执行SQL语句,对于只执行一次的操作来说,该函数是速度最快的方 
法。 
函数格式: 
SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle,SQLCHAR *StatementText,SQLI 
NTEGER TextLength); 
参数
StatementHandle 语句句柄 
StatementText 要执行的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() 
对于需多次执行的SQL语句来说,除了使用SQLExecDirect函数之外,我们也可以在执行 
SQL语句之前,先准备SQL语句的执行。对于使用参数的语句,这可大提高程序执行速度 
。 
函数格式
SQLRETURN SQLPrepare(SQLHSTMT StatementHandle,SQLCHAR* StatementText,SQLINTE 
GER TextLength); 
参数
StatementHandle 语句句柄 
StatementText 要执行的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语句多次执行,得到不同结果 
SQLBindParameter 
函数SQLBindParameter负责为参数定义变量,实现参数值的传递。 
函数格式如下: 
SQLRETURNSQLBindParameter(SQLHSTMT StatementHandle,SQLUSMALLINT ParameterNum 
ber,SQLSMALLINT InputOutputType,SQLSMALLINT valueType,SQLSMALLINT ParameterT 
ype,SQLUINTEGER ColumnSize,SQLSMALLINT DecimalDigits,SQLPOINTER ParameterVal 
uePtr,SQLINTEGER BufferLength,SQLINTEGER *StrLen_or_IndPtr); 
参数: 
StatementHandle 语句句柄 
ParameterNumber 绑定的参数在SQL语句中的序号,在SQL中,所有参数从左到右顺序编 
号,从1开始。SQL语句执行之前,应该为每个参数调用函数SQLBindParameter绑定到某 
个程序变量。 
InputOutputType 参数类型,可为SQL_PARA_INPUT, SQL_PARAM_INPUT_OUTPUT, SQL_PA 
RAM_OUTPUT。 
ParameterType 参数数据类型 
ColumnSIze 参数大小 
DecimalDigits 参数精度 
ParameterValutePtr 指向程序中存放参数值的缓冲区的指针 
BufferLength 程序中存放参数值的缓冲区的字节数 
StrLen_or_IndPtr 指向存放参数ParametervaluePtr的缓冲区指针 
返回值: 
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE 
成功返回SQL_SUCCESS,如果返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函数 
SQLGetDiagRec获取相应SQLSTATE的值。 
执行时传递参数 
对于某些文本文档或位图文件,要占用大量的存储空间。因此,在数据源传递这些数据 
时,可以分开传递。有两个函数可完成这个工作。 
函数格式: 
SQLRETURN SQLPutData(SQLHSTMT StatementHandle, 
SQLPOINTER DataPtr,SQLINTEGER StrLen_or_Ind); 
参数: 
StatementHandle 参数句柄 
DataPtr 指向包含实际数据的缓冲区指针。 
StrLen_or_Lnd 缓冲区长度 
返回值
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 指向缓冲区地址的指针 
返回值: 
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 SQLPar
1
表情
所有内容均为会员自愿发表,并不代表本站立场.
论坛帮助 会员认证删帖申请 联系我们