⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vcg14.htm

📁 Visual C++与数据库的连接经典实例
💻 HTM
📖 第 1 页 / 共 5 页
字号:

<P>PostalCode using the field PostalCode

<BR>

</BLOCKQUOTE></BLOCKQUOTE>

<BLOCKQUOTE>

<BLOCKQUOTE>

<HR ALIGN=CENTER>

<BR>

<NOTE><B>NOTE</B>

<BR>

<BR>Indexes can have one or more fields. In the example, each index has only one field. Some database applications have indexes that comprise multiple fields. For a multiple-field index, you would define your CDaoIndexFieldInfo object as an array and indicate the number of fields used in the CDaoIndexInfo::m_nFields member.</NOTE>

<BR>

<HR ALIGN=CENTER>

</BLOCKQUOTE></BLOCKQUOTE>

<P>To create an index, you must allocate a CDaoIndexInfo object and either a single CDaoIndexFieldInfo if your index will have only one field or an array of type CDaoIndexFieldInfo if your index will have more than one field. For example, your program uses this code:

<BR>

<PRE>

<FONT COLOR="#000080">// Finally, create the (optional) index fields. The example has

// four sets of indexes, each having only one field:

CDaoIndexInfo    idx;

CDaoIndexFieldInfo  fld; // Only one field per index in the example</FONT></PRE>

<P>After you've allocated your index and index field objects, you must fill them in. To create your primary key, use this code:

<BR>

<PRE>

<FONT COLOR="#000080">// Fill in your structure with revelant information, then build

// the index. CDaoTableDef::CreateIndex() calls Append

// automatically, unlike CDaoTableDef::CreateField(), which does not.

idx.m_strName = _T(&quot;PrimaryKey&quot;); // Primary

idx.m_pFieldInfos = &amp;fld;         // Primary

idx.m_nFields = 1;                // Primary

idx.m_bPrimary = TRUE;            // Secondary

idx.m_bUnique = TRUE;             // Secondary

idx.m_bClustered = FALSE;         // Secondary

idx.m_bIgnoreNulls = FALSE;       // Secondary

idx.m_bRequired = TRUE;           // Secondary

idx.m_bForeign = FALSE;           // Secondary

idx.m_lDistinctCount = 5;         // All - returned, not set!

fld.m_strName = _T(&quot;AddressID&quot;);  // Key field

fld.m_bDescending = FALSE;        // Ascending

TableDef.CreateIndex(idx);  // Create primary index</FONT></PRE>

<P>The comments //Primary, //Secondary, and //All refer to which fields are returned when you call the CDaoTableDef::GetIndexInfo() or CDaoRecordset::GetIndexInfo() functions. You must fill in all fields (except for CDaoIndexInfo::m_lDistinctCount, which is only used to return information about an existing index).

<BR>

<BLOCKQUOTE>

<BLOCKQUOTE>

<HR ALIGN=CENTER>

<BR>

<NOTE><B>CAUTION</B>

<BR>

<BR>By design, a database can have one, and only one, primary key. The primary key is often used by the database engine to manage records in the table. A database table can have other, alternative keys if desired.</NOTE>

<BR>

<HR ALIGN=CENTER>

</BLOCKQUOTE></BLOCKQUOTE>

<P>To create the secondary keys, use this code:

<BR>

<PRE>

<FONT COLOR="#000080">idx.m_strName = _T(&quot;EmailAddress&quot;); // Primary

idx.m_pFieldInfos = &amp;fld;         // Primary

idx.m_nFields = 1;                // Primary

idx.m_bPrimary = FALSE;           // Secondary

idx.m_bUnique = FALSE;            // Secondary

idx.m_bClustered = FALSE;         // Secondary

idx.m_bIgnoreNulls = FALSE;       // Secondary

idx.m_bRequired = FALSE;          // Secondary

idx.m_bForeign = FALSE;           // Secondary

idx.m_lDistinctCount = 5;         // All - returned, not set!

fld.m_strName = _T(&quot;EmailAddress&quot;);  // Key field

fld.m_bDescending = FALSE;        // Ascending

TableDef.CreateIndex(idx);  // Create secondary index

idx.m_strName = _T(&quot;LastName&quot;);   // Primary

idx.m_pFieldInfos = &amp;fld;         // Primary

idx.m_nFields = 1;                // Primary

idx.m_bPrimary = FALSE;           // Secondary

idx.m_bUnique = FALSE;            // Secondary

idx.m_bClustered = FALSE;         // Secondary

idx.m_bIgnoreNulls = FALSE;       // Secondary

idx.m_bRequired = FALSE;          // Secondary

idx.m_bForeign = FALSE;           // Secondary

idx.m_lDistinctCount = 5;         // All - returned, not set!

fld.m_strName = _T(&quot;LastName&quot;);   // Key field

fld.m_bDescending = FALSE;        // Ascending

TableDef.CreateIndex(idx);  // Create secondary index

idx.m_strName = _T(&quot;PostalCode&quot;); // Primary

idx.m_pFieldInfos = &amp;fld;         // Primary

idx.m_nFields = 1;                // Primary

idx.m_bPrimary = FALSE;           // Secondary

idx.m_bUnique = FALSE;            // Secondary

idx.m_bClustered = FALSE;         // Secondary

idx.m_bIgnoreNulls = FALSE;       // Secondary

idx.m_bRequired = FALSE;          // Secondary

idx.m_bForeign = FALSE;           // Secondary

idx.m_lDistinctCount = 5;         // All - returned, not set!

fld.m_strName = _T(&quot;PostalCode&quot;); // Key field

fld.m_bDescending = FALSE;        // Ascending

TableDef.CreateIndex(idx);  // Create secondary index

// Done creating the indexes...</FONT></PRE>

<P>There's no need to call Append(), because this is done automatically by MFC's DAO implementation. Of course, in the preceding code, you should make sure that your parameters are set to reflect your database's design.

<BR>

<BR>

<A NAME="E70E71"></A>

<H5 ALIGN=CENTER>

<CENTER>

<FONT SIZE=4 COLOR="#FF0000"><B>Adding Records to a DAO Database</B></FONT></CENTER></H5>

<BR>

<P>To add records to a DAO database, you follow procedures that are very similar to those used with ODBC. To keep this functionality separate from your database creation, you add record addition, deletion, and refresh in the view class instead of in the recordset class. You could place this functionality in either class, but the view class is a better place for record addition, deletion, and refresh.

<BR>

<P>To add this functionality, I've added three new selections to the Record menu: Add, Delete, and Refresh. I also used ClassWizard to add a handler for OnMove(). To make the user interface easier, I also added three buttons to the toolbar to perform these functions. Visual C++ 4 makes adding toolbar buttons easy. It takes more time to design and draw the button bitmaps than it does to actually implement them!

<BR>

<P>After adding the new menu selections, handlers are generated using ClassWizard for each one. As noted earlier, the handlers are added to the view class, keeping them separate from other code used in this sample program. Listing 14.2 shows the view class implementation. Additions and modifications appear in bold.

<BR>

<P>

<FONT COLOR="#000080"><B>Listing 14.2. The view implementation class file.</B></FONT>

<BR>

<PRE>

<FONT COLOR="#000080">// AddressesView.cpp : implementation of the CAddressesView class

//

#include &quot;stdafx.h&quot;

#include &quot;Addresses.h&quot;

#include &quot;AddressesSet.h&quot;

#include &quot;AddressesDoc.h&quot;

#include &quot;AddressesView.h&quot;

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CAddressesView

IMPLEMENT_DYNCREATE(CAddressesView, CDaoRecordView)

BEGIN_MESSAGE_MAP(CAddressesView, CDaoRecordView)

    //{{AFX_MSG_MAP(CAddressesView)

    ON_COMMAND(ID_RECORD_ADD, OnRecordAdd)

    ON_COMMAND(ID_RECORD_DELETE, OnRecordDelete)

    ON_COMMAND(ID_RECORD_REFRESH, OnRecordRefresh)

    //}}AFX_MSG_MAP

    // Standard printing commands

    ON_COMMAND(ID_FILE_PRINT, CDaoRecordView::OnFilePrint)

    ON_COMMAND(ID_FILE_PRINT_DIRECT, CDaoRecordView::OnFilePrint)

    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CDaoRecordView::OnFilePrintPreview)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CAddressesView construction/destruction

CAddressesView::CAddressesView()

    : CDaoRecordView(CAddressesView::IDD)

{

    //{{AFX_DATA_INIT(CAddressesView)

    m_pSet = NULL;

    //}}AFX_DATA_INIT

    // TODO: add construction code here

<B>    m_bAddMode = FALSE;</B>

}

CAddressesView::~CAddressesView()

{

}

void CAddressesView::DoDataExchange(CDataExchange* pDX)

{

    CDaoRecordView::DoDataExchange(pDX);

    //{{AFX_DATA_MAP(CAddressesView)

    DDX_FieldText(pDX, IDC_ADDRESS, m_pSet-&gt;m_Address, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_Address, 255);

    DDX_FieldText(pDX, IDC_CITY, m_pSet-&gt;m_City, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_City, 50);

    DDX_FieldText(pDX, IDC_EMAIL, m_pSet-&gt;m_EmailAddress, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_EmailAddress, 50);

    DDX_FieldText(pDX, IDC_FAX, m_pSet-&gt;m_FaxNumber, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_FaxNumber, 30);

    DDX_FieldText(pDX, IDC_FIRSTNAME, m_pSet-&gt;m_FirstName, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_FirstName, 50);

    DDX_FieldText(pDX, IDC_HOMEPHONE, m_pSet-&gt;m_HomePhone, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_HomePhone, 30);

    DDX_FieldText(pDX, IDC_LASTNAME, m_pSet-&gt;m_LastName, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_LastName, 50);

    DDX_FieldText(pDX, IDC_NOTES, m_pSet-&gt;m_Notes, m_pSet);

    DDX_FieldText(pDX, IDC_POSTALCODE, m_pSet-&gt;m_PostalCode, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_PostalCode, 20);

    DDX_FieldText(pDX, IDC_STATE, m_pSet-&gt;m_StateOrProvince, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_StateOrProvince, 20);

    DDX_FieldText(pDX, IDC_WORKPHONE, m_pSet-&gt;m_WorkPhone, m_pSet);

    DDV_MaxChars(pDX, m_pSet-&gt;m_WorkPhone, 30);

    //}}AFX_DATA_MAP

}

BOOL CAddressesView::PreCreateWindow(CREATESTRUCT&amp; cs)

{

    // TODO: Modify the Window class or styles here by modifying

    // the CREATESTRUCT cs

    return CDaoRecordView::PreCreateWindow(cs);

}

void CAddressesView::OnInitialUpdate()

{

    m_pSet = &amp;GetDocument()-&gt;m_addressesSet;

    CDaoRecordView::OnInitialUpdate();

}

/////////////////////////////////////////////////////////////////////////////

// CAddressesView printing

BOOL CAddressesView::OnPreparePrinting(CPrintInfo* pInfo)

{

    // Default preparation

    return DoPreparePrinting(pInfo);

}

void CAddressesView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

{

    // TODO: Add extra initialization before printing

}

void CAddressesView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

{

    // TODO: Add cleanup after printing

}

/////////////////////////////////////////////////////////////////////////////

// CAddressesView diagnostics

#ifdef _DEBUG

void CAddressesView::AssertValid() const

{

    CDaoRecordView::AssertValid();

}

void CAddressesView::Dump(CDumpContext&amp; dc) const

{

    CDaoRecordView::Dump(dc);

}

CAddressesDoc* CAddressesView::GetDocument() // Non-debug version is inline

{

    ASSERT(m_pDocument-&gt;IsKindOf(RUNTIME_CLASS(CAddressesDoc)));

    return (CAddressesDoc*)m_pDocument;

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CAddressesView database support

CDaoRecordset* CAddressesView::OnGetRecordset()

{

    return m_pSet;

}

/////////////////////////////////////////////////////////////////////////////

// CAddressesView message handlers

BOOL CAddressesView::OnMove(UINT nIDMoveCommand)

{

    // TODO: Add your specialized code here and/or call the base class

<B>    // Retrieve the current record set:</B>

<B>    CDaoRecordset* pRecordset = OnGetRecordset();</B>

<B>    if (m_bAddMode)</B>

<B>    {// Do special handling if you are adding records:</B>

<B>        if (!UpdateData())</B>

<B>        { // Could not get updated data from input dialog:</B>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -