天天看點

VC++連接配接資料庫SQL2000應用執行個體及登陸退出

我自己做了個用SQL2000聯接的例子,請大家幫我看看,有什麼不足還望指教。如能得到您的點滴指點

都将萬分感謝。

這個例子現在隻能操作一張表,要想操作整個庫也不難,就是改SQL語句,然後配好資料庫,建議使用存儲過程

正文:

簡易資料庫系統

第一部分:用ADO連接配接SQL Server 2000

1 在STDafx.h中加入動态連接配接庫msado15.dll,并重命名EOF為adoEOF,加在該檔案後面(藍色#endif後面,要是編譯時有錯誤說明位置不對)

#import "D:/Program Files/Common Files/System/ado/msado15.dll"/

no_namespace rename("EOF","adoEOF")

2 在App類中定義連接配接字元串。我的是CADOApp,檔案是ADO.h

_ConnectionPtr m_pConnection;

3 在資料操作類InitInstance()中初始化COM類庫

//這就是初始化COM庫

//應用程式主類的InitInstance成員函數裡初始化OLE/COM庫環境

if (!AfxOleInit()) {

AfxMessageBox("OLE/COM初始化失敗");

return FALSE;

}

theApp.m_pConnection.CreateInstance(__uuidof(Connection));

要在其它操作前面初始化,我的是dlg,原來在它後面初始化的結果走不到那一步,是以m_pConnection總是為NULL/0x000000000

4 再要操作的地方初始化結果集和連接配接字元串,我的是在一個按鈕裡

void CADOAccessDlg::OnBtnExec()

{

m_pRecordset.CreateInstance(__uuidof(Recordset));

CString strLink;//連接配接字元串

try

{ strLink.Format("Provider=SQLOLEDB;server=ZHAOPENG;UID=sa;PWD=sa;database=MD200");

theApp.m_pConnection->Open((_bstr_t)strLink,"","",NULL);

}

catch(_com_error e)

{

AfxMessageBox("連接配接SQL Server失敗!");

return;

}

//UpdateData(true);

theApp.m_pConnection->Close();

}

如果要在檔案中使用theApp,不要忘記在檔案頭部(不是頭檔案)加上extern CADOAccessApp theApp

以上就是連接配接資料庫的簡單方法。

第二部分:向ListCtrl中添加資料庫中表的資料

1先寫兩個方法用于添加表頭,和内容,ListCtrl要用Report格式

//初始化清單框

void CADOAccessDlg::InitReport()

{

m_List.InsertColumn(0,_T("音樂名稱"),LVCFMT_LEFT,120,-1);

m_List.InsertColumn(1,_T("作者/歌手"),LVCFMT_LEFT,90,-1);

m_List.InsertColumn(2,_T("備注"),LVCFMT_LEFT,110,-1);

m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT |LVS_EX_GRIDLINES);

}

//顯示清單框裡的内容,從MidoSond表中

void CADOAccessDlg::UpdataReport()

{

m_List.DeleteAllItems();

//查詢

m_pRecordset.CreateInstance(__uuidof(Recordset));

CString strLink;

try

{

strLink.Format("Provider=SQLOLEDB;server=ZHAOPENG;UID=sa;PWD=sa;database=MidoText");

theApp.m_pConnection->Open((_bstr_t)strLink,"","",NULL);

}

catch(_com_error e)

{

AfxMessageBox("連接配接SQL Server失敗!");

return;

}

UpdateData(true);

try

{

m_pRecordset->Open("select * from TextSond",theApp.m_pConnection.GetInterfacePtr(),

adOpenDynamic,//動态

adLockOptimistic,//樂觀封鎖法

adCmdText);//文本查詢

}

catch (_com_error e)

{

CString strErr="Select語句執行失敗!";

AfxMessageBox(e.ErrorMessage()+strErr);

}

_variant_t vat;

CString MusicName,ZhuoZhe,SomethingAbout;

CString strDomainName;

while (!m_pRecordset->adoEOF)

{//擷取一個字段

vat = m_pRecordset->GetCollect("音樂名稱");

if (vat.vt != VT_NULL) {

MusicName = (LPCSTR)_bstr_t(vat);

MusicName.TrimLeft();//清除左邊的空格

}

vat = m_pRecordset->GetCollect("作者/歌手");

if (vat.vt != VT_NULL) {

ZhuoZhe = (LPCSTR)_bstr_t(vat);

ZhuoZhe.TrimLeft();

}

vat = m_pRecordset->GetCollect("備注");

if (vat.vt != VT_NULL) {

SomethingAbout = (LPCSTR)_bstr_t(vat);

SomethingAbout.TrimLeft();

}

int pos,id=1;

pos = m_List.InsertItem(id,strDomainName);

m_List.SetItemText(pos,0,MusicName);

m_List.SetItemText(pos,1,ZhuoZhe);

m_List.SetItemText(pos,2,SomethingAbout);

m_pRecordset->MoveNext();

}

m_pRecordset->Close();

theApp.m_pConnection->Close();

}

2在ShowWindow事件中調用,因為該事件先于其它任何事件是以在這一個就建立了資料庫連接配接(連接配接寫在第二個方法裡)

void CADOAccessDlg::OnShowWindow(BOOL bShow, UINT nStatus)

{

CDialog::OnShowWindow(bShow, nStatus);

// TODO: Add your message handler code here

this->InitReport();

this->UpdataReport();

}

第三部分:添加,修改,删除

這三項功能看似簡單實則重要,使操作資料庫系統的核心操作,可以擴充出許多其他功能。

分析:三項功能的本質在于1檢索輸入裝置中輸入的資料合法性,将其儲存到相應的變量中。2調用指令函數,對連接配接的資料庫進行操作。3将操作結果傳回到輸出裝置上。

我們就按照這樣的思想編成,以添加功能為例說明其它給出代碼

//1檢索輸入裝置中輸入的資料合法性,将其儲存到相應的變量中

void CADOAccessDlg::OnBtnAdd()

{

//判斷是否有字元輸入

if (ISEmpty()) {

return;

}

//不可以出現前兩項一樣的輸入(正規表達式)

if (ISHaveString()==false) {

return;

}

//得到所輸入的字元

BOOL IsUpdata = FALSE;

DataTable = "TextSond";//資料表名字

//這裡我原來想作動态建庫的所遺留了變量

CString strWeather;

CString strMusicName,strMen,strSomething;

((CEdit*)GetDlgItem(IDC_EdtMusicName))->GetWindowText(strMusicName);

((CEdit*)GetDlgItem(IDC_EdtZZName))->GetWindowText(strMen);

((CEdit*)GetDlgItem(IDC_EdtSomething))->GetWindowText(strSomething);

//對所輸入字元的合法性進行驗證

if (strMusicName.GetLength()>50) {

MessageBox("音樂名稱不能超過50個位元組!","請您注意",MB_ICONINFORMATION);

return;

}

if (strMen.GetLength()>30) {

MessageBox("作者或歌手不能超過50個位元組!","請您注意",MB_ICONINFORMATION);

return;

}

if (strSomething.GetLength()>40) {

MessageBox("備注不能超過50個位元組!","請您注意",MB_ICONINFORMATION);

return;

}

//判斷要添加的行是否存在,存在就更新,不存在,就追加

for (int i=0;i<m_List.GetItemCount();i++) {

if (strWeather == m_List.GetItemText(i,0)) {

IsUpdata = TRUE;

break;

}

}

if (IsUpdata)

{

CString strUpdata;

strUpdata.Format("Updata '%s' set 音樂名稱='%s',作者或歌手='%s',備注='%s'",

DataTable,strMusicName,strMen,strSomething);

_variant_t RecordAffected;

theApp.m_pConnection->Execute(_bstr_t(strUpdata),&RecordAffected,

adCmdText);

}

else

{

UpdateData();

m_pRecordset.CreateInstance(__uuidof(Recordset));

try

{

//查找所有行

CString sql;

sql.Format("select * from %s",

DataTable);

BSTR bstrSQL = sql.AllocSysString();

m_pRecordset->Open(_bstr_t(bstrSQL),

theApp.m_pConnection.GetInterfacePtr(),

adOpenDynamic,

adLockOptimistic,

adCmdText);

}

catch (_com_error e) {

AfxMessageBox(e.ErrorMessage());

}

//添加

m_pRecordset->AddNew();

m_pRecordset->PutCollect("音樂名稱",_variant_t(strMusicName));

m_pRecordset->PutCollect("作者或歌手",_variant_t(strMen));

m_pRecordset->PutCollect("備注",_variant_t(strSomething));

m_pRecordset->Update();

m_pRecordset->Close();

}

this->UpdataReport();

}

BOOL CADOAccessDlg::ISEmpty()

{

UpdateData(TRUE);

if (m_EdtMName == "") {

MessageBox("請輸入音樂名稱!","提示",MB_ICONINFORMATION);

return true;

}

if (m_Men == "") {

MessageBox("請輸入作者或歌手!","提示",MB_ICONINFORMATION);

return true;

}

// if (m_SomeThing = "") {

// MessageBox("請輸入音樂名稱!","提示",MB_ICONINFORMATION);

// return;

// }

return false;

}

//判斷編輯框裡是否有字元,有擇削去

BOOL CADOAccessDlg::ISHaveString()

{

CString strMusicName,strMen,strSomething;

CString strOldName,strOldMen;

((CEdit*)GetDlgItem(IDC_EdtMusicName))->GetWindowText(strMusicName);

((CEdit*)GetDlgItem(IDC_EdtZZName))->GetWindowText(strMen);

for (int i=0;i<m_List.GetItemCount();i++)

{

strOldName = m_List.GetItemText(i,0);

strOldMen = m_List.GetItemText(i,1);

if ((strMusicName==strOldName)&(strMen==strOldMen))

{

AfxMessageBox("請不要重複添加記錄!");

return false;//已經有了這樣的字段

}

}

return true;

}

修改

void CADOAccessDlg::OnBtnUpdate()

{

// TODO: Add your control notification handler code here

//點選修改時将會更新資料表中的内容

if (ISEmpty()) {

return;

}

//得到所輸入的字元

BOOL IsUpdata = FALSE;

CString strMusicName,strSomeOne,strSomeThing;

((CEdit*)GetDlgItem(IDC_EdtMusicName))->GetWindowText(strMusicName);

((CEdit*)GetDlgItem(IDC_EdtZZName))->GetWindowText(strSomeOne);

((CEdit*)GetDlgItem(IDC_EdtSomething))->GetWindowText(strSomeThing);

//對所輸入字元的合法性進行驗證

if (strMusicName.GetLength()>50) {

MessageBox("音樂名稱不能超過50個位元組!","請您注意",MB_ICONINFORMATION);

return;

}

if (strSomeOne.GetLength()>30) {

MessageBox("作者或歌手不能超過50個位元組!","請您注意",MB_ICONINFORMATION);

return;

}

if (strSomeThing.GetLength()>40) {

MessageBox("備注不能超過50個位元組!","請您注意",MB_ICONINFORMATION);

return;

}

//判斷是否選中了要修改的行

CString strOldName,strOldMen;

strOldName = m_List.GetItemText(m_nIndex,0);

strOldMen = m_List.GetItemText(m_nIndex,1);

CWnd* boFocus;

boFocus = m_List.GetFocus();

if (boFocus != NULL) //有焦點,先是高亮,更新

{

UINT flag = LVIS_SELECTED|LVIS_FOCUSED;

m_List.SetItemState(m_nIndex, flag, flag);

CString strIndexName;

strIndexName = m_List.GetItemText(m_nIndex,0);

DataTable="TextSond";

CString strSQLUpdata;

_variant_t RecordAffected;

strSQLUpdata.Format("Update %s Set 音樂名稱='%s',作者或歌手='%s',備注='%s' Where 音樂名稱='%s' AND 作者或歌手='%s'",

DataTable,strMusicName,strSomeOne,strSomeThing,strOldName,strOldMen);

BSTR bstrSQL = strSQLUpdata.AllocSysString();

theApp.m_pConnection->Execute(_bstr_t(bstrSQL),&RecordAffected,adCmdText);

//重新顯示清單框

UpdataReport();

}

else

{

MessageBox("請選則要修改的行!","請您注意",MB_ICONINFORMATION);

return;

}

}

删除

void CADOAccessDlg::OnBtnDelete()

{

// TODO: Add your control notification handler code here

CString strDelete;

CString DataTable;

CString MName;

DataTable = "TextSond";

MName = m_List.GetItemText(m_nIndex,0);

strDelete.Format("Delete %s Where 音樂名稱='%s'",

DataTable,MName);

_variant_t RecordsAffected;

theApp.m_pConnection->Execute(_bstr_t(strDelete),&RecordsAffected,adCmdText);

this->UpdataReport();

}

第四部分:上下移動按鈕

功能:當點選上下移動按鈕時清單框中的被選中的一行會顯示高亮,同時該亮度條會上移或下移一行,同時編輯框中的字段會随移動有相應變化。

如圖:上移,一行

在相應的方法中添加代碼

void CADOAccessDlg::OnClickListView(NMHDR* pNMHDR, LRESULT* pResult)

{//在上下移動前需要制定一個起始位置

// TODO: Add your control notification handler code here

POSITION pos = m_List.GetFirstSelectedItemPosition();

m_nIndex = m_List.GetNextSelectedItem(pos); // 得到項目索引

CString strMusicName,strSomeOne,strSomeThing;

strMusicName = m_List.GetItemText(m_nIndex,0);

strSomeOne = m_List.GetItemText(m_nIndex,1);

strSomeThing = m_List.GetItemText(m_nIndex,2);

((CEdit*)GetDlgItem(IDC_EdtMusicName))->SetWindowText(strMusicName);

((CEdit*)GetDlgItem(IDC_EdtZZName))->SetWindowText(strSomeOne);

((CEdit*)GetDlgItem(IDC_EdtSomething))->SetWindowText(strSomeThing);

if (m_nIndex != -1) {

// m_List.SetFocus();

}

*pResult = 0;

}

void CADOAccessDlg::OnBtnUp()

{

// TODO: Add your control notification handler code here

//向上移動

m_List.SetFocus();

if (m_nIndex == -1) {

MessageBox("請選擇一行再上移!","請注意",MB_ICONINFORMATION);

return;

}

// 判斷所選項是否位于行首

if (m_nIndex == 0) {

MessageBox("已經位于第一行了!","請注意",MB_ICONINFORMATION);

return;

}

CString strMusicName,strSomeOne,strSomeThing;

strMusicName = m_List.GetItemText(m_nIndex,0);

strSomeOne = m_List.GetItemText(m_nIndex,1);

strSomeThing = m_List.GetItemText(m_nIndex,2);

m_List.DeleteItem(m_nIndex);

m_List.InsertItem(m_nIndex,strMusicName);

m_List.SetItemText(m_nIndex,1,strSomeOne);

m_List.SetItemText(m_nIndex,2,strSomeThing);

m_nIndex--;

strMusicName = m_List.GetItemText(m_nIndex,0);

strSomeOne = m_List.GetItemText(m_nIndex,1);

strSomeThing = m_List.GetItemText(m_nIndex,2);

((CEdit*)GetDlgItem(IDC_EdtMusicName))->SetWindowText(strMusicName);

((CEdit*)GetDlgItem(IDC_EdtZZName))->SetWindowText(strSomeOne);

((CEdit*)GetDlgItem(IDC_EdtSomething))->SetWindowText(strSomeThing);

// 使得m_nIndex-1位置處項目高亮顯示并獲得焦點

UINT flag = LVIS_SELECTED|LVIS_FOCUSED;

m_List.SetItemState(m_nIndex, flag, flag);

}

void CADOAccessDlg::OnBtnDown()

{

// TODO: Add your control notification handler code here

//向下移動

m_List.SetFocus();

if (m_nIndex == -1) {

MessageBox("請選擇一行再上移!","請注意",MB_ICONINFORMATION);

return;

}

// 判斷所選項是否位于行首

if (m_nIndex == m_List.GetItemCount()-1) {

MessageBox("已經位于最後一行了!","請注意",MB_ICONINFORMATION);

return;

}

CString strMusicName,strSomeOne,strSomeThing;

//擷取該行字段付給編輯框

strMusicName = m_List.GetItemText(m_nIndex,0);

strSomeOne = m_List.GetItemText(m_nIndex,1);

strSomeThing = m_List.GetItemText(m_nIndex,2);

m_List.DeleteItem(m_nIndex);

m_List.InsertItem(m_nIndex,strMusicName);

m_List.SetItemText(m_nIndex,1,strSomeOne);

m_List.SetItemText(m_nIndex,2,strSomeThing);

m_nIndex++;

strMusicName = m_List.GetItemText(m_nIndex,0);

strSomeOne = m_List.GetItemText(m_nIndex,1);

strSomeThing = m_List.GetItemText(m_nIndex,2);

((CEdit*)GetDlgItem(IDC_EdtMusicName))->SetWindowText(strMusicName);

((CEdit*)GetDlgItem(IDC_EdtZZName))->SetWindowText(strSomeOne);

((CEdit*)GetDlgItem(IDC_EdtSomething))->SetWindowText(strSomeThing);

//顯示高亮得到焦點

UINT falg = LVIS_SELECTED|LVIS_FOCUSED;

m_List.SetItemState(m_nIndex,falg,falg);

}

第五部分:登入

實質:1取得資訊,驗證,并存于相應變量。2在ini檔案中存入這些變量。3調用指令函數查詢資料庫看是否通過。

給出核心代碼,其餘請參看源代碼

void LogINDlg::OnShowWindow(BOOL bShow, UINT nStatus)

{

CDialog::OnShowWindow(bShow, nStatus);

// TODO: Add your message handler code here

CFileStatus Status;//檔案身份

CString str;//“關閉”按鈕文字

static CRect RtSmall;

if (CFile::GetStatus(".//MyDB.ini",Status))

{

this->OnBtnCloseORMore();

m_SQLDomainName = m_Inif.GetSQLServerIPORName();

m_strSQLUserName = m_Inif.GetSQLServerUserName();

m_strSQLPassword = m_Inif.GetSQLServerPassWord();

if (m_strUserName == "") {

m_Save = false;// m_Save是CheckBox的變量

}

else

{

m_Save = true;

}

CString ifFind;

ifFind = m_SQLDomainName;

if (!ifFind.IsEmpty()) {

m_Save =true;

}

UpdateData(false);

}

}

1登入

void LogINDlg::OnBtnOK()

{

// TODO: Add your control notification handler code here

if (!IsEmpty())

{

m_Inif.SetSQLServerIP(m_SQLDomainName);

m_Inif.SetSQLServerUserName(m_strSQLUserName);

m_Inif.SetSQLServerPassword(m_strSQLPassword);

if (m_Save) {

m_Inif.SetUserName(m_strUserName);

m_Inif.SetPassWord(m_strPassWord);

}

else

{

m_Inif.SetUserName("");

m_Inif.SetPassWord("");

}

//連接配接資料庫

CString strSQL;

strSQL.Format("Provider=SQLOLEDB;server=%s;uid=%s;pwd=%s;database=MidoText",

m_SQLDomainName,m_strSQLUserName,m_strSQLPassword);

try

{

theApp.m_pConnection->Open((_bstr_t)strSQL,"","",NULL);

}

catch (_com_error e)

{

AfxMessageBox("連接配接SQL Server失敗!");

return;

}

UpdateData(true);

CString strSelect;

strSelect.Format("Select * From UserINIF Where UserName='%s' And /

PassWord='%s' And UserKind=1",m_strUserName,m_strPassWord);

m_pRecordset.CreateInstance(__uuidof(Recordset));

try

{

m_pRecordset->Open((_bstr_t)strSelect,theApp.m_pConnection.GetInterfacePtr(),

adOpenDynamic,

adLockOptimistic,

adCmdText);

}

catch (_com_error e)

{

AfxMessageBox(e.ErrorMessage());

return;

}

_variant_t var;

CString strUserName;

if (!m_pRecordset->adoEOF)

{

theApp.LoginFlag = true;

theApp.UserName = strUserName;

m_pRecordset->Close();

CDialog::OnOK();

}

else

{

m_pRecordset->Close();

theApp.m_pConnection->Close();

AfxMessageBox("登陸失敗!");

}

}

}

2詳細…

void LogINDlg::OnBtnCloseORMore()

{

// TODO: Add your control notification handler code here

//改變文字

CString str;

if (GetDlgItemText(IDC_BtnCloseORMore,str),str=="關閉...") {

SetDlgItemText(IDC_BtnCloseORMore,"詳細...");

}

else

{

SetDlgItemText(IDC_BtnCloseORMore,"關閉...");

}

//開辟對話框區域

static CRect RtLarger;

static CRect RtSmall;

if (RtLarger.IsRectEmpty())

{

//可變區域

CRect temp;

GetWindowRect(&RtLarger);

GetDlgItem(IDC_STATIC_Span)->GetWindowRect(&temp);//設定分界線以下為可變區域

//設定可變區域大小

RtSmall.left = RtLarger.left;

RtSmall.right = RtLarger.right;

RtSmall.top = RtLarger.top;

RtSmall.bottom = temp.bottom;

}

//按鈕上顯示“關閉。。。”時不顯示附加區域

if (str=="關閉...") {

SetWindowPos(NULL,0,0,RtSmall.Width(),RtSmall.Height(),

SWP_NOMOVE | SWP_NOZORDER);//不改變目前的大小和位置

}

else

{

SetWindowPos(NULL,0,0,RtLarger.Width(),RtLarger.Height(),

SWP_NOMOVE | SWP_NOZORDER);

}

}

第六部分 退出

軟體要退出時應該有個退出界面,讓使用者确認是否真的要退出

效果圖

步驟:

1在主幹檔案中定義退出變量,就是和工程同名的那個檔案我的是ObjectPlayer。Cpp

Public:

BOOL ExitFlag;//退出标志符

2建立基于退出對話框的相關類,因為要用到程式對象App,是以在程式開始處引用對象extern CObjectPlayerApp theApp;

填寫相應方法

void ExitDlg::OnOK()

{

// TODO: Add extra validation here

theApp.ExitFlag = TRUE;

CDialog::OnOK();

}

void ExitDlg::OnCancel()

{

// TODO: Add extra cleanup here

theApp.ExitFlag = false;

CDialog::OnCancel();

}

3在需要調用該對話框的檔案中(.cpp)引入#include "ExitDlg.h"

extern CObjectPlayerApp theApp;

調用WM_Close消息

void CObjectPlayerDlg::OnClose()

{

// TODO: Add your message handler code here and/or call default

ExitDlg dlgExit;

dlgExit.DoModal();//調用對話框

if (theApp.ExitFlag) //判斷标志位

{

CDialog::OnClose();

}

}