热情软件屋

 

用ODBC API进行编程时,如何使用SQL语句的SELECT语句


编号:QA003969
建立日期: 2001年3月8日 最后修改日期:2002年12月8日
所属类别:

佚名:
    操作系统:win98
    编程工具:VC++ 6.0
    问题:我是一名学VC++ 6.0的高中生,在用ODBC API进行编程时遇到了几天来我一直没能解决的困难,请给予解答是盼!!!
    问题是这样的,我想把SQL语句加到我的程序中去,例如在编一个查询函数时,中心语句用:
     select * from list1(表) where name1(字段名)=某某, 这样就可以比用AddNew()好得多,面且又能提高准确性,还有在进行"事务"处理时,也是非常方便的,一句话就是我想把SQL语句用到我的某个函数中在某方面也许它比普通的编程要烦,但很多方面是非常方便的!!!
    我的程序的在体过程是这样的,第一:打开数据源(即连接数据源);
    第二:向DBMS提交SQL语句(即SQLExecDirect()等;
    第三:获取数据(比例SQLBindCol(),SQLFetch(),SQLGetData()等);
    大体过程就是这样的,我的思想是它(SQL语句)只是对数据源操作而不是对记录集作用,所以它相当于在VC++中的向导过程(即RFX过程由自己来完成sqlbindcol()),打开数据源后,是否还要打开记录集啊?
    我的想法是不是又不对啊?
     下面是我的程序:
    void testdlg::OnSqlrowButton1()
    {
     // TODO: Add your control notification handler code here
     SQLRETURN retcode;
     SQLINTEGER coum_courseeind,mmm;
     SQLCHAR coum_courseeidset[23];
     SQLCHAR godcome[50];
     CDatabase db;
     retcode=db.Open(_T("学生资料"));
     if(retcode==SQL_SUCCESS||retcode==SQL_SUCCESS_WITH_INFO)
     MessageBox("source is opened now"); file://运行结果得此步
     else
     MessageBox("failure to open source");
     COleVariant varname;
     CRecordset rs;
     rs.m_pDatabase=&db;
    // rs.Open();
     SQLCHAR statement[90]="select * from 课程 WHERE 课号='MATH333'";
     SQLBindCol(rs.m_hstmt,1,SQL_C_CHAR,coum_courseeidset,sizeof(coum_courseeidset),
     &coum_courseeind);
     SQLExecDirect(rs.m_hstmt,statement,SQL_NTS);
     if(SQLFetch(rs.m_hstmt)!=SQL_NO_DATA)
     MessageBox("ok,you can fetch your data"); // 运行结果得此步
     else
     MessageBox("fail to get data");
    
     SQLGetData(rs.m_hstmt,1,SQL_C_CHAR,godcome,sizeof(godcome),&mmm);
     char thuf[12];
     sprintf(thuf,"the %s file",godcome);
     AfxMessageBox(thuf); // 结果为"the 烫烫...... y file
    }
    邦定的数据源字段返回的值总是不对!!
    还有SQLBindCol()和SQLGetdata()这两个函数能否对每一个参数都给我详细指点一下,特别是后面的三个参数。
    几天啦,我都没能从这里争脱出来,好困好累,真有点失去信心了,这不是以前的我,真诚盼望你们能给我解答,好吗?若不能请给我个回音,好吗? 还有啊,若可能,请给我一个在一个函数中实现利用SQL的完整例子,谢谢!!

回答:

    通过程序实现对数据库数据的查询时可以使用ODBC API,也可以使用MFC中提供的类CDatabase和CRecordset等。类CDatabase和CRecordset是对ODBC API的封装。而从你提的问题,可以看出你的思路有些混乱了,一会用类库,一会又用ODBC API。
    通过类CDatabase和CRecordset实现对数据库的查询,很简单。其中CDatabase是建立数据库连接,而任何查询语句,都是需要获得查询的结果,所以是需要打开结果集的。
     (1)使用类库进行查询的过程,大体如下:
     CString strConnect;
     strConnect.Format("ODBC;DSN=%s;UID=%s;PWD=%s",m_strCombDSN,m_strUID,m_strPswd);
     CDatabase db;
     if(!db.Open(NULL,FALSE,FALSE,strConnect,TRUE))
     return FALSE;
    
     CString strSql="select * from 课 程 WHERE 课 号 ='MATH333'";
     CRecordset rs(db);
     rs.Open(CRecordset::snapshot, strSQL,
     CRecordset::readOnly | CRecordset::useMultiRowFetch);
     while (!rs.IsEOF())
     {
     //根据情况调用GetODBCFieldCount()、GetRowsFetched、CRecordset::GetFieldValue()等,取出数据
     }
    
     (2)使用ODBC API获得查询结果的方法大体如下:
     RETCODE loc_retcode;
     HDBC loc_hdbc;
     unsigned char* szDSN=(unsigned char *)DSN;
     unsigned char* szUID=(unsigned char *)UID;
     unsigned char* szAuthStr=(unsigned char *)PWD;
    
     loc_retcode=SQLAllocConnect(GDAI_henv,&loc_hdbc); file://创建连接句柄
     if (!(loc_retcode==SQL_SUCCESS || loc_retcode==SQL_SUCCESS_WITH_INFO))
     return -1;
     loc_retcode=SQLConnect(loc_hdbc,szDSN,SQL_NTS,szUID,SQL_NTS,szAuthStr,SQL_NTS);//建立与数据源的连接
     if (!loc_retcode==SQL_SUCCESS)
     {
     GetErrorInfoFromODBC(loc_hdbc);
     SQLFreeConnect(loc_hdbc);//连接失败
     return -1;
     }
    
     SQLAllocStmt(loc_hdbc,&loc_hstmt);
    
     SWORD pccol; file://存放结果集中返回的列数
     char szColName[129];
     short cbColName;
     short sqlType;
     UDWORD ColDef;
     short Scale;
     short Nullable;
     loc_retcode=SQLExecDirect(loc_hstmt, (unsigned char*)pSQL, strlen(pSQL));
     loc_retcode = SQLFetch(loc_hstmt);
     while(loc_retcode ==SQL_SUCCESS||loc_retcode == SQL_SUCCESS_WITH_INFO)
     {
     //取每列数据 例如 SQLGetData(hstmt, icol, SQL_C_CHAR, v_data->data, 511, &pcbValue);
     loc_retcode = SQLFetch(loc_hstmt);
     }
    关于这类数据库功能的原码在VC的例子程序中应该就可以获得。
    
    Odin的意见:
    对ODBC API我不太熟悉,但是下面这个网址中提供的类 SQLDirect是一个类似于CRecordset 的对ODBC的封装。里面有真正的动态绑定的内容。可能可以作为一个好例子。
    http://www.codeguru.com/mfc_database/direct_sql_with_odbc.shtml
    
    forallthenights问:
    请问这条sql语句中
    CString strSql="select * from 课 程 WHERE 课 号 ='MATH333'"
    的math33如果要换成变量该怎么写?
    如果要用m_strFilter,
    是不是m_strFilter="课 号 =" + 变量;
    如果我用m_pDatabase->ExecuteSQL(sql),这个sql该怎么写?
    李海答:
    如果s是一个字符串变量,可以这样写:
    CString strSql="select * from 课 程 WHERE 课 号 ='" + s + "'";

此问题由autumn回答。

 
把这个问题推荐给朋友
   
   
您的意见类别
您的名字
您的电子邮件
您的建议(请尽可能详细)
 
 

版权所有 1997-2008 热情软件屋
如果您有任何建议和意见, 请给我发个电子邮件 askpro@china-askpro.com
Web Designed by ZebraStudio