新手,做课程设计,数据库后台的表写好了,前台用C++写的简陋的控制台程序,在通过ODBC连接好之后,一使用SQL语句就会出现Runtime error    abnormal program termination.
以下是代码,第一处触发崩溃用红色标注:
#include <windows.h> 
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>
#include <string> 
using std::string;
using namespace std; 
/*
C++连接SQL数据库第一步 系统配置
1.设置SQLSERVER服务器为SQL登录方式,并且系统安全性中的sa用户要设置登录功能为“启用”,还有必须要有密码。
2.需要在ODBC中进行数据源配置,数据源选\”SQL SERVER”,登录方式使用“使用输入用户登录ID和密码的SQL SERVER验证”,并填写登录名(sa)和密码,注意一点,密码不能为空,这就意味着你的sa用户必须得有密码。否则无法通过系统本身的安全策略。测试通过就完成了配置。*//*
C++连接SQL数据库第二步 C++与SQL连接初始化
1.在建立的C++项目中引入ADO
具体代码如下:
*/
#pragma warning(disable:4146)
#pragma warning(disable:4786)
#import "c:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
//主程序
int main(){
system("COLOR A"); 
BOOL FLAG=TRUE; 
int  flag=0;
_ConnectionPtr m_pConnection=NULL;  //connection   object's   pointer
_CommandPtr m_pCommand=NULL;             //command   object's   pointer 
_ParameterPtr m_pParameter=NULL;         //Parameter   object's   pointer
_RecordsetPtr m_pRecordset=NULL;
CoInitialize(NULL);                 //COM注册不可少
int userright=0;                    //用户权限,1为读者,2为管理员
char username[12]; /**
定义_ConnectionPtr变量后调用Connection对象的Open方法建立与服务器的连接。
数据类型_ConnectionPtr实际上是由类模板_com_ptr_t得到的一个具体的实例类。
_ConnectionPtr类封装了Connection对象的Idispatch接口指针及其一些必要的操作。可以通过这个指针操纵Connection对象。      
**/ 
//例如连接SQLServer数据库,代码如下:
//连接到MS SQL Server   
//初始化指针 
   HRESULT hr=m_pConnection.CreateInstance(__uuidof(Connection)); 
   if(FAILED(hr))
   return 0;
//初始化链接参数 
   _bstr_t strConnect = "Driver={sql server};server=127.0.0.1;uid=sasa;pwd=123;database=library";  //SQLSERVER
//Database指你系统中的数据库名 
//执行连接 
   try  
   {    
 // Open方法连接字串必须四BSTR或者_bstr_t类型 
   m_pConnection->Open(strConnect,"", "",NULL);  
   } 
   catch(_com_error &e)
   {
 //MessageBox(e.Description(),"警告",MB_OK|MB_ICONINFORMATION); 
   cout<<e.Description()<<endl; 
   }//发生链接错误/**C++连接SQL数据库第三步 简单的数据连接**/ 
//定义_RecordsetPtr变量,调用它Recordset对象的Open,即可打开一个数据集 
//初始化过程 以下是个实例
//RecordsetPtr pRecordset;
//登录 
//*** 
   int loginflag=1; /* 
输入一个数字,确定是读者(1)还是管理员(2)
 */
   int ID=3;
   int IDflag = 1;
   char password[12]; 
   while(ID)
   {
   cout<<"选择身份:"<<endl<<"1.读者"<<endl<<"2.管理员"<<endl<<"进行选择:";
   cin>>ID;/* 进入读者登录界面 */
   if(ID==1)
   {
   system("cls");
   cout<<"输入读者编号:";
   cin>>username;
   cout<<"输入密码:";  
   cin>>password;  
   char sqllogin[100];  
   sprintf(sqllogin,"select * from Reader where Rno='%s' and Rpassword='%s'",username,password); 
   m_pRecordset=m_pConnection->Execute(_bstr_t(sqllogin), NULL, adCmdText);
     if(!m_pRecordset->adoEOF)
   {
   cout<<"登录成功!";  
   cout<<(char*)(_bstr_t)(m_pRecordset->Fields->GetItem(_variant_t("uright"))->Value);
   loginflag=0;      /* 进入读者功能界面 */
  // system("cls"); 
   int rchose=4;
   while(rchose)
   {
   //system("cls");
   cout<<"1.查询图书信息"<<endl;
   cout<<"2.查询借书记录"<<endl; 
   cout<<"3.退出"<<endl;
   cin>>rchose;
   switch(rchose)
   {
   case 1:
   /* 查询图书信息 */
   char strsql1[100];
   sprintf(strsql1,"select * from Book order by Bno asc"); 
   m_pRecordset=m_pConnection->Execute(_bstr_t(strsql1),NULL,adCmdText);
     if(strsql1!=NULL)
   {
   cout<<" 图书编号  "<<"    图书名称 "<<" 图书类型 "<<"  图书定价  "<<" 图书作者 " <<endl; 
   int flag=0;     
   while(!m_pRecordset->adoEOF)  //遍历并读取每列的记录并输出 
   {     
   flag=1;    
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Bno")->Value<<"   ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Bname")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Btype")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Bprice")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Bwriter")->Value<<endl;       
   m_pRecordset->MoveNext();  
   }    
   if(flag==0)   
   cout<<"不存在任何图书!"<<endl; 
   }
   break;
   case 2:
   /* 查询借阅记录 */
   char strsql2[100];
   sprintf(strsql2,"select * from Record where ReRno ='%s' order by Reno asc",username); 
   m_pRecordset=m_pConnection->Execute(_bstr_t(strsql2),NULL,adCmdText); 
   /* 借阅记录全部是该读者的 */
   if(strsql2 !=NULL)
   {
   cout<<" 记录编号 "<<"  图书编号 "<<" 借阅日期"<<"  还书日期 "<<" 借阅数量 " <<"管理员编号 " <<endl; 
   int flag=0;     
   while(!m_pRecordset->adoEOF)  //遍历并读取每列的记录并输出 
   {     
   flag=1;    
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Reno")->Value<<"   ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("ReBno")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Reborrow")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Rereturn")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Recount")->Value<<"      ";   
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("ReAno")->Value<<endl;  
   m_pRecordset->MoveNext();  
   }    
   if(flag==0)   
   cout<<"您还没有任何借书记录!"<<endl; 
   }
   break;
   case 3:
   cout<<"退出!"<<endl;
   break;
   default:
   break;
   }//switch
   }//while
   }//登录成功  
   else   
   cout<<"登录失败,请重新登录!"<<endl;  
   }
   
   /* 进入管理员登录界面 */
   if(ID==2)
   {
   system("cls");
   cout<<"输入管理员编号:";
   cin>>username;
   cout<<"输入密码:";  
   cin>>password;  
   char sqllogin3[100];  
   sprintf(sqllogin3,"select * from Users where Uno='%s' and Upassword='%s'",username,password); 
   m_pRecordset=m_pConnection->Execute(_bstr_t(sqllogin3), NULL, adCmdText);
 
   if(!m_pRecordset->adoEOF)
   {
   cout<<"登录成功!";  
   cout<<(char*)(_bstr_t)(m_pRecordset->Fields->GetItem(_variant_t("uright"))->Value);
   loginflag=0;      /* 进入管理员功能界面 */
   system("cls"); 
   int rchose1=4;
   while(rchose1)
   {   
   system("cls");
   cout<<"1.查询图书信息"<<endl;
   cout<<"2.查询借阅记录"<<endl; 
   cout<<"3.添加借阅记录"<<endl;
   cout<<"4.删除借阅记录"<<endl;
   cout<<"5.退出"<<endl;
   cin>>rchose1;
   switch(rchose1)  
   { 
   case 1:
   /* 查询图书信息 */
   char strsql3[100];
   sprintf(strsql3,"select * from Book order by Bno asc"); 
   m_pRecordset=m_pConnection->Execute(_bstr_t(strsql3),NULL,adCmdText); 
   if(strsql3 !=NULL)
   {
   cout<<" 图书编号  "<<"    图书名称 "<<" 图书类型 "<<"  图书定价  "<<" 图书作者 " <<endl; 
   int flag=0;     
   while(!m_pRecordset->adoEOF)  //遍历并读取每列的记录并输出 
   {     
   flag=1;    
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Bno")->Value<<"   ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Bname")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Btype")->Value<<"      "; 
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Bprice")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Bwriter")->Value<<endl;       
   m_pRecordset->MoveNext();  
   }    
   if(flag==0)   
   cout<<"不存在任何图书!"<<endl; 
   }
   break;
   case 2:
   /* 查询借阅记录 */
   char strsql4[100];
   sprintf(strsql4,"select * from Record where ReAno ='%s' order by Reno asc",username); 
   m_pRecordset=m_pConnection->Execute(_bstr_t(strsql4),NULL,adCmdText); 
   /* 所有借阅记录都是该管理员处理的 */
   if(strsql4 !=NULL)
   {
   cout<<" 记录编号 "<<"  图书编号 "<<" 借阅日期"<<"  还书日期 "<<" 借阅数量 " <<"读者编号 " <<endl; 
   int flag=0;     
   while(!m_pRecordset->adoEOF)  //遍历并读取每列的记录并输出 
   {     
   flag=1;    
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Reno")->Value<<"   ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("ReBno")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Reborrow")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Rereturn")->Value<<"      ";  
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("Recount")->Value<<"      ";   
   cout<<(char*)(_bstr_t)m_pRecordset->GetFields()->GetItem("ReRno")->Value<<endl;  
   m_pRecordset->MoveNext();  
   }    
   if(flag==0)   
   cout<<"您还没有处理过任何借阅记录!"<<endl; 
   }
   break;
   case 3:
   /* 添加借阅记录 */
   cout<<"现在输入一条新的借阅记录!"<<endl;
   getch();
   char reno[10];
   cout<<"记录编号:"; cin>>reno;
   char rebno[10];
   cout<<"图书编号:"; cin>>rebno;
   char reborrow[15];
   cout<<"借阅日期:"; cin>>reborrow;
   char rereturn[15];
   cout<<"还书日期:"; cin>>rereturn;
   char rerno[10];
   cout<<"读者编号:"; cin>>rerno;
   char strsql5[100];
   sprintf(strsql5,"insert into Record values('%s','%s','%s','%s','%s','%s')",reno,rebno,reborrow,rereturn,rerno,username); 
   m_pRecordset=m_pConnection->Execute(_bstr_t(strsql5),NULL,adCmdText); 
   cout<<endl<<"添加借阅记录成功!"<<endl;
   break;
   case 4:
   /* 添加借阅记录 */
   cout<<"现在删除一条借阅记录!"<<endl;
   getch();
   char strsql6[100];
   sprintf(strsql6,"select * from Record where ReAno ='%s' order by Reno asc",username); 
   m_pRecordset=m_pConnection->Execute(_bstr_t(strsql6),NULL,adCmdText); 
   /* 所有借阅记录都是该管理员处理的 */
   if(strsql6 !=NULL)
   {
   cout<<" 记录编号 "<<"  图书编号 "<<" 借阅日期"<<"  还书日期 "<<" 借阅数量 " <<"读者编号 " <<endl; 
   int flag=0;     
   while(!m_pRecordset->adoEOF)  //遍历并读取每列的记录并输出 
   {     
   flag=1;    
…………

解决方案 »

  1.   

    楼主知道你那条select语句返回了多少条记录吗?先在查询分析器中测试相应的查询语句没问题,再在代码中调用。
      

  2.   

    看着像sql语句出错了,先在数据库执行一下试试
      

  3.   

    try catch 捕捉 _com_error参考MSDN的例子#import "c:\Program Files\Common Files\System\ADO\msado15.dll" 
       no_namespace rename("EOF", "EndOfFile")
    #include <stdio.h>
    #include "icrsint.h"void dump_com_error(_com_error &e)
    {
      printf("Error\n");
      printf("\a\tCode = %08lx\n", e.Error());
      printf("\a\tCode meaning = %s", e.ErrorMessage());
      _bstr_t bstrSource(e.Source());
      _bstr_t bstrDescription(e.Description());
      printf("\a\tSource = %s\n", (LPCSTR) bstrSource);
      printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription);
    }class CCustomRs : public CADORecordBinding
    {
      BEGIN_ADO_BINDING(CCustomRs)
        ADO_VARIABLE_LENGTH_BINDING_ENTRY(1, adVarChar, m_szau_lname, 
          sizeof(m_szau_lname), lau_lnameStatus, FALSE)
        ADO_VARIABLE_LENGTH_BINDING_ENTRY(2, adVarChar, m_szau_fname, 
          sizeof(m_szau_fname), lau_fnameStatus, TRUE)
      END_ADO_BINDING()public:
      CHAR   m_szau_lname[41];
      ULONG   lau_lnameStatus;
      CHAR   m_szau_fname[41];
      ULONG   lau_fnameStatus;
    };VOID   main()
    {
      HRESULT hr;
      IADORecordBinding   *picRs = NULL;  ::CoInitialize(NULL);  try 
      {
        _RecordsetPtr pRs.CreateInstance(__uuidof(Recordset));      CCustomRs rs;    pRs->Open("select FirstName, LastName, Age from Employees", 
        "dsn=pubs;uid=sa;pwd=;", 
        adOpenStatic, adLockOptimistic, adCmdUnknown);    if (FAILED(hr = pRs->QueryInterface(__uuidof(IADORecordBinding), 
          (LPVOID*)&picRs)))
        _com_issue_error(hr);    if (FAILED(hr = picRs->BindToRecordset(&rs)))
          _com_issue_error(hr);    while (VARIANT_FALSE == pRs->EndOfFile)
        {
          // 处理 CCustomRs C++ 实例变量中的数据。      printf("\a\tName = %s \t%s", 
          (lau_fnameStatus == adFldOK ? m_szau_fname : "<NULL>"), 
          (lau_lnameStatus == adFldOK ? m_szau_lname): "<NULL>"));      // 更改 Recordset 的当前行。
          // 新当前行的 Recordset 数据将被
          // 自动取出并防止在 CCustomRs C++ 实例变量中      pRs->MoveNext();
        }
      }
      catch (_com_error &e)
      {
        dump_com_error(e);
      }  if (picRs)
        picRs->Release();  CoUninitialize();
    };