新手,做課程設計,資料庫后臺的表寫好了,前臺用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;
…………
uj5u.com熱心網友回復:
我的代碼應該沒有邏輯和語法問題,求大神指教為什么uj5u.com熱心網友回復:
求指導惹,拜托拜托uj5u.com熱心網友回復:
樓主知道你那條select陳述句回傳了多少條記錄嗎?先在查詢分析器中測驗相應的查詢陳述句沒問題,再在代碼中呼叫。
uj5u.com熱心網友回復:
看下函式是否會拋出例外?uj5u.com熱心網友回復:
捕捉例外,看看報什么錯uj5u.com熱心網友回復:
看著像sql陳述句出錯了,先在資料庫執行一下試試uj5u.com熱心網友回復:
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();
};
uj5u.com熱心網友回復:
所查詢的欄位與資料庫表中的欄位不符,或數目不等。 一般是陳述句錯誤。轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/129725.html
標籤:數據庫
