第一百二十五个SQLDriverConnect连接数据库
函数定义:
SQLRETURN SQLDriverConnect(
SQLHDBC ConnectionHandle,//hdbc句柄
SQLHWND WindowHandle,//窗口句柄,不显示窗口为NULL
SQLCHAR * InConnectionString,//连接字符串,参照SQLConfigDataSource函数的最后一个参数
SQLSMALLINT StringLength1,//InConnectionString缓存区大小
SQLCHAR * OutConnectionString,//该参数接收连接详细信息。
SQLSMALLINT BufferLength,//OutConnectionString缓存区大小
SQLSMALLINT * StringLength2Ptr,//OutConnectionString实际大小(接收后)
SQLUSMALLINT DriverCompletion);//是否显示连接窗口,SQL_DRIVER_NOPROMPT不显示。
SQLDriverConnect相比SQLConnect函数,功能强大许多,它可以直接连接数据库驱动,不需要通过数据源,当然它也可以连接数据源,SQLDriverConnect完全可以替代SQLConnect函数。
那么连接数据源的时候,如果需要ID和密码,这些信息填在哪里呢,填在InConnectionString连接字符串里。对应的项属性是
UID和PWD。这个参数的解释可以参考SQLConfigDataSource函数的最后一个参数。
SQLDriverConnect函数的InConnectionString多了几个项属性(较之SQLConfigDataSource函数的最后一个参数),前面UID和PWD算两个。还有一个是DRIVER,这个指明驱动名称。
SQLDriverConnect应用例子:
#include<windows.h>
#include<sqlext.h>//SQLConnect函数头文件
#include<iostream.h>
#include <odbcinst.h>//SQLConfigDataSource函数头文件
int main()
{
HENV henv;//数据据源连接需要的环境变量
HDBC hdbc;//数据源连接需要的连接变量
RETCODE rcode;
//连接数据源,项属性用分号隔开,不需要帐号密码验证的话,仅填数据源就行了
SQLCHAR ConnStr[256] = {"DSN=MySqlServer;UID=sa;PWD=123456"};
//直接连接Access数据库
//SQLCHAR ConnStr[256]={"DBQ=d:\\book.mdb;DRIVER=Microsoft Access Driver (*.mdb)"};
//直接连接SQL Server
//SQLCHAR ConnStr[256]={"SERVER=20110304-1717;DATABASE=MyDatabase;DRIVER=SQL Server"};
SQLCHAR OutConnStr[256];
short OutConnStrLen;
//创建环境句柄
SQLAllocEnv(&henv);
HWND desktopHandle = GetDesktopWindow();
//创建连接句柄
SQLAllocConnect(henv,&hdbc);
rcode=::SQLDriverConnect(hdbc,NULL,ConnStr,
SQL_NTS,
OutConnStr,256,&OutConnStrLen,SQL_DRIVER_NOPROMPT);
if(rcode==SQL_SUCCESS||rcode==SQL_SUCCESS_WITH_INFO)
{
cout<<"连接成功!"<<endl;
cout<<OutConnStr<<'\t'<<OutConnStrLen<<endl;
}
else
{
cout<<"连接失败!"<<endl;
}
::SQLDisconnect(hdbc);//解除连接
return 0;
}
第一百二十五个SQLFetchScroll滚动结果集行
前面提到的SQLFetch函数,只能向一个方向移动,就是当游标在第一行的时候,调用SQLFetch函数获得的是第二行的数据(关联的变量)。
而SQLFetchScroll不仅能向下一行移动,还能向上一行移动。也能获取特定行的数据。。
函数定义:SQLRETURN SQLFetchScroll(
SQLHSTMT StatementHandle,//hstmt句柄
SQLSMALLINT FetchOrientation,//标明,向前移动,还是向后移动。或者特定行。
SQLLEN FetchOffset);//用于特定行,指明移动到哪行,也就获取哪行数据。向后或向前无意义,为0
第二个参数FetchOrientation有以下取值:
SQL_FETCH_NEXT//获取下一行
SQL_FETCH_PRIOR//获取上一行
SQL_FETCH_FIRST //获取首行
SQL_FETCH_LAST //获取最后一行
SQL_FETCH_ABSOLUTE //用于特指获取哪一行,FetchOffset指明行数
SQL_FETCH_RELATIVE //用于特指获取哪一行,位置为相对。如当前在第二行,FetchOffset为2,那么获取的是第4行。
如果直接调用SQLFetchScroll函数,会发现除了SQL_FETCH_PRIOR和SQL_FETCH_NEXT参数有效外,其它参数都无效,是什么原因呢。。是由于hstmt的属性造成的,默认属性规定游标只能向前移动。也就是SQL_CURSOR_FORWARD_ONLY。
(这里前一行,上行都给我搞乱了,FORWARD是向前的意思,NEXT是下一行的意思。。。没个统一的叫法,真搞不明白)
我们只要将HSTMT的SQL_ATTR_CURSOR_TYPE游标属性设置成静态的就行了。也就是SQL_CURSOR_STATIC。
用SQLSetStmtAttr函数可以设置。这个函数可以到MSDN里查。这里我只用它设置一下属性就行了,解决上面的问题。设置的语句哪下:
SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (void *)SQL_CURSOR_STATIC, SQL_IS_INTEGER);
接着来一个简单例子,获取特定行的数据。
#include<windows.h>
#include<sqlext.h>//SQLConnect函数头文件
#include<iostream.h>
#include <odbcinst.h>//SQLConfigDataSource函数头文件
int main()
{
HENV henv;//数据据源连接需要的环境变量
HDBC hdbc;//数据源连接需要的连接变量
HSTMT hstmt;//语句变量
RETCODE rcode;
//创建环境句柄
SQLAllocEnv(&henv);
//创建连接句柄
SQLAllocConnect(henv,&hdbc);
rcode=::SQLConnect(hdbc,(PUCHAR)"MySqlServer",SQL_NTS,NULL,0,
NULL,0);
if(rcode==SQL_SUCCESS||rcode==SQL_SUCCESS_WITH_INFO)
{
cout<<"连接数据源成功!"<<endl;
}
else
{
cout<<"连接失败!"<<endl;
}
::SQLAllocStmt(hdbc,&hstmt);
LPSTR pszSQL=new char[52];
//假设数据库里表名为Student
strcpy(pszSQL,"Select * from Student");
//执行SQL语句
//设置静态游标
SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, (void *)SQL_CURSOR_STATIC, SQL_IS_INTEGER);
rcode=::SQLExecDirect(hstmt,(UCHAR *)pszSQL,SQL_NTS);
if(rcode==SQL_SUCCESS)
{
cout<<"执行SQL语句成功!"<<endl;
char *pStuNo=new char[256];//绑定的变量,学号
long StuNolen;//实际获取数据的大小
//绑定变量
SQLBindCol(hstmt,1,SQL_C_CHAR,pStuNo,256,&StuNolen);//第一列
//获取第二行的学号,学号最好按顺序排,如第一行001,第二行002,这样好查看结果的时候好区分的些。
rcode=SQLFetchScroll(hstmt,SQL_FETCH_ABSOLUTE,2);
cout<<pStuNo<<endl;
SQLCancel(hstmt);
}
else
{
cout<<"执行失败!"<<endl;
}
::SQLDisconnect(hdbc);//解除连接
return 0;
}