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

📄 ch14.htm

📁 好书《C++ Builder高级编程技术》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>

<HEAD>
	<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
	<META NAME="Author" Content="Steph Mineart">
	<TITLE>Ch 14 -- Sessions and Relational Real-World 
Databases</TITLE>
</HEAD>

<BODY BACKGROUND="bg1.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/bg1.gif" BGCOLOR="#FFFFFF">

<P ALIGN="CENTER"><IMG SRC="sams.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/sams.gif" WIDTH="75" HEIGHT="24" ALIGN="BOTTOM"
BORDER="0"><BR>
<BR>
<A HREF="index-3.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/index.htm"><IMG SRC="toc.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/toc.gif" WIDTH="40" 
HEIGHT="40" ALIGN="BOTTOM"
ALT="TOC" BORDER="0" NAME="toc4"></A><A HREF="ch13.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/ch13.htm"><IMG SRC="back-1.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/back.gif"
WIDTH="40" HEIGHT="40" ALIGN="BOTTOM" ALT="BACK" BORDER="0" NAME="toc1"></A><A HREF="ch15.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/ch15.htm"><IMG
SRC="forward.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/forward.gif" WIDTH="40" 
HEIGHT="40" ALIGN="BOTTOM" ALT="FORWARD" BORDER="0"
NAME="toc2"></A></P>
<H2 ALIGN="CENTER"><FONT COLOR="#000077">Charlie Calvert's C++ Builder Unleashed</FONT></H2>
<P>
<H2 ALIGN="CENTER"><A NAME="Heading1"></A><FONT COLOR="#000077">- 14 
-</FONT></H2>
<H2 ALIGN="CENTER"><A NAME="Heading2"></A><FONT COLOR="#000077">Sessions and Relational
Real-World Databases</FONT></H2>
<P>
<H3><A NAME="Heading3"></A><FONT COLOR="#000077">Overview</FONT></H3>
<P>Now you can take a look at a real 
relational database in action. The preceding
six chapters have really been nothing but a long prelude to this chapter, where all
the pieces finally come together.</P>
<P>This chapter features another address book program, but this time it will be 
based
on a relational database. This second database will allow you to add multiple addresses,
phone numbers, and e-mail addresses to each name in the address book.</P>
<P>Subjects covered in this chapter include the following:

<UL>
	<LI>Creating the 
tables for a relational database
	<P>
	<LI>Cascading deletes
	<P>
	<LI>At runtime, iterating through the controls on a form or a data module and performing
	certain actions on selected components. For instance, the code shows how to iterate
	through 
all the tables on <TT>TDataModule</TT> to make sure that they are all posted.
	<P>
	<LI>Working with the <TT>TPageControl</TT> and <TT>TTabSheet</TT> objects
	<P>
	<LI>Working with <TT>TTreeView</TT>, <TT>TImageList</TT>, and <TT>TTreeNode</TT>
	<P>
	
<LI>Retrieving error strings from a resource
	<P>
	<LI>Using the <TT>TSession</TT> object
</UL>

<P>After you get a look at the address book program, I start a second program called
kdAddExplore. This program looks and feels a lot like a miniature 
version of the
Database Explorer. You can use this program to explore the structure of the five
tables used in the address book program found in the first half of this chapter.</P>
<P>The main purpose of the kdAddExplore program is to let you see some 
of the functionality
of the global <TT>TSession</TT> object that is automatically available in all BCB
database applications. The <TT>Session</TT> object is created automatically when
you call <TT>Application-&gt;Initialize</TT> at the startup of a 
database program.
This call is found in the program source generated for you by BCB. To view the program
source, choose View | Program Source from the main BCB menu. Don't forget to check
the readme file on the CD that comes with this book for 
additional information about
the aliases used in this book.
<H3><A NAME="Heading4"></A><FONT COLOR="#000077">Data in the Real World</FONT></H3>
<P>The code in this chapter addresses the kinds of problems you find in real-world
situations. In 
particular, the conflict that needs to be resolved is between the
rigid, inflexible nature of simple tables and the fluid, kaleidoscope-like nature
of information in the real world.</P>
<P>When most people first try to build database programs, they 
tend to create one
simple table, like the one shown in the Address2 program from the preceding chapter.
The limitations with that kind of system might well emerge on the first day of use.
For example, you might start transferring handwritten addresses 
into the database.
At first, this process might go fairly well, but then you are likely to encounter
a situation in which one person has multiple phone numbers or multiple addresses.
It's not at all unusual for one person to have three or more e-mail 
addresses. The
Address2 program does not have a good solution for that kind of problem.</P>
<P>In professional settings, this problem can be multiplied many times. For example,
I need to track all the Borland offices in the world. This task involves 
tracking
addresses in Germany, England, France, Australia, Hong Kong, Japan, and various other
locations throughout the world.</P>
<P>My job puts me in contact with a number of software vendors (ISVs) that use or
create Borland tools. Many of these 
people maintain offices both at home and at their
businesses. Some of them frequent certain sites, and others have complex relationships
with their companies that I can track only via freehand notes.</P>
<P>As you can see, information in the real 
world is messy and complex. The Address2
program is simple and straightforward. Many people can make do with simple tools,
but others need to have a more sophisticated system.</P>
<P>The kdAdd program found in this chapter is an attempt to resolve the 
kinds of
problems you find in real-world situations. In the form you see it here, it is not
quite as polished as the Address2 program. It is, however, much more sophisticated
and much more powerful. With some work, it could easily form the basis for a 
professional-level
database used in an office.
<H3><A NAME="Heading5"></A><FONT COLOR="#000077">Examining the Relational Address
Program</FONT></H3>
<P>The kdAdd program uses five tables called <TT>kdNames</TT>, <TT>kdAddress</TT>,
<TT>kdPhone</TT>, 
<TT>kdMemo</TT>, and <TT>kdEmail</TT>. The <TT>kdNames</TT> table
is the master table that &quot;owns&quot; the other four tables. The other tables
are detail tables.</P>
<P>When the program first appears, it looks like the image shown in Figure 14.1.

As you can see, the program uses a <TT>TPageControl</TT> with five pages, one for
each of the tables. The Address and Phone tables are also shown on the first page
so that the user can see them easily. If you want to delete items from either an

address or phone number, then you should turn to the respective pages for those items.</P>
<P>The data for the program is kept in the <TT>Data</TT> directory on the CD that
comes with this book. You should create a Standard Paradox alias called 
<TT>CUNLEASHED</TT>
that points to a copy of this directory, which resides on your hard drive. Refer
to the readme file on the CD that comes with this book if you need additional information
setting up the alias. The fields for the tables in the 
database are shown in Table
14.1 through Table 14.5.<BR>
<BR>
<A NAME="Heading6"></A><A HREF="14ebu01.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/14/14ebu01.jpg">FIGURE 14.1.</A><FONT COLOR="#000077">
</FONT><I>The main screen for the kdAdd program.</I></P>
<P><B>Table 14.1. The format for the 
kdName table. </B>
<TABLE BORDER="1">
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="73" ALIGN="LEFT"><B>Table name</B></TD>
		<TD WIDTH="37" ALIGN="LEFT"><B>Type</B></TD>
		<TD WIDTH="39" ALIGN="LEFT"><B>Size</B></TD>
		<TD ALIGN="LEFT"><B>Primary 
index</B></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="73" ALIGN="LEFT"><TT>NameCode</TT></TD>
		<TD WIDTH="37" ALIGN="LEFT">+</TD>
		<TD WIDTH="39" ALIGN="LEFT"></TD>
		<TD ALIGN="LEFT">*</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD 
WIDTH="73" ALIGN="LEFT"><TT>FirstName</TT></TD>
		<TD WIDTH="37" ALIGN="LEFT">A</TD>
		<TD WIDTH="39" ALIGN="LEFT">30</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="73" ALIGN="LEFT"><TT>LastName</TT></TD>
		<TD 
WIDTH="37" ALIGN="LEFT">A</TD>
		<TD WIDTH="39" ALIGN="LEFT">30</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="73" ALIGN="LEFT"><TT>Company</TT></TD>
		<TD WIDTH="37" ALIGN="LEFT">A</TD>
		<TD WIDTH="39" 
ALIGN="LEFT">30</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
</TABLE>
<BR>
<BR>
<B>Table 14.2. The structure for the kdAdd table</B><FONT SIZE="4"><B>. </B></FONT>
<TABLE BORDER="1">
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="80" ALIGN="LEFT"><B>Table 
name</B></TD>
		<TD WIDTH="40" ALIGN="LEFT"><B>Type</B></TD>
		<TD WIDTH="44" ALIGN="LEFT"><B>Size</B></TD>
		<TD ALIGN="LEFT"><B>Primary index</B></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="80" ALIGN="LEFT"><TT>AddCode</TT></TD>
		<TD 
WIDTH="40" ALIGN="LEFT">+</TD>
		<TD WIDTH="44" ALIGN="LEFT"></TD>
		<TD ALIGN="LEFT">*</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="80" ALIGN="LEFT"><TT>Address1</TT></TD>
		<TD WIDTH="40" ALIGN="LEFT">A</TD>
		<TD WIDTH="44" 
ALIGN="LEFT">30</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="80" ALIGN="LEFT"><TT>Address2</TT></TD>
		<TD WIDTH="40" ALIGN="LEFT">A</TD>
		<TD WIDTH="44" ALIGN="LEFT">30</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR 
ALIGN="LEFT" rowspan="1">
		<TD WIDTH="80" ALIGN="LEFT"><TT>City</TT></TD>
		<TD WIDTH="40" ALIGN="LEFT">A</TD>
		<TD WIDTH="44" ALIGN="LEFT">30</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="80" 
ALIGN="LEFT"><TT>State</TT></TD>
		<TD WIDTH="40" ALIGN="LEFT">A</TD>
		<TD WIDTH="44" ALIGN="LEFT">3</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="80" ALIGN="LEFT"><TT>Zip</TT></TD>
		<TD WIDTH="40" 
ALIGN="LEFT">A</TD>
		<TD WIDTH="44" ALIGN="LEFT">10</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="80" ALIGN="LEFT"><TT>NameCode</TT></TD>
		<TD WIDTH="40" ALIGN="LEFT">I</TD>
		<TD WIDTH="44" ALIGN="LEFT"></TD>
		
<TD ALIGN="LEFT"></TD>
	</TR>
</TABLE>
<BR>
<BR>
<B>Table 14.3. The structure for the kdPhone table. </B>
<TABLE BORDER="1">
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="83" ALIGN="LEFT"><B>Table name</B></TD>
		<TD WIDTH="43" 
ALIGN="LEFT"><B>Type</B></TD>
		<TD WIDTH="44" ALIGN="LEFT"><B>Size</B></TD>
		<TD ALIGN="LEFT"><B>Primary index</B></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="83" ALIGN="LEFT"><TT>PhoneCode</TT></TD>
		<TD WIDTH="43" ALIGN="LEFT">+</TD>
		
<TD WIDTH="44" ALIGN="LEFT"></TD>
		<TD ALIGN="LEFT">*</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="83" ALIGN="LEFT"><TT>Description</TT></TD>
		<TD WIDTH="43" ALIGN="LEFT">A</TD>
		<TD WIDTH="44" ALIGN="LEFT">15</TD>
		<TD 
ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="83" ALIGN="LEFT"><TT>Number</TT></TD>
		<TD WIDTH="43" ALIGN="LEFT">A</TD>
		<TD WIDTH="44" ALIGN="LEFT">25</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD 
WIDTH="83" ALIGN="LEFT"><TT>Ext</TT></TD>
		<TD WIDTH="43" ALIGN="LEFT">A</TD>
		<TD WIDTH="44" ALIGN="LEFT">5</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="83" ALIGN="LEFT"><TT>NameCode</TT></TD>
		<TD WIDTH="43" 
ALIGN="LEFT">I</TD>
		<TD WIDTH="44" ALIGN="LEFT"></TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
</TABLE>
<BR>
<BR>
<B>Table 14.4. The structure for the kdEMail table. </B>
<TABLE BORDER="1">
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="91" 
ALIGN="LEFT"><B>Table name</B></TD>
		<TD WIDTH="40" ALIGN="LEFT"><B>Type</B></TD>
		<TD WIDTH="48" ALIGN="LEFT"><B>Size</B></TD>
		<TD ALIGN="LEFT"><B>Primary index</B></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="91" 
ALIGN="LEFT"><TT>EMailCode</TT></TD>
		<TD WIDTH="40" ALIGN="LEFT">+</TD>
		<TD WIDTH="48" ALIGN="LEFT"></TD>
		<TD ALIGN="LEFT">*</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="91" ALIGN="LEFT"><TT>Address</TT></TD>
		<TD WIDTH="40" 
ALIGN="LEFT">A</TD>
		<TD WIDTH="48" ALIGN="LEFT">50</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="91" ALIGN="LEFT"><TT>Description</TT></TD>
		<TD WIDTH="40" ALIGN="LEFT">A</TD>
		<TD WIDTH="48" ALIGN="LEFT">65</TD>
		
<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="91" ALIGN="LEFT"><TT>Service</TT></TD>
		<TD WIDTH="40" ALIGN="LEFT">A</TD>
		<TD WIDTH="48" ALIGN="LEFT">25</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		
<TD WIDTH="91" ALIGN="LEFT"><TT>NameCode</TT></TD>
		<TD WIDTH="40" ALIGN="LEFT">I</TD>
		<TD WIDTH="48" ALIGN="LEFT"></TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
</TABLE>
<BR>
<BR>
<B>Table 14.5. The structure for the kdMemo table. </B>
<TABLE BORDER="1">
	
<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="100" ALIGN="LEFT"><B>Table name</B></TD>
		<TD WIDTH="41" ALIGN="LEFT"><B>Type</B></TD>
		<TD WIDTH="47" ALIGN="LEFT"><B>Size</B></TD>
		<TD ALIGN="LEFT"><B>Primary index</B></TD>
	</TR>
	<TR ALIGN="LEFT" 
rowspan="1">
		<TD WIDTH="100" ALIGN="LEFT"><TT>MemoCode</TT></TD>
		<TD WIDTH="41" ALIGN="LEFT">+</TD>
		<TD WIDTH="47" ALIGN="LEFT"></TD>
		<TD ALIGN="LEFT">*</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="100" 
ALIGN="LEFT"><TT>Description</TT></TD>
		<TD WIDTH="41" ALIGN="LEFT">A</TD>
		<TD WIDTH="47" ALIGN="LEFT">25</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="100" ALIGN="LEFT"><TT>MemoData</TT></TD>
		<TD WIDTH="41" 
ALIGN="LEFT">M</TD>
		<TD WIDTH="47" ALIGN="LEFT">15</TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="100" ALIGN="LEFT"><TT>NameCode</TT></TD>
		<TD WIDTH="41" ALIGN="LEFT">I</TD>
		<TD WIDTH="47" ALIGN="LEFT"></TD>
		
<TD ALIGN="LEFT"></TD>
	</TR>
</TABLE>
<BR>
<BR>
Four constraints are placed on the table in the form of foreign keys called <TT>NameCode</TT>.
They are placed in each of the program's tables except for the master table. These
constraints are shown in 
Figure 14.2.</P>
<P>When you're viewing this information in the Database Explorer (DBX), you should
highlight the name of each constraint and then look at the definition page to read
the <TT>Reference Type</TT> and <TT>Reference To</TT> fields. As you 
can see from
Figure 14.2, these fields show which table the constraint references. The view shown
here is of the <TT>kdNames</TT> table, and it is the master table in these relationships.
The <TT>riAddNameCode</TT> constraint references the 
<TT>kdAdds</TT> table.<BR>
<BR>
<A NAME="Heading7"></A><A HREF="14ebu02.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/14/14ebu02.jpg">FIGURE 14.2.</A><FONT COLOR="#000077">
</FONT><I>By opening the Referential Integrity section of <TT>kdNames</TT> in DBX,
you can see the foreign keys used by the 
database</I>.</P>
<P>Table 14.6 shows another way to think about the referential integrity in this
database. <BR>
<BR>
<B>Table 14.6. The keys in the database shown in table format. </B>
<TABLE BORDER="1">
	<TR ALIGN="LEFT" rowspan="1">
		<TD 
WIDTH="63" ALIGN="LEFT"><B>Table</B></TD>
		<TD WIDTH="84" ALIGN="LEFT"><B>Primary key</B></TD>
		<TD ALIGN="LEFT"><B>Foreign key</B></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="63" ALIGN="LEFT"><TT>kdName</TT></TD>
		<TD WIDTH="84" 
ALIGN="LEFT"><TT>NameCode</TT></TD>
		<TD ALIGN="LEFT"></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="63" ALIGN="LEFT"><TT>kdAdd</TT></TD>
		<TD WIDTH="84" ALIGN="LEFT"><TT>AddCode</TT></TD>
		<TD ALIGN="LEFT"><TT>NameCode</TT> references 
<TT>kdName.NameCode</TT></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="63" ALIGN="LEFT"><TT>kdPhone</TT></TD>
		<TD WIDTH="84" ALIGN="LEFT"><TT>PhoneCode</TT></TD>
		<TD ALIGN="LEFT"><TT>NameCode</TT> references <TT>kdName.NameCode</TT></TD>
	
</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD WIDTH="63" ALIGN="LEFT"><TT>kdEMail</TT></TD>
		<TD WIDTH="84" ALIGN="LEFT"><TT>EMailCode</TT></TD>
		<TD ALIGN="LEFT"><TT>NameCode</TT> references <TT>kdName.NameCode</TT></TD>
	</TR>
	<TR ALIGN="LEFT" 
rowspan="1">
		<TD WIDTH="63" ALIGN="LEFT"><TT>kdMemo</TT></TD>
		<TD WIDTH="84" ALIGN="LEFT"><TT>MemoCode</TT></TD>
		<TD ALIGN="LEFT"><TT>NameCode</TT> references <TT>kdName.NameCode</TT></TD>
	</TR>
</TABLE>
<BR>
As you can see, <TT>kdAdd</TT>, 
<TT>kdPhone</TT>, <TT>kdEmail</TT>, and <TT>kdMemo</TT>
all have a single foreign key called <TT>NameCode</TT> that references the <TT>NameCode</TT>
primary key in <TT>kdNames</TT>. The number in the foreign keys therefore must be
a number found in 
the primary key of the <TT>kdNames</TT> table. Furthermore, you
cannot delete a row from the <TT>kdNames</TT> table unless all its related fields
in the other tables have been deleted first. You also cannot change the value in
the <TT>NameCode</TT> 
field of <TT>kdNames</TT> if it will leave records in the other
tables &quot;stranded.&quot;

<DL>
	<DT></DT>
</DL>



<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>If you are new to referential integrity,
	take the time to 
play with the database and test these constraints. Referential integrity
	exists to prevent the user from accidentally deleting needed data, and from accidentally
	entering erroneous data. During the course of this chapter, you should test the 
restraints
	on this database so you can see how it establishes rules that help both the programmer
	and the user maintain a valid set of data. 
<HR>


</BLOCKQUOTE>

<P>The referential integrity relationships you see here represent the classic 
simplest
case for constructing a real relational database. Most databases in the real world
have more tables and more foreign keys. However, this one has all the elements of
a real relational database, and the complexity level is sufficient for 

⌨️ 快捷键说明

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