ms access 파일로 연결하기
ODBC 데이터 원본관리자(32비트)
고급설정도 진행하기
mfc 애플리케이션 옵션 설정
프로젝트 이름 : MFCODBC_EXAM
----framework.h
// odbc 관련된 헤더 파일
#include <afxdb.h>
32비트로 설정 (ms access만 해당)
----view.cpp
BOOL CMFCODBCEXAMView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: CREATESTRUCT cs를 수정하여 여기에서
// Window 클래스 또는 스타일을 수정합니다.
return CFormView::PreCreateWindow(cs);
}
void CMFCODBCEXAMView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
/*
1. db 연결
2. sql 실행
3. sql 결과 얻기
4. 연결 종료
CDatabase 클래스 : db 연결 관리하는 클래스
CRecordset 클래스 : sql 구문을 실행하고 결과 집합을 관라하는 클래스
*/
//1. db 연결
CDatabase db;
BOOL bRet = db.OpenEx(_T("DSN=scott_db;uid=user1;PWD=passwd;"), 0);
if (bRet) {
AfxMessageBox(_T("DB 연결 성공"));
}
else {
AfxMessageBox(_T("DB 연결 실패"));
}
//4. 연결 종료
db.Close();
}
데이터 값 넣기
----view.cpp
void CMFCODBCEXAMView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
m_imageList.Create(48, 48, ILC_COLOR32, 5, 5);
m_imageListSmall.Create(16, 16, ILC_COLOR32, 5, 5);
m_imageList.Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME));
m_imageListSmall.Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME));
m_listView.SetImageList(&m_imageList, LVSIL_NORMAL);
m_listView.SetImageList(&m_imageListSmall, LVSIL_SMALL);
//칼럼 정보 출력
m_listView.InsertColumn(0, _T("사원번호"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(1, _T("이름"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(2, _T("직업"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(3, _T("관리자"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(4, _T("입사일자"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(5, _T("급여"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(6, _T("상여금"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(7, _T("부서번호"), LVCFMT_LEFT, 100);
DWORD dwExStyle = m_listView.GetExtendedStyle();
m_listView.SetExtendedStyle(dwExStyle | LVS_EX_CHECKBOXES | LVS_EX_BORDERSELECT | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
/*
1. db 연결
2. sql 실행
3. sql 결과 얻기
4. 연결 종료
CDatabase 클래스 : db 연결 관리하는 클래스
CRecordset 클래스 : sql 구문을 실행하고 결과 집합을 관라하는 클래스
*/
//1. db 연결
CDatabase db;
BOOL bRet = db.OpenEx(_T("DSN=scott_db;uid=user1;PWD=passwd;"), 0);
if (bRet) {
//AfxMessageBox(_T("DB 연결 성공"));
//2. sql 실행
CRecordset rs(&db);
rs.Open(CRecordset::forwardOnly, _T("select * from emp"));
// rs에 데이터가 배열로 존재하게 됨
//3. sql 결과 얻기
int nRow = 0;
CString strEmpNo;
CString strEmpName;
CString strEmpJob;
while (!rs.IsEOF()) { // 마지막인지 확인
rs.GetFieldValue((short)0, strEmpNo);
rs.GetFieldValue((short)1, strEmpName);
m_listView.InsertItem(nRow, strEmpNo, 0);
m_listView.SetItemText(nRow++, 1, strEmpName);
rs.MoveNext();
}
}
else {
AfxMessageBox(_T("DB 연결 실패"));
}
//4. 연결 종료
db.Close();
}
데이터 값 전부 넣기
void CMFCODBCEXAMView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
m_imageList.Create(48, 48, ILC_COLOR32, 5, 5);
m_imageListSmall.Create(16, 16, ILC_COLOR32, 5, 5);
m_imageList.Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME));
m_imageListSmall.Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME));
m_listView.SetImageList(&m_imageList, LVSIL_NORMAL);
m_listView.SetImageList(&m_imageListSmall, LVSIL_SMALL);
//칼럼 정보 출력
m_listView.InsertColumn(0, _T("사원번호"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(1, _T("이름"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(2, _T("직업"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(3, _T("관리자"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(4, _T("입사일자"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(5, _T("급여"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(6, _T("상여금"), LVCFMT_LEFT, 100);
m_listView.InsertColumn(7, _T("부서번호"), LVCFMT_LEFT, 100);
DWORD dwExStyle = m_listView.GetExtendedStyle();
m_listView.SetExtendedStyle(dwExStyle | LVS_EX_CHECKBOXES | LVS_EX_BORDERSELECT | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
/*
1. db 연결
2. sql 실행
3. sql 결과 얻기
4. 연결 종료
CDatabase 클래스 : db 연결 관리하는 클래스
CRecordset 클래스 : sql 구문을 실행하고 결과 집합을 관라하는 클래스
*/
//1. db 연결
CDatabase db;
BOOL bRet = db.OpenEx(_T("DSN=scott_db;uid=user1;PWD=passwd;"), 0);
if (bRet) {
//AfxMessageBox(_T("DB 연결 성공"));
//2. sql 실행
CRecordset rs(&db);
rs.Open(CRecordset::forwardOnly, _T("select * from emp"));
// 형식 맞추기 (날짜, 상여금)
//rs.Open(CRecordset::forwardOnly, _T("select \
empno, ename, job, mgr, to_char(hirdate, 'YYYY-MM-DD') \
hirdate, to_char(sal, '99,999') sal ,comm, deptno from emp"));
// 매니저 이름으로 바꾸기(없을경우는 null 표시)
//rs.Open(CRecordset::forwardOnly, _T("select a.empno, \
a.ename, a.job, b.ename mgr_name, to_char(a.hirdate, 'YYYY-MM-DD') hirdate, \
to_char(a.sal, '99,999') sal , a.comm, a.deptno from emp a, emp b \
where a.mgr = b.empno(+)"));
// 부서명으로 출력하기
//rs.Open(CRecordset::forwardOnly, _T("select \
a.empno, a.ename, a.job, b.ename mgr_name, \
to_char(a.hirdate, 'YYYY-MM-DD') hirdate, \
to_char(a.sal, '99,999') sal , a.comm, c.dname \
from emp a, emp b, dept c where a.mgr = b.empno(+) \
and a.depto = c.deptno(+)"));
// rs에 데이터가 배열로 존재하게 됨
//3. sql 결과 얻기
int nRow = 0;
CString strEmpNo;
CString strEmpName;
CString strEmpJob;
CString strEmpMgr;
CString strEmpDate;
CString strEmpSal;
CString strEmpComm;
CString strEmpDeptno;
while (!rs.IsEOF()) { // 마지막인지 확인
rs.GetFieldValue((short)0, strEmpNo);
rs.GetFieldValue((short)1, strEmpName);
rs.GetFieldValue((short)2, strEmpJob);
rs.GetFieldValue((short)3, strEmpMgr);
rs.GetFieldValue((short)4, strEmpDate);
rs.GetFieldValue((short)5, strEmpSal);
rs.GetFieldValue((short)6, strEmpComm);
rs.GetFieldValue((short)7, strEmpDeptno);
m_listView.InsertItem(nRow, strEmpNo, 0);
m_listView.SetItemText(nRow, 1, strEmpName);
m_listView.SetItemText(nRow, 2, strEmpJob);
m_listView.SetItemText(nRow, 3, strEmpMgr);
m_listView.SetItemText(nRow, 4, strEmpDate);
m_listView.SetItemText(nRow, 5, strEmpSal);
m_listView.SetItemText(nRow, 6, strEmpComm);
m_listView.SetItemText(nRow, 7, strEmpDeptno);
nRow++;
rs.MoveNext();
}
}
else {
AfxMessageBox(_T("DB 연결 실패"));
}
//4. 연결 종료
db.Close();
}
삭제기능 추가
---view.cpp
void CMFCODBCEXAMView::OnBnClickedButton3()
{
const int nCount = m_listView.GetItemCount();
CString strEmpNo;
CString strSQL;
CDatabase db;
BOOL bRet = db.OpenEx(_T("DSN=scott_db;uid=user1;PWD=passwd;"), 0);
if (bRet) {
for (int i = nCount - 1; i >= 0; --i) {
if (m_listView.GetCheck(i)) {
// 삭제할 사원 번호 얻음
strEmpNo = m_listView.GetItemText(i, 0); // 사번이 나옴
AfxMessageBox(strEmpNo);
// 삭제할 사원 sql구문 생성
strSQL.Format(_T("delete from emp where empno = %s"), strEmpNo);
// 삭제 sql을 실행
db.ExecuteSQL(strSQL); // ExecuteSQL : DML구문(insert, delete, update, merge)
// 목록에서 제거
m_listView.DeleteItem(i);
}
}
}
else {
}
db.Close();
}
한번에 쿼리 보내서 삭제하기
void CMFCODBCEXAMView::OnBnClickedButton3()
{
const int nCount = m_listView.GetItemCount();
CString strEmpNo;
CString strSQL;
CDatabase db;
BOOL bRet = db.OpenEx(_T("DSN=scott_db;uid=user1;PWD=passwd;"), 0);
if (bRet) {
// CStringArray : mfc에서 사용하는 vector 대용 자료형
CStringArray arr;
for (int i = nCount - 1; i >= 0; --i) {
if (m_listView.GetCheck(i)) {
//삭제할 사원 번호를 얻음
strEmpNo = m_listView.GetItemText(i, 0); // 사번이 나옴
//삭제할 사원번호를 배열에 추가
arr.Add(strEmpNo);
//목록에서 제거
m_listView.DeleteItem(i);
}
}
const int size = arr.GetSize();
if (size != 0) {
CString strInParam;
for (int i = 0; i < size; i++) {
strInParam += arr.GetAt(i) + _T(",");
//strInParam += _T("'") + arr.GetAt(i) + _T("', "); // 문자열인 경우
}
strInParam.Delete(strInParam.GetLength() - 1, 1); // 마지막 ',' 지움
// 삭제할 사원 sql구문 생성
strSQL.Format(_T("delete from emp where empno in (%s)"), strInParam.GetBuffer());
//삭제 SQL을 실행
db.ExecuteSQL(strSQL);
// ExecuteSQL : DML구문(insert, delete, update, merge)
}
}
else {
AfxMessageBox(_T("DB 연결 실패"));
}
//DB 연결 종료
db.Close();
}
예외처리 진행하기
void CMFCODBCEXAMView::OnBnClickedButton3()
{
const int nCount = m_listView.GetItemCount();
CString strEmpNo;
CString strSQL;
CDatabase db;
BOOL bRet = db.OpenEx(_T("DSN=scott_db;uid=user1;PWD=passwd;"), 0);
if (bRet) {
CString strInParam;
CArray<int, int> arr;
// 삭제 위치와 삭제 사원번호만 얻음
for (int i = nCount - 1; i >= 0; --i) {
if (m_listView.GetCheck(i)) {
// 삭제할 사원 번호 얻음
strEmpNo = m_listView.GetItemText(i, 0);
strInParam += strEmpNo + _T(", ");
// 삭제할 사원의 위치를 배열에 추가
arr.Add(i);
}
}
const int size = arr.GetSize();
try {
if (!strInParam.IsEmpty()) {
strInParam.Delete(strInParam.GetLength() - 1, 1);
// 삭제할 사원 sql구문 생성
strSQL.Format(_T("delete from emp where empno in (%s)"), strInParam.GetBuffer());
//AfxMessageBox(strSQL);
// 삭제 sql을 실행
db.ExecuteSQL(strSQL);
// ExecuteSQL : DML구문(insert, delete, update, merge)
// 거꾸로 넣었으므로 순서대로 제거 실행
for (int i = 0; i < arr.GetSize(); i++) {
m_listView.DeleteItem(arr.GetAt(i));
}
}
}
catch (CException* p) {
TCHAR szErr[100];
p->GetErrorMessage(szErr, sizeof(szErr));
AfxMessageBox(szErr);
}
}
else {
AfxMessageBox(_T("DB 연결 실패"));
}
db.Close();
}