Вы находитесь на странице: 1из 189

Base Tutorial: From Newbie to Advocate in a one, two... three!

BASE TUTORIAL:
From Newbie to Advocate in a one, two... three!

Step-by-step guide to producing fairly sophisticated database applications with OpenOffice.org ase, from initial problem to final product complete with forms and reports.

by !ariano "asanova

ase #utorial$ From Newbie to Advocate in a one, two... three!


y !ariano "asanova "opyright % &'(' !ariano "asanova. All rights reserved. First )dition$ August &'(' Second )dition$ September &'('

All names of products and companies mentioned in this te*t are the trademar+ of their respective owners and are mentioned here with no intention of infringement and for the benefit of those respective owners. ,lease note that the author can not provide software support. ,lease contact the appropriate software developers of ase or -S./ at$ www.openoffice.org and www.hs0ldb.org or their fantastic fan base and forum e*perts. #he author has ta+en every precaution possible to ensure the correctness and appropriateness of the information provided in this te*t, including the testing of the code supplied. -owever, due to possible human or mechanical error from the sources, the constant changing and evolution of the software described and +nown and un+nown issues in the code, its functioning and compatibility, the author can assume no responsibility for errors or omissions or for damages resulting from the use of the information provided here. #he author does not guarantee the accuracy, ade0uacy or completeness of this information and shall not be liable to any person, legal or natural, with respect to any loss or damage caused or allegedly caused directly or indirectly by the use of such information, including but not limited to, business interruption, loss of profits or loss of data. #he information is provided 1as is1 with no warranties whatsoever of its appropriateness or fitness for any purpose. 2ou use this information at your own ris+.

#his digital edition can be distributed under the terms of the Creative Commons Attribution Non-"ommercial Share Ali+e license, as described in$ /icense, full te*t$ http$33creativecommons.org3licenses3by-nc-sa34.'3legalcode /icense, summary$ http$33creativecommons.org3licenses3by-nc-sa34.'3 2ou can copy this electronic file and distribute this electronic file with no limitation for all non-commercial use. 2ou can adapt, e*pand or translate this wor+ as long as you$ a5 Attribute the wor+ by providing the name of the initial author and a lin+ to the original wor+ or, if such lin+ is not available, a reference to the source of your copy of the original wor+. 2our attribu tion must not suggest that the initial author endorses you or your use of the wor+. b5 "learly state the nature and scope of your contribution to the wor+. c5 6istribute this wor+ under the same or similar license and ensure that all derivatives will also be non-commercial in nature. 2ou can not use this wor+ or its derivatives for commercial purposes. ase #utorial OOo.

To everyone involved in the creation, distribution and documentation of free and open software And in particular to the developers, writers and administrators at OpenOffice.org ~Thanks!

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Content overview:
Part I: Things you need to know e!ore you "reate a data ase with Base# 8here we introduce this tutorial and its scope. 8e start by analy;ing what a database is and describe its different components$ #ables, relationships, primary and foreign +eys, columns, column attributes, deletion attributes and relationship cardinalities and finally we provide a definition of database and ase database. 8e later comment on forms and reports and on modeling data and goals of proper design, after which we provide an overview of <!/ diagrams to use as a visual vocabulary. 8e then summarily review phases in database design and the importance of Normal Form. 8e also review First, Second and #hird normal forms and how they aid in class e*traction. After this we review the way that ase records attributes and the nature of the variables it uses, analy;ing te*t variables, numeric variables, date and time variables and ob=ect variables and how choosing them properly will affect the performance of a ase application. Part II: Things you need to do e!ore you "ode a data ase with Base# 8here we offer a real case e*ample and, using the elements presented in part 9, we start with a problem and end with a database design. 8e cover class formation, class e*traction, the importance of atomi;ation and descriptors. 8e apply normali;ation and other tools to decide on data structure and finally come up with a complete <!/ diagram of our database. 8e then stress the importance of using au*iliary elements li+e a :ariables 6efinition /ist for the aid they provide in coding our application with ase. After this we analy;e the problem of duplicity of roles in order to introduce the concept of super-class formation. 8e then analy;e the forms and reports that we will use in con=unction with the design we have produced and describe the +ind of features we will want them to have. Now that we understand how to design our tables, its connections, forms and reports, and what do the options that ase offers mean, we are ready to sit down in front of ase and start coding our database. Part III: Things you need to do whi$e "oding a data ase with Base# 8here we describe how to use ase to create the database it too+ us so long to design, complete with forms and reports. 8e star by analy;ing the setup and e*plain how to use S./ commands for the creation of tables and relationships, analy;ing the >"reate #able? and >"onstraint? instructions in detail. 8e also review how to read their descriptions when consulting the 8i+i or other sources. #hen we describe in depth how to create forms to populate our tables and how to use radio buttons, sub-forms, list bo*es and other widgets to simplify data entry. 8e later ta+e our time to analy;e the >Select? command to produce 0ueries and e*tract information from our data and finally e*plain in detail how to produce the reports using both the 7eport 8i;ard and the S<N 7eport uilder.

AS)

#<#O79A/

Table of Contents
9ntroduction$....................................................................................................................v Ac+nowledgments.........................................................................................................vii Part I: Things you need to know e!ore you "reate a data ase with Base# "hapter (..............................................................................................................................4 9ntroduction to databases.................................................................................................4 Anatomy of a database$ #ables, attributes and relationships......................................4 )stablishing relationships within tables.....................................................................@ "ardinality and optionality of a relationship..............................................................A !anaging relationships with column and delete options.........................................(' A definition of database and database design................................................................(( #al+ing about forms and reports....................................................................................(& !odeling data and goals of proper design....................................................................(4 :isual vocabulary..........................................................................................................(B ,hases in database design..............................................................................................(C "hapter &............................................................................................................................(D Eetting into normal form..............................................................................................(D First normal form......................................................................................................&' Second normal form.................................................................................................&' #hird normal form....................................................................................................&( Aiming for simplicity....................................................................................................&4 "hapter 4............................................................................................................................&F 7ecording attributes$ Are you my variableG..................................................................&F 8hy is all this information relevantG............................................................................4' On logical Names and ,hysical Names........................................................................4( Part II: Things you need to do e!ore you "ode a data ase with Base# "hapter B............................................................................................................................4F /etHs get real!.................................................................................................................4F "ase )*ample$ Now we need a problem.......................................................................4F ,ossible solution............................................................................................................4D 6ata !odeling...............................................................................................................B' A little bit more$ 6uplicity of roles and super classes..................................................F& Attributes3:ariable definition lists................................................................................FB "hapter F............................................................................................................................F@ #he forms......................................................................................................................F@ "hapter C............................................................................................................................C4 #he reports....................................................................................................................C4
ii

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#urn on the computers...................................................................................................CA Part III: Things you need to do whi$e "oding a data ase with Base# "hapter @............................................................................................................................@( "reating tables in ase with S./.................................................................................@( Eeneral Overview$........................................................................................................@( "reating tables and relationships with S./ commands................................................@& 8hat S./ window are you, anywayG...........................................................................A& "hapter A............................................................................................................................AF ,roducing our forms......................................................................................................AF #he Form 8i;ard..........................................................................................................AC 6esign :iew and the ,roperties dialog bo*..................................................................AA 7adio uttons................................................................................................................D' #ab Stops Iand 7adio uttons5......................................................................................D& Forms with Sub Forms..................................................................................................D4 6rop 6own lists............................................................................................................DF /ist o*es with compound fields..................................................................................D@ 6efault values..............................................................................................................('' )ntering time and date................................................................................................('' Forms with two or more sub forms.............................................................................('4 "hapter D..........................................................................................................................((( ,roducing .ueries.......................................................................................................((( S./ 0ueries with ase................................................................................................((& uilt-in Functions in -S./........................................................................................((B Saving and "alling a .uery.........................................................................................((F 8hereG.........................................................................................................................((C "ompound 0ueries.......................................................................................................((@ Order in the room, please!...........................................................................................((A <ser defined parameters..............................................................................................((A .uerying more than one table at a time......................................................................(&' Aggregate Functions$..................................................................................................(&B Some time functions$...................................................................................................(4( "hapter ('........................................................................................................................(44 "reating reports with ase..........................................................................................(44 Our first 7eport with ase$.........................................................................................(4F Steps in designing a report$.........................................................................................(B( "reating a report with 7eport uilder Ithat is not in tabular form5............................(B( Analy;e the reportHs re0uirements and decide on the overall layout......................(B4 Select needed tables and columns..........................................................................(B4 "ompose 0uery.......................................................................................................(B4 <sing the S<N 7eport uilder....................................................................................(BF S<N 7eport uilder overview................................................................................(BF
iii

AS)

#<#O79A/

uilding a report with the S7 ..............................................................................(B@ <sing formulas and functions with S7 .....................................................................(F' <sing Formulas......................................................................................................(F( <sing Functions......................................................................................................(FB #he 7eport Navigator..................................................................................................(FD "ustom made functions...............................................................................................(C& "onditional formatting................................................................................................(CF A word of caution$.......................................................................................................(CC "hapter ((........................................................................................................................(C@ !aintenance of a 6atabase.........................................................................................(C@ !odifying data structure........................................................................................(C@ !odifying forms.....................................................................................................(CA 6efragmenting your 6atabase$...............................................................................(@' ac+ups$.................................................................................................................(@( "hapter (&........................................................................................................................(@4 Some final words$.......................................................................................................(@4

iv

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Introduction:
6atabases are very useful programs that allow us to store information, organi;e it, retrieve it and even e*tract new information from it. OpenOffice.org offers a very powerful database system with ase. ut because ase is a powerful and fle*ible application, you need to be able to ma+e some informed decisions while wor+ing with it and this, in turn, re0uires some preparation. #his tutorial will try to help you better understand the options offered by ase while attempting to develop a functional application of a medium level of comple*ity. #o achieve this, the first part of the tutorial will review some important concepts in the design of databases, that is, on how to organi;e the information that you need to collect. #he later part of this tutorial will show you how to implement those decisions while developing an actual application with ase. ,arts 9 and 99 of this tutorial cover some fundamental notions for organi;ing your information that applies to any attempt to design a database, including aseJ although they also describe some elements that are specific to it. ,art 999 is solely focused on ase and the way to implement your decisions with it. -owever, the three parts are necessary in order to understand how to effectively design database applications with ase. 9f you are reading this, chances are that you are a non-e*pert loo+ing for answers to concrete 0uestions and with very little time to spare. 9 hope that by following along these lines you will find concepts and tips that will help you design more useful, fle*ible and reliable databases. 2ou can be sure that there is a learning curve, but it is not steep. After all, the whole purpose of ase is to ma+e the development process easier. 9n any event, practice does perfect and mista+es are a problem only if you are planning not to learn from them. #his tutorial cannot cover all aspects of ase. ase has many features li+e the ability to be a front end for other database systems. 8e will focus on ase wor+ing with its own embedded database engine called -S./. )ven in this narrower topic we cannot cover all of its functionality. #he te*t will attempt to provide elements that could help you build a wor+ing database model with which to +eep trac+ of resources and processes li+e customers, rendition of services and cash flow. -owever, 9 hope that this tutorial will provide a foundation from which to continue your e*ploration of this application. ,lease note that this te*t has been arranged as a tutorial and not as a reference manual. #his means that the information here has been organi;ed thin+ing more on aiding the generation of meaning. 9 strongly suggest that you ma+e notes in the margins and compile summaries from this te*t and form with them your own reference manual later. ase is a great tool at your disposal and, the more you +now about it, the more functionality and fle*ibility you can get from it. 6onHt hesitate to read everything you can about ase. ,articularly, you will discover that there is a very active and +nowledgeable comv

AS)

#<#O79A/

munity at www.ooforum.com, to which 9 am particularly grateful and where you can find answers to 0uestions, post your own 0uestions if they happen to be uni0ue and maybe even share your own wisdom. 6onHt hesitate to participate! 9 have written this tutorial as a way to say than+ you to the open source community in general and the good fol+s involved with OpenOffice.org in particular. 9t is a lot of hard wor+ to +eep alive the ideals the open source software represents but is also most beneficial -and at several levels- for the rest of us. So hey, #han+s! 9 hope that you find this tutorial helpful and that you start ta+ing advantage of all the computational power that a database application li+e ase can provide.

!ariano "asanova New 2or+, Summer of &'('

vi

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Acknowledgments
!any people have helped me compile this te*t. 9 am very grateful of Kean -ollis 8eber who thought that a tutorial li+e this was necessary and swiftly connected me to people who could provide relevant information. 9 am also grateful of Andrew Kensen who very +indly e*plained to me the different data types used by ase wor+ing with -S./ and their different memory re0uirements. !r. Kensen also provided an early S./ code for this tutorial, answered all my 0uestions on how it wor+s and also tested the S./ code provided as e*amples in the tutorial. 9 also found great support and very important information at the OO.o Forum - ase on several concrete topics and specific 0uestions 9 had during the development of this te*t. 9n particular 9 am very appreciative of the help provided by 7om+e ,. Eroeneveld who +indly showed me how to use mathematical operators with 0ueries and the casting of variables to other data types. 9 also want to than+ all the people who sent me words of encouragement and comments about the te*t or the code so it could be corrected or perfected. !any people have offered their help proofreading this te*t and 9 want to e*press my gratitude to all of them, even if different circumstances Iincluding a terrible earth0ua+e5 prevented us from wor+ing together. 9n particular, 9 am very appreciative of the patience and unassuming help by !s. Kudy 6immic+ and the in-depth comments by Koe Smith. Finally, many than+s to everyone who thought that this was a worthwhile pro=ect and gave me the encouragement to see it through. #han+ you very much!

vii

,art 9
#hings you need to +now before you create a database with ase.

Contents: Chapter 1: Introduction to Databases. Chapter 2: ormal !orm. Chapter ": #ariable data t$pes.

Chapter
Introduction to databases.

A database allows for the semi-permanent storage of data. Semi-permanent means that you can later correct or update the record but, until you do so, it remains =ust li+e you left it. /ater on you can retrieve that piece of data and use it in a meaningful way. 6atabases are ama;ing beasts. 9 am sure that you +now that you can store names and addresses in a database and later generate mailing lists and bul+ mail or that you can +eep trac+ of your "6 collection with them. #his is already impressive. ut you can do much more than that. 6atabases can help you identify the wea+er lin+s in your production process or rendition of services, they can help you identify where your public comes from and how they discovered youJ they can help you +eep trac+ of the status of clientsH orders and cash-flow and calculate payments for wor+ers and fee per service professionals according to the number of hours wor+ed, pro=ect involvement and differential hourly feeJ hey! they can even help you learn about yourself. asically, a database helps you collect and organi;e data( and then, if you as+ appropriately, discover trends in your data that can help you organi;e your resources better. #he +ey concept here is 1as+ appropriately1. #o help you achieve this you need to ma+e sure that your data faithfully represents the fact that you need to record, that you can find this data when you needed it and that you can use it with no restrictions or complications. #his in turn is largely dependent on the way you design your database. So, the first thing that we are going to do in this tutorial is to describe some practices that allow for better design. 8e will start by naming the parts and bits that ma+e up our database in order to ma+e communication easier. 9n the later part of this tutorial we are going to assemble a database of medium comple*ity with ase. #hat will be the how-to. ut in order to understand the options we will e*ercise then, we need to review the why behind our actions, which also rests on some concepts in database design. /etHs get into this right away. 9nstead of =ust providing arid definitions, we will wor+ a plausible e*ample to illustrate the concepts. Anatom$ of a database: Tables% attributes and relationships. /etHs start with some general statements that we will then attempt to e*plain$ A database consists of a group of tables that are interrelated. A table records information about ob=ects that have the same characteristics. #hese characteristics are called attributes and are decided by you depending on the purpose of your database and the information you find necessary to collect and store. One attribute in a table can reference a record in another table, allowing tables to connect information in ways that are very fle*ible and powerful when you later want to retrieve this information from your database. 8e will e*amine
( And there is a little bit of us in the data we find relevant to collect and the way we organi;e it

AS)

#<#O79A/

this in depth. 8hen we say >database structure? we mean the collection of attributes you have chosen to build your tables with and the way these tables connect with one another. #he process of deciding on a database structure is called >data modeling?. #he heart of database design, then, consists of forming tables and deciding how to interconnect them. #his topic will occupy the rest of part 9 and part 99 of this tutorial. /etHs imagine that you have collected over ('.''' boo+s I9 +now someone who has done this!5. !aybe you donHt read them all but li+e to +now that you have them, who wrote them, when and things li+e that. !emory will fail with a big number li+e this and +eeping and consulting a written log can be very cumbersome as well. )nter ase and the help of databases. A database is a way of storing information that can be easily retrieved later. 2ou can retrieve a particular record Ie. g. 8ho is the author of >Around the 8orld in A' days?G5 or a summary of information Ie. g. list all boo+s by Kules :erne5. #he information in a database is organi;ed in tables. 8e will see later why it ma+es sense to use many tables in one database instead of =ust one big table. 9f you can find an e*ample where =ust one table would suffice, then you might find it more straightforward to wor+ it with "alc instead. #ables are organi;ed in columns Ifrom top to bottom5 and rows Ifrom left to right5. #he columns represent different attributes that you want to store. For e*ample, you can create the table >Authors? with the columns to store the attributes$ First Name, Surname, 6ate of irth, "ountry of irth and 6ate of 6eath. )ach row will hold one particular author, li+e$ Kules :erne, Ale*ander 6umas or ,ablo Neruda. )ach row is called a HrecordH. )ach cell -the intersection of a row with an attribute- can also be called a HrecordH, =ust to confuse you. 7ows are said to store >ob=ects? Isee figure (5.
This row holds the names of the attributes for the )Authors) table

Authors %irst &ame ,ablo Kules Surname 'ate o! Birth '@3&B3(A'& '@3(&3(D'B '&3'A3(A&A Country o! Birth France "hile France 'ate o! 'eath (&3'F3(A@' 'D3&D3(D@4 '43&B3(D'F

Ale*ander 6umas Neruda :erne

&ow: 'b(ect or &ecord

Column: Attribute Cell: *articular record

Figure 1: The 'Authors' Table


B

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Notice this$ some of the authors could not be dead but your table will not become obsolete if Ior rather when5 this happens. #his shows that in designing your tables, which information you decide to include and which not, will have an impact on the overall usefulness of the database. 6onHt panic =ust yet, as we will be describing some systematic ways to decide on what data is relevant to collect. esides, 9 am counting on your imagination and intelligence to sort this out. Now that we can collect information about the authors, we want to record the boo+s they wrote as well. !ost of us would thin+ about =ust adding more columns to record the boo+s. For this you would need at least one column for each title assuming that you only record the name of the boo+. 9f you also want to record the year of publication and the country of first publication, for e*ample, you would need three columns per title Isee figure &5.

Authors
First Name Surname 6ate Of irth "ountry 6ate Of 6eath oo+( ,ublication( "ountry( oo+& ,ublication& "ountry&

and etc.

Biographic info of the authors

Books written by the authors

Notice 3 columns per book

Figure 2: Unpopulated table for authors and their books /etHs say that each author has four or five titles, e*cept for one that has twenty. 2ou will need to create &' columns Ior C'!5 if you want to store your data faithfully, most of which would not be used, wasting computer memory and speed. And what if this author later writes a &(st boo+G 2ou will need to re-structure your database- adding new columns- and face unforeseen conse0uences that can come to haunt you later. 9nstead of ta+ing this route we could decide to focus on the boo+s instead and create a >#itles? table, with the attributes we need for each boo+, and later add the columns for AuthorHs name, surname and the rest. #his way it would not matter how many boo+s one author writes and we would not waste space with cells that would never be populated Isee figure 45.

AS)

#<#O79A/

Tit$es Book &ame #he #hree !us+eteers (ear (ABB In Country France France "hile Author 'ate o! Birth Country o! Birth 'ate o! 'eath (&3'F3(A@' (&3'F3(A@' 'D3&D3(D@4

A. 6umas '@3&B3(A'& France A. 6umas '@3&B3(A'& France ,. Neruda '@3(&3(D'B "hile

#he "ount of (ABC !onte "risto &' /ove (D&B ,oems and a song of despair One hundred (DC' love sonnets Around the world in A' days 9nvasion of the sea (A@4

Argentina ,. Neruda France K. :erne

'@3(&3(D'B "hile '&3'A3(A&A France

'D3&D3(D@4 '43&B3(D'F

(D'B

France

K. :erne

'&3'A3(A&A France

'43&B3(D'F

Figure 3: A 'Titles' table with author information Still, this would create new problems$ Note that we need to repeat the authorHs data for every boo+ the author wrote or writes in the future. #his complicates maintenance of the data. For e*ample, if one author dies, you need to locate every boo+ she wrote in order to add that data. 2ou also open the door for inconsistencies. 8hat if some boo+s have one date of birth for this author while others have a different dayG One Ior both dates5 is wrong. Now you need to +now which one is the correct day and find and modify each wrong record. 9nstead of trying to merge both tables into one we will +eep them separated, but we will find a way to connect the info in one table to the info in the other table. #his mista+e, trying to create one big comprehensive table, is very common and arises because beginners want to ma+e sure that all the relevant data is connected and forget that there are tools that can lin+ them in more fle*ible and powerful ways. #his is your first lesson in database design$ each table needs to cover one topic and one topic only. "reating tables that hold the attributes of both authors and titles is a bad idea. "reating tables that mi* employee and department attributes is a bad idea. "reating tables that mi* customers and services fields is a bad idea. 9nstead, you need to create one table for boo+s, one table for authors, one table for employees, one table for departments, one
C

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

table for customers, one table for services and so on. 9f you are ta+ing notes, write this down because 9 will as+ you later. +stablishing relationships within tables. -ow e*actly do we lin+ the HAuthorsH table with the H#itlesH tableG -ow do we ma+e sure that, for e*ample, the ob=ect HKules :erneH in the HAuthorsH tables can reference HAround the world in A' daysH in the H#itlesH table AN6 all the other boo+s written by himG #o accomplish this, you need to chose a field in the HAuthorsH table that uni0uely identifies each record. #he chosen field that uni0uely identifies each record is called a ' rimary !ey'. Now you create an e*tra column in the H#itlesH table that is going to hold the value of the primary +ey. #his column, that stores the primary +ey value of the lin+ed table, is said to store a '"oreign !ey'. For instance, you could decide that the HSurnameH field in the HAuthorsH table will be the primary +ey. 2ou then create a new column in the H#itlesH table -that you can call HauthorH if you li+e- and write the surname of the author with each boo+ record, correspondingly, in the column that holds the foreign +ey$ :erne, 6umas, Neruda, etc. #his HauthorH column in the H#itlesH table une0uivocally lin+s each boo+ with one author Isee figure B5. ase will use that inde* to lin+ and retrieve the information that you will be as+ing for later.

Tit$es Book &ame #he #hree !us+eteers #he "ount of !onte "risto &' /ove ,oems and a song of despair One hundred love sonnets Around the world in A' days 9nvasion of the sea (ear )u $ished (ABB (ABC (D&B (DC' (A@4 (D'B Country o! Pu $i"ation France France "hile Argentina France France Author *%+, 6umas 6umas Neruda Neruda :erne :erne

Figure : 'Titles' table linked to the 'Authors' table through the 'Author' foreign key #his way, for e*ample, you could as+ your database to list all > oo+ Name? where >Author? e0uals >Neruda?. Although you had not e*plicitly recorded such a list, the database can create it for you. 9magine how useful this is if, instead of si* records, you really have ten thousand! <sing a surname as a primary +ey wor+s fine many times, but has one drawbac+$ what happens if you have two authors with the same surnameG
@

AS)

#<#O79A/

One solution is to use more than =ust one field to form the primary +ey. 9n this case it is said that you have a compound primary key. For e*ample, you could use the first name and the surname, together, to form the primary +ey. #his solution is possible and perhaps in many cases the right one. Of course, we can also thin+ of instances where two authors have the same name and surname Ili+e Ale*ander 6umas, father and son, for e*ample5. 8e could e*tend the notion of a compound +ey and wor+ with a combination of three and even four fields to form a une0uivocal primary +ey, but thin+ of all the calculations the computer would have to do =ust to handle rare e*ceptions. #o simplify this, ase can automatically generate a uni0ue number for each record in a table. #his way each author would have a uni0ue number I6umas father would have one number, 6umas son would have a different number5 that you can record in the column for the foreign +ey in the H#itlesH table. 9nstead of writing H:erneH, H6umasH HNerudaH, the computer will write ''4, ''B, ''F or something li+e this. 2ou, as a user of the database, might not even be aware of the e*istence of these numbers or what numbers they are e*actly. #he relevant thing, however, is that these automatically generated numbers allow for a une0uivocal connection between one ob=ect in the HAuthorsH table with one or more ob=ects in the H#itlesH table. At other times, however, you could be using primary +eys that are not numbers or primary +eys that are compound. Leep this in mind. Our e*ample uses only one foreign +ey in the H#itlesH table, but donHt be surprised if you find yourself needing to record two or more foreign +eys in a table. #his is how tables are related! #he primary +ey is important in more ways than one, and we will chec+ this when we review the process of Normali;ation. Cardinalit$ and optionalit$ of a relationship. Notice this$ in our e*ample one author will have at least one and possibly many titles. On the other hand, one title can have e*actly one author only IletHs leave collaborations aside for now. 9 promise to include them by the end of this section5. 8hen you say $ >one author, many titles? you are tal+ing about the cardinality of the relationship. Note again that the relationship is not the same for authors and titles$ one author can have many titles, titles have e*actly one author. So, when we analy;e the relationship from author to title, the cardinals are$ (..n Ione to many5. 8hen we analy;e the relationship from title to author, the cardinals are$ (..( Ione to one5. Strictly spea+ing then, relationships always have two sets of cardinals. #he first number of the set is called >Optionality? and is usually a ;ero or a one. 9n the case it is a ;ero it means that a member of the class has the option to not relate to the second class. For e*ample, if the cardinality from title to author had been '..(, that would have meant that you can register a boo+ even if you donHt +now who the author is. -ere
A

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

you have something e*tra to thin+ about$ whether your database needs, or needs to avoid, ob=ects in one table that are not associated to ob=ects in the other table. Of course, both options are valid and which one you choose depends on the way you define their relationships. #he options for cardinality include$

Mero to one I'..(5 Mero to many I'..n5 One to one I(..(5 One to many I(..n5 !any to manyIn..m5

-ero to one implies the possibility that an ob=ect of the class is associated with none or at most one ob=ect of the other class. -ero to many implies the possibility that one ob=ect in the first table is associated to no ob=ect in the second table, to e*actly one or to many. #he ;ero optionality opens the possibility for the e*istence of an ob=ect even if is not associated to other ob=ects in other tables. One to one cardinality connotes properties of ob=ects in one table that are e*panded in the second table. /etHs say that some of your boo+s have beautiful illustrations -paintings, engravings, photos, etc- and others donHt. 2ou would want to register who was the artist, the name of the art piece and other data. 9t would be wasteful to include these attributes in the H#itlesH table, because most boo+s would leave these records unpopulated. Notice the Set-subset relationship here. 2ou have a set$ boo+s, and a subset$boo+s with illustrations. 2ou record the attributes common to all in the H#itlesH table and then create a new table >Art info? for e*ample- where you record the e*tra attributes of the subset. Oh! And of course, the foreign +ey. )very time you have a set-subset situation a (..( cardinality comes in handy. Note that if this cardinality were the same at both sides of the relationship Iin the direction subset-set5 then maybe both classes are really one big class&. A one to many cardinality implies that one ob=ect of the first class can relate to one or more ob=ects of the second class and that an ob=ect in the second class can not e*ist by itself. .any to many relationships can not be performed without the use of an intermediate table. For e*ample, one author could write one or more boo+sJ at the same time, one boo+ could be written by several authors Iin collaboration5. 9n order to +eep trac+ of this, you will need a simple table -maybe with only two columns- between the HAuthorH and H#itlesH tables that can record all the combinations of boo+ and author. #his will change the n..m cardinality to a manageable (..n or so. )very time you encounter a n..m cardinality, you +now that you will be using an intermediate table.

& Also note that the one optionality precludes having information about illustrations if it is not associated to a boo+.

AS)

#<#O79A/

,anaging relationships with column and delete options. 9n order to enforce and ma+e tidy the inclusion of primary +eys, foreign +eys and the cardinality of the relationships, ase allows you to specify certain options for the columns in your tables. 9n this tutorial we will consider the following ones$ +ey: #his option tells ase that this column will hold the primary +ey of the table. ase will prepare then to see it associated with other tables. Uni/ue: 8hen you specify this option, ase will ma+e sure that records in this column are not repeated. 9f, for e*ample, you specify that the HsurnameH column be uni0ue, then the second time you try to enter H6umasH, ase will re=ect it as an invalid entry. 9t ma+es a lot of sense to ma+e sure that a column set to L)2 is also set to <N9.<). &ot nu$$: #his option means that records cannot be left with this attribute empty. ase will display an error message if you try to enter a record that leaves a NO# N<// column empty. #his forces whomever is using your database to at least have the information re0uested in the NO# N<// columns if they want to enter the record. For e*ample, if you set the HsurnameH and Hdate of birthH as NO# N<//, then a user can not input a new author if he doesnHt have at least the surname and the date of birth. Again, it ma+es sense that Ley columns are also set to NO# N<//. #his option can also affect cardinalities. 9f you have decided that your database should be able to accept a boo+ entry even if it is not associated to an author, you can not set the foreign +ey to NO# N<//. On the other hand, if you will not accept a boo+ entry unless it is associated to an author, the foreign +ey should be set to NO# N<// in order to enforce this. ecause being able to relate the ob=ect in one table to another ob=ect in another table is so important, special care must be placed on the sub=ect of deleting records. #hin+ about this$ /etHs say that there is an author that wrote only one boo+ and you discover that you no longer have that boo+ in your collection. As you update your database and erase that title, what will happen to the HauthorH informationG Should it be deleted tooG Should it be +ept as an historical record or in case you find and buy one of his boo+s againG Actually, both options are valid and you can chose the one that reflects the purpose of your database better. ut your application will not +now what to do unless you ma+e e*plicit what your preference is. For this reason, when you are developing your application and defining relationships, ase will need instructions on how to handle the deletion of records and will offer you the following options. #his is what they mean$ &o a"tion: ase will delete the record you want but will not delete the records associated with it. #his way, you can delete the missing boo+ and +eep the record of the author that wrote it. 'e$ete Cas"ade: 8ith this option, ase will delete the record you are re0uesting to delete and will also delete all other records that have this recordHs +ey as a foreign +ey. #his option is called cascade because it elicits the image of a deletion creating further deletions.

('

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Following the e*ample, if you delete the author, any boo+ associated to him will be deleted too. Set &u$$: 8ith this option, ase will delete the record you are re0uesting but will not delete the other records related to it. 9nstead it will erase their foreign +eys to reflect that they are no longer associated to other ob=ects. Note that this re0uires that NO# N<// is not a condition of the foreign +ey column. 9f you decide to erase the author in the e*ample, the boo+ record would not be deleted but you would find that it no longer has data for the foreign +ey, i. e. 9t would be set to null. Set 'e!au$t: 8hen deleting an ob=ect, the foreign +ey column of the associated tables will be populated with a default parameter that you previously specify. #his way, instead of =ust leaving an empty foreign +ey in the boo+ record, ase could write, for e*ample Iand this is completely arbitrary5 >'''?, which you +now means >9 have no author info for this boo+ in this database?.

A definition of database and database design.


9t too+ some time, but now that we have described a database and its properties, we are ready to offer a definition of 6atabase and ase 6atabase. 8e have seen that database design uses many tables that are all related one way or another. )ach table will only cover one particular topic or unity Iauthors, titles, places, events, etc.5. #hese topics are called classes. A class is a collection of ob=ects that have the same attributes. 9n database theory, each class translates to a table. 8ith that said, we can attempt to define a 7elational 6atabase as a collection of ob=ects -organi;ed in classes- and their relationships4. #his definition didnHt ta+e long to write but you wonHt be deceived by this illusory simplicity. 2ou can appreciate that Hob=ectH has a rather precise meaning and is a central element in the conformation of your classes and that there is a big chun+ of +nowledge around the concept of relationship, particularly because of its fundamental role in connecting information. 6atabase design, then, is about deciding on class structure Iwhich classes to wor+ with and which attributes to record in each5 and the structure of connections they establish Iwhich table connects with which and with what cardinality5. Of course, you also need a method to add records to your tables. And you need a method to retrieve useful information -li+e particular records or summaries- to produce reports. ase offers forms, 0ueries and reports for this. For this reason, when we say a H ase databaseH, we mean not only the data and their relationships but also the forms, 0ueries and reports to use it.
4 Kust to be clear, the name >7elational 6atabase? derives from the use of the word HrelationH which is a way used in mathematics ISet #heory5 to say table. 9n conse0uence, when we say Hrelational databaseH we mean$ Hdatabase that uses tablesH, which is a distinct feature when we compare this to other database models Ie.g. -ierarchical, Networ+, etc.5 and is not an emphasis on our intent to relate -or connect- data.

((

AS)

#<#O79A/

Talking about forms and reports...


Forms allow you to enter data to populate your tables. 8ith ase, you can build them by using the Form 8i;ard, which simplifies the tas+, or in design mode, which gives you ma*imum fle*ibility. 8hen building forms you will need to thin+ about what you want them to achieve and this in turn re0uires that you understand what do the different options offered in building them mean. 8e will review this more closely in part 999. Not surprisingly, the time you spend thin+ing about the design of your forms will be paid bac+ with better performance and efficiency. Among these considerations, you need to ma+e sure that the user of your form understands e*actly what she3he is being as+ed Ie.g. #o the entry >Se*$? do you input >!ale? or >Scarcely?G5. 9t is not uncommon that we use words believing that they have a very precise meaning but later discover that they can be ambiguous. #hat is because when we use a word, it correlates strongly with an image in our mind, but our readers could have other associations. #he conte*t in which they appear can also suggest meanings that were not intended. #o avoid traps li+e these you need to test and test and test your forms, as+ing friends to read them and give you feedbac+ about what they understand and how they thin+ they should answer. )ven if you thin+ that you will be the only one using your forms, you never +now when someone will show up to help you with data entry or when someone will as+ you for a copy of your application to use it herself. #he other important aspect of forms is that you want to ensure that data entry is uniform, that is, that the same element is entered in the same way every time. 9n general, ase will consider as different entities two spellings of the same word. Also, if you are not consistent with the use of capitals, ase can consider H:erneH and HverneH, for e*ample, as two different ob=ects. #his could lead to wrong summaries of data or records impossible to find. ase offers a type of variable that treats words with the same letters as the same word, no matter how you capitali;e them. #his can be very helpful. -owever, if you are +eeping customer data, you would not want to have them receive mail with their names carelessly treated, as in >6ear !r. S!ith?, so you still need to monitor input. ase offers several ways to handle this. One of my favorites is the drop-down menu, where you point-and-clic+ your entry. 2ou can also use chec+ lists and circular buttons. 8hat they have in common is that they automati;e the entry of data. ase also offers functions with which you standardi;e data entry, for e*ample, changing all letters to small caps Ias in >pro")du7e? to >procedure?5. Of course, this means more wor+ while you are developing your form, but ase ma+es it really easy and itHs worth the e*tra effort. For data output you have the 7eports. #hey are usually built by 0ueries and you also have the options of either getting help from the 8i;ard or using the full fle*ibility of 6esign !ode. 8e will also spend time in part 999 studying this. 8hat 9 want to point out is that reports need to be easy to read, unambiguous and provide the necessary information. #his means that spending some time in their design is also bound to repay you later with added efficiency. For e*ample, 9 always recommend to include time data in a report so we can be sure about when the information presented was valid.
(&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

So get as many people as you can to test your forms and reports. At the same time, test your database design. See if someone can fool your input options or find e*ceptions that are possible but that your design canHt handle. #est, #est, #est. 9t is easier to ma+e changes at earlier stages than trying to repair a live version.

,odeling data and goals of proper design.


9n designing your database, you will need to define the classes that you will be wor+ing with Iboo+s, authors, etc.5 and what relationships within them you need. #hen you need to decide on the structure of each table, that is, what attributes you need to record for each class Iname, surname, etc. or title, year of publication, etc.5 and what properties you will give to the columns Inot null, uni0ue, etc.5. 2ou canHt attempt to collect A// information about your classes and you will need to edit your selections according to the )ur0 )ose of your database. 2ou will then need to refine the structure of connections, deciding not only what table connects with which, but also the cardinality and optionality they use, the type of primary +eys that you choose and how to treat deletions. #hese decisions might also influence, or be influenced by, the order in which your forms as+ for the information and the reports that will ma+e sense to produce. 8hen you are deciding all this and fine tuning your decisions, it is said that you are modeling your data. 6onHt feel dismayed by all this. #he sub=ect of database design is vast and comple* enough to comprise several years of college education. So it is going to ta+e some time and patience for you to feel comfortable with these concepts and the ways to implement them. ut you donHt need to be a roc+et scientist to become 0uite proficient at wor+ing with ase. #he description offered in the previous paragraph is 0uite a good summary. 7ead it and translate it to a numbered list and then try to visuali;e your actions at each step. #his is e*actly what we will do in part 99 of the tutorial. One of the most important aspects in data modeling is defining Ialso said He*tractingH5 your classes. 8e will review two ways for doing this. #he first is a conse0uence of your activities during the different phases of database design, which we will describe shortly. #he second is a formal method called Normali;ation. Normali;ation is a formal method because it does not analy;e the content of your tables Iit does not care if the classes are boo+s or authors or if the attributes are names or dates, etc.5 but focuses on certain mechanical connections of the primary +ey. #here are several normal forms and, in this tutorial, we will review three$ first, second and third normal form. 9n your wor+ you will be doing both, content analysis and formal analysis. #here is no one way to design a relational database. 2our design will reflect your level of preparation and e*perience. #he techni0ues we will review here are only tools to help you ma+e better decisions. 9n general, however, you will want your database to avoid repeating information while still recording all the data you needJ that your database can grow, as your collection of data grows, without a brea+down in functionality, and that your database has some fle*ibility to handle entries that are not common but possible. ,rincipally, you want your database to provide the information you need and that such information is valid for the sample from which it was e*tracted.
(4

AS)

#<#O79A/

9n order to ensure this, modeling e*perts tal+ about )ntity 9ntegrity, 7eferential 9ntegrity and 6ata 9ntegrity. )ntity 9ntegrity means that each row of a table represents only one entity in the database. #herefore, each entity can be assigned a uni0ue Iand only one5 primary +ey. 7eferential integrity means that all foreign +eys in all tables must be matched by a row in another table Iobviously, a primary +ey5. Finally, 6ata 9ntegrity means that all data in the database correctly represents the fact that it aims to collect. #his is achieved basically by minimi;ing data entry error -you +now- misspelling of names, repetition of characters, transposition of numerical digits, wrong or impossible dates and a long etcetera. #hroughout, we will be reviewing ways to achieve these goals of proper design.

#isual vocabular$.
6atabase design is aided by a diagram protocol called <!/, acronym for <nified !odeling /anguage. <!/ provides a standardi;ed way to signify components or aspects of the 6atabase. /etHs see this$ "lasses are often notated this way$ "lass Name "lass ,roperty ( "lass ,roperty & "lass ,roperty 4 etc. "lass !ethod ( "lass !ethod & "lass !ethod 4 etc. See the e*amples$ Authors Name Surname 6ate of irth "ountry of Origin Produ"ts Name 6escription "ompany .uantity ,roduce appropriate re0uest form if 0uantity is less than 4'' units

Notice that this class has no { methods

Class properties correspond to the attributes of your class, which later form the columns in your tables.

(B

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#he relationships are commonly notated by a line or arrow between the classes$ Author

Tit$es

ecause in the design of a database you are mostly concerned with the classes and their relationships, these two elements will suffice for now to describe, thin+ about and communicate with others the structure we give to our data I#hat is, the structure of our classes -which attributes we will want to record- and the structure of connections -what table connects with what table and with what cardinality5. <!/ offers other elements but we will not review them here. 2ou can imagine that, in the process of fleshing out the design of your database, you are prone to spend a lot of time drawing bo*es, connecting them with lines, deciding on cardinalities and deciding which attributes to include in each class. 9tHs funny to notice that this very important phase of database design is best aided by a simple pencil and paper. -owever, this is very powerful. 8e have already hinted at the fact that you will be wor+ing with several tables and the more thought you invest in the design, the more fle*ible, reliable and functional it might become. "hanges in design now are =ust a matter of erasing a line and drawing a new one or deleting or adding attributes instead of trying to undo part of your wor+ in front of the computer while trying to retain other decisions at the same time. 8ith the level of abstraction offered by <!/, you can focus on deciding the general structure of your database and deal with the details later. /et me note that 6raw offers a fle*ible set of tools for drawing bo*es and connecting them with arrows. 6raw can even let you easily ad=ust the arrows, for e*ample, if you have several bo*es and need to surf the connections between them. 2ou can also find other freeware for doing this, li+e 6ia Ia EN< license pro=ect5 that comes with a complete set of <!/ tools. /ater, when we discuss the database we will wor+ with in part 99 of this tutorial, you will see how our design decisions are represented in the diagrams, how this simplifies the communication about the design and how this translates into the development of the application. A more formal rendition of your design should include the names of your attributes in the corresponding classes and the identification of the primary and foreign +eys. #he relationships should indicate the cardinalities and the arrows should go from the primary +ey to the foreign +eys Ifigure F5.

(F

AS)

#<#O79A/

Author 96 number I+ey5 Name Surname 6ate of irth "ountry of origin 6ate of death
(..n

Tit$es 96 number I+ey5 Name of oo+ 2ear of publication "ountry of first pub. (..( Author Iforeign +ey5

%igure 1: U.L diagram !or the Author and Tit$es data ase

*hases in database design.


9n general, the effort to design a database will start with someone finding a problem in the real world. 9t can be a dentist trying to organi;e his clients and lab wor+ or a company trying to +eep inventory of on-line sales. #his person will need help from someone with +nowledge of database design and in implementing it with ase. /etHs call the person a HclientH and the e*pert the HdeveloperH. Of course, the client and the developer can be the same person -and if you are reading this, then this is most probably the case. ut 9 ma+e the distinction because a dialog between the client and the developer is always necessary, even if it only ta+es place inside someoneHs head. <sually, the client has a general idea of what he wants and the developer will as+ 0uestions in order to be able to translate the need into a well developed database application. roadly, the phases of database development can be described in the following way$ (. &. 4. B. F. ,resenting problem is identified ,ossible solution is defined 6ata modeling !odel testing 6atabase running and maintenance

6uring the first phase, the client tries to e*plain what his needs are -which are often multiple- and the e*pert tries to help him narrow it down to the +ind of tas+s a database can really perform. 9n the second phase, the e*pert develops a formal statement of the goals and scope of the database application. #his is important because a small change in a goal can produce important changes in the design of the database. esides you will discover yourself becoming more ambitious with what you want your database to do. 9f you donHt set a line somewhere, you can find yourself ma+ing your model progressively more and more comple* and never actually develop your application or, worse, have it perform erratically as you +eep modifying data structure.
(C

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Now that, as the e*pert, you have defined the scope and goals of the database, you are in the privileged position to decide which information is relevant and which not. 2ou can ma+e better decisions that can help define classes and attributes, primary +eys and relationships with ;ero or one cardinalities. #his is the e*traction of classes we earlier identified with "ontent ana$ysis. 2ou can also s+etch and consider the forms and reports that your application will need and how they integrate with the design. Of course, you also have to test your logic and grammar by as+ing friends to find holes in your design and meaning in your reports and forms. #hese two phases do not have a clear boundary because the testing will impose changes in your design and the new design will need to be tested. 6onHt mind spending some time here and test, test test! Now that you feel confident of your database design Iclass structure and structure of connections5 and the forms and reports you want to use, it is time to code them with ase. Now you are sitting in front of the computer for the first time since the pro=ect started! Of course, if you are in the process of learning then 9 strongly encourage you to sit and play around with ase, the more the better, so that you can become ac0uainted with its different screens, dialog bo*es and options. ut if you are in the tas+ of designing a database, this is the first time that you really need to interact with the computer. 6uring maintenance, you test that your database remains consistent and able to handle the growing number of data it receives. 6efragmenting your database and ma+ing bac+ups that could get you up and running should disaster ensue seems appropriate. Now is when you can also try to introduce the features that you didnHt thin+ of before and that can ma+e your application run faster or more efficiently. Of course, these changes need to be permitted by the structure of your database. 8hen your structure can no longer accommodate the new functionality that you want, then maybe itHs time to go for a new design. #he more that you, as the e*pert, 0uestion the client and become familiar with the business process, the better your decisions for class e*traction and table structure. <sually, the actors involved in the productive process Icustomers, providers of service, suppliers, investors, etc.5 become classes. 6ifferent phases in the production processes Irecorded as schedules or logs5, places Ie.g. the different stores of the chain5 and even events Ie.g. rendition of services5 can also become classes. Some data can be better recorded as tablesJ some other times you will find that the same data is better recorded as attributes. #he difference is set by the purpose Ifunctionality5 of the database. -ere is where imagination and e*perience come in very handy. #ry out your ideas and see what happens. 7ead about database design and donHt fear to as+ other people Iespecially if they +now something about database design!5. #he other tool for deciding on class e*traction is Normali;ation, which deserves a chapter of its own.

(@

AS)

#<#O79A/

(A

Chapter
-etting into normal form.
#ypical problems avoided with proper normali;ation include$

Normali;ation is a formal way to ensure that our tables have a good structure, that is, that each table has the appropriate attributes.

<nable to create a record without information from a foreign record. 6eleting one record will result in other data being lost. 6ata being repeated in other fields Ior tables5 resulting in possible inconsistent records of data.

!any of these problems have to do with deciding if certain data should be organi;ed by itself -in a table of its own- or as fields in a host table. ecause this is a formal method, we will not deal with the actual content of our tables Iwhich is what we are supposed to do the rest of the time anyway5 but will analy;e certain mechanical connections of the primary +ey. A +ey concept of normali;ation is that of HFunctional 6ependencyH.#his concept means that there is one field Ithe primary +ey5 or more fields Ifor a compound primary +ey5 of a record that is3are enough to help me identify any other field Iattribute5 of that record, that is to say that +nowing the value of any field de)ends on +nowing the value of the primary +ey. "learly, true primary +eys help me identify -or determine- all other attributes in a record Irow5. #his also means that, if we have a compound +ey and one of the fields in it turns out to be superfluous or redundant, then this primary +ey is not a true primary +ey, itHs =ust a +ey. #herefore, a primary +ey has no subset of fields that is also a primary +ey. !any times the vastness and comple*ity of the data in our database obscure this leanness, potentially creating problems li+e those described above. y analy;ing functional dependency -at several levels- we can identify if our data structure is compromised or not and avoid those problems. #here are several normal forms and in this tutorial we will cover three$ first, second and third normal form.

AS)

#<#O79A/

!irst normal form. According to this rule, a table must not try to keep multiple values for a piece of informa# tion, whether in one field or in multiple columns. 8e would have this situation if we tried to include in the HAuthorsH table all the boo+s written by them. /etHs say that we create a column called H oo+sH and then we cram together H#he "ount of !onte "ristoH, H#he #hree !us+eteersH, H#he !an in the 9ron !as+H and etc., all separated by commas, for the record of A. 6umas. )ven if we use several columns I oo+(, oo+&, oo+4, etc.5 we are still trying to cram multiple values Ithe name of the different titles5 for one type of information I oo+s written by author5. 8e already saw other reasons why this is a bad idea. First normal form helps us identify this problem. 9t also offers a generic solution$ 9f a table is not in first normal form, remove the multivalued information from the table and create a new table with that information. 9nclude the primary +ey of the original table as a foreign +ey. 9n our e*ample, this would result in the creation of the H#itlesH table, with info on the boo+s, and a relationship to the HAuthorsH table. Although not immediately evident, first normal form solves a problem of functional dependency, as the authorsH primary +ey would have not helped to identify a particular value for the multivalued field. 9f 9 as+ you to provide a concrete title for a particular author, you have no way for selecting it. #hin+ing in terms of e*tracting multivalued pieces of information is very simple and completely e0uivalent to the analysis we did in the earlier chapter with this same e*ample. .econd normal form Second normal form re0uires that a table be in first normal form AN6 that all fields in the table $that are not primary keys% can be identified only by the primary key and not by a subset of it. y definition, this problem can arise only when we have a compound primary +ey to identify a record. #o e*plain this, letHs analy;e the following table$
Tea"her I' mac+ormac'4& ,hillipi@& mac+ormac'4& ,hillipi@& Pro2e"t &ame Science Fair Soccer coach Art "ontest Science Fair 'e)artment Science 6ept Athletic 6ept Art 6epartment Science 6ept Conta"t 4BB-&@(4 &&F-FD'& C4D-C@DA 4BB-&@(4 3ours (' (A @ (F

&'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

9s this table in first normal formG 2es, 9f 9 tell you the primary +ey, you can identify uni0ue values for the other fields. 9n this case, the primary +ey is a compound +ey that re0uires the #eacher 96 and the ,ro=ect Name. 9 need both bits of information to +now, for e*ample, how many hours have been devoted by a certain teacher to a certain pro=ect. ut it is also true that 9 only need the ,ro=ect name if 9 want to +now the involved department or the contact information. Oops! So, while 9 am thin+ing that #eacher 96 and ,ro=ect Name form the compound primary +ey, it turns out that a subset of it -the ,ro=ect Name- is a primary +ey for certain fields in this table. #o solve this, we need to e*tract the info related to the subset primary +ey I6epartment and "ontact5 and form a new table with them, including the subset +ey they depend on I,ro=ect Name5. #his process is called H6ecompositionH. 6ecomposing the table of the e*ample we get$
Tea"her I' Pro2e"t &ame 3ours Pro2e"t &ame 'e)artment Conta"t

and

Note that the original table retains the entire compound +ey I#eacher 96 and ,ro=ect Name5 and the info that functionally depends on it I-ours5. /ets restate this in formal parlance$ A table is in second normal form if it is in first normal form and we need all the fields in the key to determine the value of non#key fields. &f a table is not in second normal form, remove the non#key fields that do not de# pend on the whole of the compound primary key, then create a table with these fields and the part of the primary key they do depend on.

Third normal form Third normal form re'uires a table to be in second normal form A() that you can not use regular fields Ithat is, that are not +ey fields5 to determine other regular fields. 9n other words, you need to ma+e sure that only +ey fields determine non-+ey fields. #o ma+e sense of this, letHs analy;e to following e*ample$

&(

AS)

#<#O79A/

Tea"her I' fsmith'AD mlingC(D syor+&44

Surname &ame Smith /ing 2or+ Fred !ei Susan

'e)artment I' 'e)artment &ame (@ (@ (A Science Science -istory

9f each teacher wor+s for only one department, then this table is in first and second normal form. /et us analy;e this$ (. 9f 9 +now the teacherHs primary +ey Ithe #eacher 965 9 can tell you a uni0ue value for all the other fields. &. #he primary +ey is not compound, so 9 have no possibility of subset conflicts. -owever, notice that there is information about the department that is repeated Idepartment 96 and 6epartment Name5 and could become inconsistent Ie.g. 9t seems that the Science 6ept. has been assigned the 96 number (@. 9f we later find a record that assigns the number &4 instead, we would have an inconsistency5. Further, it is possible to determine the 6epartment Name by +nowing the 6epartment 96, which is not a primary +ey, and vice#versa. 9n this case, we remove the regular fields that are dependent on the non#key field I9n this case, we remove the 6epartment Name5 and create a table with it, in which we also in# clude the field they depend on Ithe 6epartment 965, left as their primary key. #his way we would have$
Tea"her I' Surname &ame 'e)artment I'

and
'e)artment I' 'e)artment &ame

9n formal parlance we have$ A table is in third normal form if it is in second normal form and we cannot use non#key fields to determine other non#key fields. &f a table is not in third normal form, remove the regular fields that are dependent on the non#key field and create a table with them, including the field they depend on as their primary key.
&&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Aiming for simplicit$


An analysis of functional dependency can easily identify decisions in table structure that will create problems sooner or later. Notice that some of the decisions made with Normali;ation had already been implemented with content analysis. #his shows that both tools have an area of overlap. #his is fine. Normali;ation can help us simplify structure when we are very in love with the table designs we have done and it hurts us to chop them further. And believe me$ simple is better! -owever, in the process of designing your database, you will be using both tools$ Normali;ation and content analysis i. e., the e*traction of classes by understanding the production processes, the +ey roles involved, the re0uired reports and the overall purpose of the database.

&4

AS)

#<#O79A/

&B

Chapter
&ecording attributes: Are $ou m$ variable/
#he data that you will store in your tables will actually be stored as variables in your computer. "omputers have different ways of storing data. 9n general, they trade memory or speed for accuracy$ "omputations that re0uire more accuracy tend to be slower and use more memory. 8hen you are building your tables with ase, you are as+ed what +ind of variables you want to store and are presented with a drop-down menu of options. #he decisions you ma+e will affect the performance of your database. #o better understand what these options mean and how they affect the way ase handles your variables, it is necessary to review the way computers handle data. 9n general, computers handle numbers and characters differently. Some people are confused by the fact that numbers can be treated as characters also. e. g. H@H is a sign that represents the concept of seven. 9n that sense, it is stored in the same way as the signs HNH or HOH or the letter HAH. As a character, the sign can not be operated mathematically, =ust as it would not ma+e sense to calculate the sum of HNH and HOH. ,hone numbers are good candidates for being stored as characters. Of course, any information that uses te*t is also stored as characters. Addresses need both, numbers and te*t, but we store them all as characters. 8hether they are letters or numbers, when we are only storing the signs Ias opposed to the value for a number5 we call them HAlphanumeric charactersH. "omputers have different ways of storing alphanumeric characters. For e*ample there is the AS"99 code, that needs only one byte to store a character. <nfortunately, this limits the number of possible characters that you can use to only &FC. Although enough for many applications, it falls short if you want to have access to e*panded character sets$ "hinese or Arabic characters, accented vowels Idiacritics5 and things li+e that. ,rotocols that allow for lager numbers of characters have been developed, li+e <nicode, that use more bytes per character. ase will store alphanumeric characters using <#F-A, which is a code that is compatible with both AS"99 and <nicode. ase will use one or more bytes for each character according to internal calculations. 8hen ase as+s you the length for a particular record, e.g. Surname of Author, it is not as+ing the number of ytes you want to allocate but for the number of characters you want to receive. -ow many bytes are actually used is fi*ed by the software. #his is not the case when you store the value for a number. 6ifferent ways of storing numbers will re0uire more or less bytes. /etHs see why$ "omputers store information in binary form. #he unit is called a HbitH and can have one of two values Ithus binary5$ either ;ero or one Ior On and Off, or 4.F volts and F :olts, or

AS)

#<#O79A/

any of two possible states5. its are organi;ed in larger groups -usually eight bits- to form a yte. 9n this conceptual representation a byte is drawn as a bo* with eight spaces. )ach space can hold a ;ero or a one$
0$te:

'

'

'

'
0it

Since this is a binary numeral system, each bo* represents a power of two, in the same way our decimal number system assigns successive powers of ten from right to left$ &@ 8hich is to say$ (&A CB 4& (C A B & ( &C &F &B &4 && &( &'

#o represent the number five, you would need to HactivateH or indicate the numbers for four and one Ibecause four plus one is five5. So your byte representing five would loo+ li+e this$ ' ' ' ' ' ( ' ( PF

8ith a little bit of math you can figure out that you can represent all numbers from ' to &FF Ithat is &FC numbers in total5 using one byte. 9f you need to store numbers bigger than &FF then you need to add e*tra bytes. ase offers different amounts of byte aggregate options to store numbers, depending on how potentially big the values that you need to record are. "hec+ the chart below to get and idea. Now, what if you need to store negative numbers, say -@G #he solution for this has been to use the last bit to the left of your byte to represent the sign and use the other seven bits to represent the number. ecause the last bit no longer represents the value (&A but instead wor+s as a flag to indicate if the number is positive or negative, we can represent numbers form -(&A to (&@ with this arrangementB. #his type of bytes are called HsignedH bytes, while the bytes that only store positive numbers are called Hunsigned bytesH. #he chart below indicates which options are signed or unsigned and helps you +now the range of values you can store with them.
B #he binary negative numbers are deduced by a techni0ue called two's complement where ('''''''P -(&A and (''''''(P -(&@... ((((((('P -&, ((((((((P -(, ''''''''P', '''''''(P(, ''''''('P&... '((((((((P(&@ and around again. #his way the machine can subtract numbers by adding a number with the twoHs complement of the other number and not have to attempt really complicated alternative ways of subtracting.

&C

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Again, if you need to store values beyond these boundaries, you need to add more bytes, which uses more memory per record. 9n any event, only the leftmost bit, also called H!ost Significant bitH I!Sb5 will act as a flag, that is, if you are using two bytes, the !Sb will act as a flag and the other (F bits will store numbers. 8ith this information, you can calculate the range of such a variable. 9n general, &umeri" data varia $es are described by the number of bytes they use and whether they are signed or unsigned. #hese two factors determine the range of possible values they can hold. ase offers several types of numeric data variables, both signed and unsigned and using different amount of bytes. At the least memory consuming side of number storage we have the oolean numbers. A oolean number is in fact =ust a bit, and we use it to store 2)S3NO type of data, li+e and answer to the 0uestion Hhave you ever been to -awaiiG At the other end there are variables called Hfloating point numbersH I=ust HFloatH to family and friends5 that allow us to store numbers that have decimal places li+e (.C(A'44... #hey are the most memory consuming numbers but the only ones that can perform divisions with good accuracy. Table 1! "umeri# Type $ariables: Used for storing numeri# %alues! &ame 'ata ty)e &o# o! Bytes Signed Range oolean #inyint Smallint 9nteger igint Numeric 6ecimal 7eal Float 6ouble yes3no #iny 9nteger Small 9nteger 9nteger ig integer Number 6ecimal 7eal Float 6ouble ( it ( yte & ytes B ytes A ytes No limit No limit B ytes B ytes B ytes ---No 2es 2es 2es 2es 2es 2es 2es 2es '-( ' Q &FF -4&@CA to 4&@CA -&.(B * ('D to &.(B * ('D -&.4 * ('(A to &.4 * ('(A <nlimited <nlimited F * ('4&B to (.@D * ('4'A F * ('4&B to (.@D * ('4'A F * ('4&B to (.@D * ('4'A

2ou might have noticed that many numeric variables in ase using -S./ have the same parameters. #his is because those variables might behave differently when ase acts as a front end for other database systems. 8hen you use the -S./ embedded engine -li+e in this tutorial-, you can consider these variables as interchangeable. #o be more precise, ase using -S./ understands N<!)79" and 6)"9!A/ as one set of interchangeable types of numeric data. #heir characteristic is that they can hold very large numbers. On the other hand, 7)A/, F/OA# and 6O< /), also interchangeable, handle better the divisions. For e*ample, if you store A and (' as N<!)79" and then as+ for ('3A, ase will return (.&. 9f you store them as 7)A/, it will return$ (.&F.
&@

AS)

#<#O79A/

6onHt be afraid to use all variable types at your disposal. Kust ma+e sure you assign the data type that best describes the values you need to store. 9f your database records the number of children or previous spouses of a person, an unsigned byte should be enough and a signed double would be a waste. Not only does this planning save memory but it also ensures that the application will run as fast as it can and will be less prone to brea+downs. #he same care should be e*ercised with A$)hanumeri" "hara"ters. Although the number of bytes per character might depend on the code system used Ie. g. AS"99 or <nicode5, ase allows you to limit the ma*imum number of characters it will accept for an entry. -ere you have some options$ /ets say that you have the attribute HSurnameH. 2ou assign it a "-A7 Ifi*ed5 data type and give it the value of F'. #his means that ase will assign a space of e4a"t$y F' characters to store each HSurnameH entry. 8hat if you enter the name H:erneH, that only uses F charactersG #he computer will store H:erneH and BF blan+ characters. 9nstead, if you assign the variable type :A7 "-A7 I:ar short for H:ariableH5 and the value F' then the computer will store u) to F' characters and not more <# would only store F characters for the entry H:erneH, saving you memory. 9f you try to store more than F' characters, ase will only record the first F' characters and ignore the rest. 2ou will have to do some research before assigning length values. F' characters could seem li+e a waste for surnames, but five or ten could be dangerously low. Also chec+ address formats and the length of street names that could show up. 2ou will notice in the chart below that the different alphanumeric data types can store, as of the time of this writing, up to & gigabytes of characters, which is more than plenty. 2ou will also note that the parameters are the same for several data types. Again, in -S./ they can be considered e0uivalent. Table 2! Alphanumeri# Type $ariables: Used for storing alphanumeri# #hara#ters! &ame 'ata ty)e .a4 $ength 'es"ri)tion !emo /ong :ar "har & E for 4& bit OS Stores up to the ma* length or number indicated by user. 9t accepts any <#F A "haracter Stores e*actly the length specified by user. ,ads with trailing spaces for shorter strings. Accepts any <#F A "haracter. Stores up to the specified length. No padding ISame as long var char5 Stores up the the specified length. "omparisons are not case sensitive but stores capitals as you type them.

#e*t Ifi*5 "har

&E for 4& bit OS

#e*t #e*t

:ar "har

&E for 4& bit OS

:ar "har 9gnore &E for 4& bit OS "ase

&A

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Another important type of variable is the 'ate type. #hey are used to store calendar information li+e year, month, day, hour, minute, second and fraction of a second. #here are several types, designed to be the most efficient in storing some or all of this information. 'ate allows you to store year, month and day as it is stored in your computer Iyes, your computer +eeps trac+ of this. Other database systems use the time stored in servers in the 9nternet -which could be more precise, but then they re0uire an 9nternet connection5. #he same is true for the Time type variable, which stores the time of the day$ hour, minute and second. e sure to understand the format in which this information is given. #he <SA uses the month before the day. Other countries use the day before the month. Some countries use the am3pm format while others use the military format Ie.g (D$4' hrs. for @$4' in the evening5. #hese preferences are set globally when you assign the language for the OpenOffice.org suite. Finally, some procedures might need you to record both the time and day of an event. Timestam) has been designed for this, recording all information at once. Table 3! &alendar Type $ariables: used for storing dates and hours! &ame 'es"ri)tion %ormat 6ate #ime #imestamp Stores month, day and year information Stores hour, minute and second info Stores date and time information (3(3DD or (3(3DDDD Seconds since (3(3(D@'

#he Binary ty)e varia $es allow you to store any information that comes as a long string of ;eros and ones. 6igiti;ed images use this format. 6igiti;ed sound uses this format too. 9n general, anything digiti;ed is stored as a long se0uence of ;eros and ones. #hey are told apart by the computer because the first ;eros and ones identify the +ind of file they represent Ia K,)E image or an !,4 file, etc.5. -owever, ase will ma+e no attempt to identify the +ind of file you have stored. #his is to say that it wonHt care if the file is an !,4 or a #9FF and it will happily store it, regardless. #he only limitation is the amount of memory the file uses. At the time of the writing of this tutorial, the ma*imum amount of memory ase will use to store inary variables is & gigabytes. #his in effect means that you could use a ase database to store, for e*ample, photos of the members of a pro=ect or the staff , or sound snippets or voice messages. -owever, be warned that images and sounds tend to use a lot of memory and limit the functionality of your database. Again, the different inary types can be assumed as interchangeable when using the embedded -S./ database engine.

&D

AS)

#<#O79A/

Table ! 'inary Type %ariables: Used for storing files like ()*+s, -p3s, et#!: &ame 'ata ty)e .a4 $ength 'es"ri)tion 9mage inary inary Ifi*5 /ong :ar inary :ar inary inary &E for 4& bit OS Stores any array of bytes Iimages, sounds, etc5. No validation re0uired. &E for 4& bit OS Stores any array of bytes. No validation re0uired. &E for 4& bit OS Stores any array of bytes. No validation re0uired.

Finally, there are two variable types offered by ase called O#-)7 and O K)"#. #hey are used to store small programs that really advanced developers of databases can use in their applications. )ssentially they store binary data =ust li+e inary but this time ase pays attention to the beginning of the code so it +nows what +ind of program it is and how to use it. 8e will not be using this type of variables in this tutorial. Table .! /ther $ariable types: For storing small #omputer programs in the (a%a language! &ame 'es"ri)tion Other Ob=ect Stores seriali;ed Kava ob=ects Q user application must supply seriali;ation routines Same

1h$ is all this information relevant/


ase, wor+ing with the embedded -S./ database engine, re0uires that all your database Idata, data structure and forms and reports5 be in 7A! memory while you wor+ with it. #his means that the number of records that you can +eep will be affected by the si;e of your variables and the amount of 7A! in your computer. #he number of your reports and the speed in which they are calculated will also be affected by this. 9n theory, -S./ limits your tables to & gigabytes Iwhich is a lot of memory5 and the overall si;e of your database to A gigabytes Iremember, this includes the forms and reports -but still itHs plenty5. 9f you had a table with an image that is roughly & gigabytes, you would not be able to record more information in that table. 2ou would have one table with only one record in it. 9n practice, however, and at the time of this writing, computers tend to have F(& megabytes, ( gigabyte or & gigabytes of memory, reducing the resources available to your ase database. Although this is still plenty for a functional application, you can ma*imi;e your resources by spending some time assigning variable types and memory allocations commensurate to the variables you need to record. #his will also help your application run faster. Now you +now!

4'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

'n logical ames and *h$sical

ames

#hroughout this tutorial 9 try to use the words >"lass?, >#able?, >Attributes? and >"olumns? as if they belong to different logical levels. 8e defined a class as a collection of ob=ects that share the same attributes. A class translates to a table and the attributes conform columns, which is why we are tempted to use them interchangeablyJ but in fact they denote different things. A class is a logical relationship, formed when the abstractive powers of our mind are able to establish patterns of commonalities among the entities we are wor+ing with. A table is the physical e*pression of such a class, as embodied in the way the database software and hardware actually store, inde* and organi;e data. 8hen thin+ing about the name for our variables it can be useful to differentiate between a logical name for the variable and the physical name used in the application. For e*ample, >First Name? is the name of the variable that stores the first name of our ob=ects, li+e >Kohn? or >"hloe?. >First Name? describes a data entity we are wor+ing with. 9t does not matter if >First Name? is alternatively written >F97S# NA!)? or >firstName? or >firstRname? or even >FRN? as long as we conceptually understand that it references the first name. 8hen we thin+ about conceptual or logical relationships, a clear and descriptive name is all we need. #his is the +ind of name we would use in our <!/ diagrams, which is an e*ample of conceptual or logical data model. <nfortunately this does not translate so simply into the names that a database software will allow us to use. For e*ample, ase wor+ing with -S./ will allow us to use >First Name? but other database applications would re=ect it and as+ us to use >firstRname? instead. #his has to do with the way a particular database software has been designed and the conventions accepted then. #he name actually used in the internal structure of our tables is called a >physical? name, as opposed to the logical name discussed above. #his physical name will have to conform to the conventions imposed by the software that we are using. #o be clear, ase using the -S./ engine can accept spaces and other special characters as valid characters for names and can also act as caps sensitive as long as you enclose the names within double 0uotes. ecause of this we will be using physical names in this tutorial that are identical, for the most part, to their logical names, which will simplify our wor+ when we start creating forms with ase. 8e will see this in action in part 999 of the tutorial. 9f this is so, why do 9 care about how other database programs handle variable namesG 2ou will discover how much thin+ing goes into designing the tables and their connections. "ompared to such effort, actually building them can seem almost trivial. Once you have the logical structure, you can easily transport it to any database application. 8hat if the code itself, with which you create the database in ase using the -S./ database engine, could be transported to other database software as easilyG #his is not always possible because of different physical name conventions. Furthermore, ase can act as a front end for several different database engines I+nown as 7elational 6atabase !anagement Software, or 76 !S5. /ater on you might want to start using databases that offer you more features, speed or stability and, therefore, mi4(

AS)

#<#O79A/

grate from the -S./ embedded engine to some other database software. 9f you are planning to use ase in this way then you might want to ma+e sure that the software that you will migrate to accepts the variable names you have chosen and properly understands the variable types that you are using. #o facilitate porting your design to other database software, you can conform to the following practices when naming variables$ (. &. 4. B. F. Start all variable names with a letter. For subse0uent characters use either letters, numbers or the underscore character. 6onHt use a space between words. 9nstead separate them with the underscore. 6onHt use special characters e*cept for the underscore. <se abbreviations, if needed, to help +eep the length of variables names short.

8hat short means e*actly will be determined by e*perience and the conte*t of the problem. 2ou will see how our e*ample uses some abbreviations. 9n any event, 9n this tutorial 9 will focus on the -S./ embedded database engine, which allows me to use spaces, special characters and capitali;ation. As you will see soon, this will facilitate the creation of the forms 9 need for data entry. /etHs get going!

4&

,art 99
#hings you need to do before you code a database with ase.

Contents: Chapter 2: Data ,odeling: A case e3ample Chapter 4: Designing our forms Chapter 5: Designing our reports

Chapter
6et)s get real7

9n this section we will translate the ideas analy;ed in part 9 into a concrete pro=ect that should help illustrate how to apply such concepts. #his e*ample will be of a general nature -in order to facilitate the application of the operations described here into pro=ects of your own- and of a medium level of comple*ity. #his should ma+e our wor+ both challenging and useful.

Case +3ample: ow we need a problem...


/etHs apply the phases of database design to a concrete and possible problem. 8e will consider the needs of a small psychotherapy center. #he director will be the client and you and 9 will be the e*perts. Our first step as e*perts will be to try and identify the presenting problem. ecause this is a styli;ed version of the wor+, the most important 0uestions -and answers- will appear 0uite 0uic+ly. 9n real life this can easily ta+e several meetings or a good chun+ of time devoted to thin+ing about the operations or business processes we will be aiding. 9n our e*ample we start by as+ing the "lient and learning what is the business about and who the principal players are. #he clinic receives people loo+ing for psychotherapy services. #hey are usually referred by their medical doctor but not always. Once evaluated and admitted, they are assigned to a therapist according to relevant training and time availability. #hen they show up for a number of sessions they, or their insurances, need to pay for. #he director will then pay the therapists according to the number of patients they saw in a month. Now that we have a broad understanding of the process, we want to +now what the needs of our "lient are$ #he "lient needs to record data from his patients and decide if they should be admitted to the clinic. -e needs to organi;e the admitted patients, matching them to a therapist and finding an available time slot. -e needs to +eep trac+ of the performed sessions, by therapists, so he can pay them, and by patient so he can charge them. -e also needs to +eep info about the therapists, their training and other data for ta* purposes. So we need to record info about the patients, the therapists, about their meetings and about the payments. After our first Iand very styli;ed and lean5 approach we can start to identify some classes we are going to need$ #he ,atient class, the #herapists class, the Schedule class and the ,ayment class.

AS)

#<#O79A/

*atient

*a$ment

Therapist

.chedule

8e can imagine that a patient and a therapist will be assigned to a schedule and that a payment will be associated with a performed session, as recorded in the schedule. So in very general terms we can imagine a structure of connections more or less li+e the following$ *atient .chedule *a$ment

Therapist

Now here comes the first problem with assumptions$ #hey can be wrong! So it is always better to as+ about what we are thin+ing instead of ta+ing it for granted$ 8hen we show this diagram to the "lient, he tells us that, although our first assumption -that patients and therapists will be assigned to a schedule- is correct, our second assumption -that payments are associated to a performed session- is not. First, patients will have to pay for a session they didnHt show up for if they do not cancel it at least &B hours prior, so payment is not necessarily associated with performed sessions. Second, patients might re0uest a payment plan, allowing them to ma+e -say- wee+ly payments of a fraction of the cost of the session. #his way, they will ma+e small payments until the debt is complete even if they are no longer receiving therapy. All right, good we as+ed! Now we +now that the schedule will have to record if the session too+ place or not and if it was properly canceled in order to +eep a tally of money owedJ and that the payments will only be associated with the client and not to the Schedule. 8e can modify our model to reflect this in the following way$

4C

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

*atient

*a$ment

.chedule

Therapist

9t might seem li+e a small modification but, at this very early stage in the process, this change has ta+en our design in a different direction. 8e go bac+ to the "lient for more information$ 8e heard that some patients are referred by their medical doctors. 6o we need to collect this informationG #he "lient says yesJ furthermore, every patient needs to have one medical doctor on record. Are there other professionals we need to register for every patientG #he "lient informs us that some patients might also need services by a psychiatrist and that this data, along with the medication they are assigned, needs to be collected. 6o all patients need a psychiatristG #he "lient informs us that no, only some patients could need it. 8e +now by now that the "lient needs to collect info about the potential patient but that he also needs to perform an evaluation of several factors and later ma+e a decision to admit him3her or not. Now we can see that there is contact info, evaluation info and resolution info. #he dialog between "lient and )*pert continues$ At what moment is the patient registered into the databaseG 8hen he calls see+ing services or when it is resolved that he be admittedG 8ill all the information re0uested be available at the time that the record is enteredG 9f not, what information is essential to decide to register a recordG Iremember the NO# N<// attribute of columnsG5. y as+ing the former, we the e*perts learn that the patients will be registered into the database only after they have been admitted, which means that the evaluation has already been performed and a diagnosis been madeJ this way there is no need to collect all the information generated by the evaluation or the resolution. eing registered in the database is a very important milestone as it mar+s the moment when the patient is incorporated to the clinic and becomes a responsibility of it. For this reason, it is also important to record the date at which the patient is registered into the database. -owever, at this point in time, there could still be some information that has not been properly collected from the patients. For e*ample, some could be ta+ing medication and, although +now the name of it, not be sure of the dosage. Others could have forgotten the phone number of their medical doctor and promise to phone later with it. #his shows us that some information is essential while other is not... #he "lient gives us a list of the information he wants to collect
4@

AS)

#<#O79A/

about the patients but also informs us that the name, address and the diagnosis -proof of the evaluation- would be enough to ma+e an entry. #his essential information will later become NO# N<// records. /etHs continue the dialog between the "lient and the )*pert$ 8hat data do we need from the therapistsG Of course, name and contact information, their degrees and specialties and ta* information so they can be properly paid. And what data is relevant to collect in the payments classG #he "lient wants to +now who made the payment and how much he paid. At this point we can use our imagination and identify data that the "lient has not thought of but that sounds important to us$ For e*ample, would the "lient li+e to record the date when the payment was doneG 2es, he answers. 8ould he li+e to record the date a therapists is hired or stops wor+ing at the clinicG At first the "lient seems unsure about this info, that it would not be commonly used, but later reali;es that it would be proper administration and decides to include that data. 8hat about the schedule classG #he "lient states that he will want to record the time slots the patients are assigned and the therapists they are assigned to, the date when the patient is assigned and the date the case is closed. As we discovered earlier, he also wants to record whether the patients came or not to a scheduled session and, if not, if they properly canceled the session. 8e, the e*perts, as+ him what happens if it is the therapist who has to cancel a session. 9n that case, he answers, the patient should not be billed for that session and therefore, who cancels the session Ithe therapist or the patient5 should also be recorded. After reviewing the paper forms the clinic has been using up to now, we discover other elements of interest$ Some patients have a home phone number and live happily with that. Other patients have a home number, a cell or mobile number, a =ob number and maybe even a second =ob phone number. 8e as+ why and discover that being able to get in touch with the patients is very important for the clinic, particularly if an emergency arises. #his also leads us to the possibility that the "lient could need e*tra contact information to reach the medical doctor and the psychiatrist in case of an emergency. 8e as+ the "lient about this but he says that the staff of those professionals will +now how to reach them if needed, so we only need to record their office numbers. 8hat reports does the "lient need to ma+eG At first, the "lient can thin+ of three principal ones$ "linical reports, financial reports and schedule reports. #he clinical reports should contain contact information about the patients, diagnosis, assigned therapist and medical doctor, and psychiatrist and medication info if any. Financial reports need to provide information in three different ways$ #he overall number of billable sessions performed in a set period of time, patient information that includes the total number of sessions performed and the total amount of money payed by him and, lastly, the assigned sessions to be payed to every therapist. #he schedule report should indicate what therapist has been assigned to what patient and in what time slot. After thin+ing about this for a while, the "lient also tells us that he would li+e to have a summary of all the sessions to be performed ne*t day with the name and contact data of the patients so they can be

4A

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

called and confirmed. -um! "hallenging. /etHs see if we can accommodate these re0uests! Now, =ust in case this has been going too fast, letHs ma+e a summary of what has happened so far. A client, the director of a mental health clinic, has approached us, the e*perts, to develop a database to organi;e his clients, therapists and to +eep trac+ of payments. 8e, the e*perts, have in0uired about the way this clinic handles business, previsuali;ed the reports re0uired by the client and analy;ed the paper forms he currently uses. 8e also stressed our own imaginations and offered some ideas, all of which helps in fleshing out the classes and attributes we could need. 8ith this wor+ we have identified four main classes$ ,atients, therapists, schedules and payments. So far, so good.

*ossible solution.
Now that we have relevant information, we should sit down and write a formal statement about what the goals or purpose of our database will be. y this 9 mean the functionality that, we as e*perts, believe that is possible to provide for the situation and needs revealed in the previous research. So after thin+ing about it for a while we write down that we will develop a database that stores contact and clinical information about patients, that stores and maintains information about services provided, including dates of sessions and assigned therapist, that stores and maintains information about payments received by them and that stores information about therapists and their 0ualifications. #he database will be able to provide the following reports$ "linical summary of patients, summary of services rendered to individual patients, payments made by individual patients, sessions performed by individual therapists, summary of all services rendered by the clinic for a set period of time and a log of ne*t-day sessions with patient contact info. 2ou can see that this statement is 0uite short and representative of the needs of the client and the information that needs to be collected. 9t provides concise goals and boils down the needs of the client into concrete procedures and final reports. 9t also sets a standard of completion$ 8hen our ase application can do what is stated in the previous paragraph then this pro=ect has been completed Iand a new one can be started5. ,rofessional developers usually present this to their "lients and ma+e them sign a copy. 8hen clients later complain that the application does not, for e*ample, provide a summary of the most common mental health illnesses, they answer$ >8ell, that was not in the initial specification. 9f you want that we can develop it for you and it will cost you SSS e*tra?. ,ure genius! #he other important thing is that this statement will help us ma+e decisions about data modeling. As you might +now by now, there is more than one way to organi;e the same data. 9f one of those options ma+es producing one of the re0uired reports difficult or complicates the collection of information then that is an option we will surely drop in favor of
4D

AS)

#<#O79A/

an option that ma+es the tas+s easier. #his should become self evident the more you practice your data modeling s+ills. 8ith the elements collected so far we can start drafting the forms we might need. For patients we will want to record$ name, date of birth, address, one or more phone numbers, diagnosis, medical doctor, psychiatrist and medication -if present- and the date of registry. For therapists, we will want to record name, address, phone numbers, ta* id number, degree, speciali;ation and date hired. For the ,ayment class we will record the patient, the amount and the date of the payment. For the schedule class we will collect the patient, the therapists, the assignment date, the time slot and whether the session too+ place or not. 8e are now ready to start modeling data. -owever, and to be truly honest, we have not cleared all possible 0uestions relating our data. As we try to conform the classes, their attributes and connections, new 0uestions will pop up that will force us to go bac+ to the "lient, rethin+ our designs, include new data or even e*clude some of the data we now find necessary. /etHs not fear this and consider it part of the =ob. -owever, our goal statement provides a direction and, whatever changes we do, they must all aid in achieving the stated goals.

Data ,odeling.
9ntuitively, the ,atient class and the Schedule class seem the most comple*. /etHs star by analy;ing and fleshing them out. 9n our initial draft, the ,atient class was connected to the Assignment and the ,ayment classes. #his means that we will need a primary +ey. 8e will let ase produce a numeric +ey for each record. 8ith the information collected so far, we can propose the following attributes for this class$ *atient
I Number !"rimary key# Name ate of Birth $ddress "hone number%, number&, number3, etc. iagnosis 'edical octor Name, address, phone number "sychiatrist Name, address, phone number 'edication (ime of registry

Any problems with thisG Several.

B'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

!aybe you have already spotted the multivalued information for phone numbers. #his is because this table is not in first normal form. Normali;ation here re0uires us to ta+e the phone numbers and produce a new table with the multivalued item and the primary +ey as a foreign +ey. 9f we didnHt do this, we would have an arbitrary number of columns I,hone(, ,hone&, ,hone4, for e*ample5 that sometimes are populated and oftentimes not. 8e would also be unable to record a fourth phone number if the patient has one. All this is solved by e*tracting the phone numbers and ma+ing them their own class. 6o we have problems with second normal formG No, because this class does not have a compound primary +ey, so there is no way a subset of it could also be a primary +ey. ut there is something fishy about the data for the medical doctor. Notice this. 9 do need the primary +ey to +now what medical doctor a particular client has. ut 9 donHt need the +ey to +now the medical doctorHs address or phone number, all 9 need is the medical doctorHs name and 9 can tell you the other data. #his could be better visuali;ed if you imagine this class as a table with several records that have the same doctor. Only the information particular to each patient is uni0ue, but the medical doctorHs information would be repeated again and again and you could identify it by =ust +nowing the medical doctorHs name. Aha, we are in violation of third normal form here! 8e need to e*tract the data H!edical 6octorH and ma+e a new table with it. #he same thin+ing applies to the information about the psychiatrist. 9 only need the psychiatristHs name and 9 can tell you the psychiatristHs address or phone number. #his info also re0uires a table of its own. Not all patients have psychiatrists, which means using optionality ;ero, and a patient will have at most one psychiatrist. 8e can already anticipate that we are going to need a cardinality of$ '..(. #he other way to loo+ at this situation is to recall the first principle in class formation that states that a class must be about one topic and one topic only. Our first draft for the ,atient class does not follow this rule and includes other topics li+e medical doctors and psychiatrists. Something similar happens with medication. Not all patients need medication. #his is, again, a set-subset situation and medication needs to be made its own class. 8ould normali;ation spot that medication needs to be in its own classG 2es, but by a different route$ people could need one but also two, three or more different medications, reviving the problem of multiple values for one item of information alluded by first normal form. #herefore, medication would have been made a table of its own. oth ways of thin+ing reach the same conclusion and are, in conse0uence, e0uivalent. After applying normali;ation to the ,atient class we have developed four new classes that relate to it. <sing <!/ we can describe their relationships as follows$

B(

AS)

#<#O79A/

,edical Doctor *atient

*hone

umbers

*s$chiatrist ,edication

/etHs now thin+ about the cardinalities$ y as+ing our "lient, and using our imagination, we can reali;e that one medical doctor could be responsible for several ,atients I(..n5 but that each patient will have e*actly one head medical doctor I(..(5. Similarly, one psychiatrist could be seeing several patients from this clinic I(..n5 but ,atients will have either e*actly one psychiatrist or none I'..(5. ,hone numbers are not a big mystery$ one patient can have one or more phone numbers I(..n5 while phone numbers can be thought as belonging to e*actly one patient I(..(, although family members could have the same number5. 8hat is the situation with the medicationG 8e already +now that one patient would be using either none, e*actly one or even several medications I'..n5 while several medications could be being used by several patients at the same time In..m5. Aha! n..m relationships force us to use an intermediate table between "lient and !edication! 8e will call this table "lient3!edication. /etHs add all these elements to the diagram$
(..(

*hone

umber

,edical Doctor

(..n (..(

*atient

(..n

*s$chiatrist

'..( (..n

'..n

(..n

,edication

*atient 8 ,edication

(..n

(..n

8hat seemed li+e a simple ,atient class was decomposed to form five new classes. -owever, ma+ing this decomposition was not difficult at all as it only too+ applying the rules of Normali;ation and understanding well the needs of our client and the conditions under
B&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

which business operations ta+e place. 9ntuition also suggests that this new design is far more fle*ible and reliable than the first one-table draft for a ,atient class "onse0uently, the new ,atient "lass will be structured in the following way$ *atient
I Number !"rimary key# Name ate of Birth $ddress iagnosis (ime of registry

Any problem with thisG Again, yes. #o start with, the table records the name of the patient as only one attribute. 9f we later wanted to send mail to the patients we could only use the obviously computer-generated >6ear Kohn Smith$? -for e*ample- unless we embar+ in complicated string manipulation. 9f we record the name in smaller categories, li+e first name and surname, we could have the option to produce different tones in our letters, li+e a formal$ >6ear !r. Smith$? or a more friendly >6ear Kohn$?. Eenerali;ing this, it will give us more fle*ibility if we tend to record the smallest unity of usable information. 8hat is the definition of usableG #hat will depend on the goals of your database. For e*ample, there is no use for me to distinguish between the area code and the phone number and 9 would record them both as one attribute. 2et, for someone who is analy;ing patterns in phone numbers maybe storing each individual number of the se0uence in its own column would ma+e plenty of sense. 9n the same line, it is useful to me if 9 atomi;e the address information. 8here 9 live, addresses include a street name and a number, a city, a state and a postal ;one number. y storing each in its own attribute we could later, during maintenance, develop reports that produce statistics that show what cities or postal ;one codes patients tend to come from, for e*ample. Sure, this is not part of our initial goal statement but that was because we were very ine*perienced then and didnHt +now about the power and fle*ibility of atomi;ing information categories. 9f the client later as+s us for such statistics, we will be ready to deliver and not discover with dread that our data structure does not support this. Another helpful thing is to include gender information. 9 really disli+e mail that reads$ >6ear Sir3!adam Kohn Smith?. #his happens because the database was not able to capture the gender of the person. 9 might not be the only one complaining because 9 have seen attempts to solve this. Some forms will as+ for a prefi*$ !r., !rs., !iss, etc. 2ou might +now that OO.o 8riter allows you to create letter templates with conditional te*t
B4

AS)

#<#O79A/

that will be printed only if certain conditions are met. For this reason 9 would recommend to include a variable to record the gender of the patient, for e*ample$a oolean variable where 'Pmale and (Pfemale Ithis assignment is arbitrary, of course5 or a "-A7 to hold HmaleH or HfemaleH and then use this as a condition to tailor the te*t. Additionally, we can later compile statistics that include gender as a factor. Summari;ing, what we have done is atomi;e information Ie. g. name first name T surname5 and added descriptors Ie.g. Eender info5. #hese same considerations will be applied to the other classes$ !edical 6octor, ,sychiatrists, #herapists, etc. )ven a class li+e !edication can benefit from a descriptor, recording, for e*ample, what the medications do or what illnesses they treat. 8ith these elements, we have modified the structure of the ,atient class to the following form$ *atient
I Number !"rimary key# )irst Name *urname +ender ate of Birth *treet and number City "ostal code *tate iagnosis (ime of registry

Anything missingG 8ell, it is time to assign foreign +eys. #he phone number table is 0uite straightforward, as we only have to follow the instructions for first normal form. #his means that it will be this table that will receive the patientHs primary +ey as a foreign +ey. #he intermediary table >,atient3!edication?, by definition, will receive the primary +eys from the ,atient table and also from the !edication table. 8hat about the medical doctorHs tableG 9f we made this table receive the patientHs primary +ey, this would mean that we would be repeating the medical doctorHs info for every patient that had him as a head doctor Ivisuali;e this by imagining a populated table that repeats all data for a doctor e*cept for the foreign +ey that connects it to a particular patient5, and this would not ma+e any sense. 9n fact, it would be creating the +ind of redundancy that we want to avoid because it consumes unnecessary memory and opens the door for inconsistencies. 9nstead, we will want the patientHs table to receive, as a foreign +ey, the primary +ey of the medical doctorHs table. #his same logic can be applied to the psychiatristHs table.
BB

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#his way we +now that the medical doctorHs table and the psychiatristHs table will both re0uire primary +eys and that the patient table will need to store them as foreign +eys. After this analysis, we can finally complete the ,atient class, which ta+es the following form$ *atient
I Number !"rimary key# )irst Name *urname +ender ate of Birth *treet and number City "ostal code *tate iagnosis 'edical octor !foreign key# "sychiatrist !foreign key# (ime of registry

Applying the same principles alluded so far, the related tables will have to following structure$ ,edical Doctor
I Number !"rimary key# )irst Name *urname +ender *treet and number City "ostal code *tate "hone number

*s$chiatrist
I Number !"rimary key# )irst Name *urname +ender *treet and number City "ostal code *tate "hone number

OL, we can see the primary +ey that ase will generate for us, we can see that atomi;ation of name and address information. 8e can also see the gender descriptors. ut wait a minute!! -ow come these tables have a phone number attributeG -ow come ,hone Number is a table in relation to the ,atient class but is an attribute in these two tablesG #his is dictated by the needs of the "lient. -e needs to record as many numbers from the patients as possible, in order to handle emergenciesJ but only needs one number from the professionals as their staff will +now how to reach them if they are not immediately available. #he defining factor is that in one case we need an undetermined number of phone numbers and in the second case we +now that we need e*actly one.

BF

AS)

#<#O79A/

*hone

umber

"atient I !)oreign key# Number escription

OL, we can see the foreign +ey connecting the phone number with the proper patient. 8e can also see a descriptor with the very creative name of >description?. 8e will use this to record if the number is the home number or the mobile or the office or the second =ob, etc. 9f it were an important piece of information, you could also add the descriptor that records the best time to call, but this didnHt come up in our research. 9t would be up to you to recommend this or not. Now wait! ShouldnHt there be a primary +ey attribute hereG Strictly spea+ing, we donHt need it, as all the information is relevant only in relationship to the ,atient table. Our 0ueries relating phone number will all have the form$ >locate phone number where patient id is such?. -owever, please note that when you are coding your tables in ase using the E<9 Ithat is, the graphical interface as opposed to using S./ command lines5 ase will automatically generate a numeric primary +ey in every table, =ust to +eep things neat. Additionally, in our e*ample all our tables will have a primary +ey, even if theoretically this is not re0uired, to aid some automatic processes handled by ase. Another thing$ isnHt this a rather small tableG ShouldnHt tables be biggerG 9snHt it a waste to create a table to =ust record two or three attributesG 8ell, we have seen that the power of relational databases comes from their ability to connect data, not from the si;e of its tables. 9t is not uncommon that databases are made of many, many rather small tables, but all really very interconnected. On the other hand, 9 am not sure if this table is small. 9t records only three attributes but, if every patient has e*actly two numbers Ihome and office, for e*ampleJ and about everybody also uses a mobile phone these days5, this table will always hold -at least- twice as many records as the patientHs table. 8hoHs small, againG 8ith this in mind, the medication table should not surprise you$

,edication
'ed I !"rimary key# Name escription

Nor the intermediate ,atient3!edication table$ *atient8,edication


"atient I !)oreign key# 'ed I !)oreign key#

BC

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#his last table records only two attributes and doesnHt even need a primary +ey, yet is allows us to find all the medications one particular patient is using or all the patients using a particular medication. 9snHt this niceGF "ould this table use a descriptorG !aybe we could have recorded the date this medication was assigned and the current dosage. And if we capture the date the patient started using this medication, we could also record the date he stopped using it, and +eep this as an historical record for the patient Iand we will be doing this in our final version5. -owever, the need for this information did not arise in the goal statement and seems more relevant in a database for the psychiatrists, who is the one who is really monitoring the medication. 8e could as+ the "lient if he really needs this information or not. -owever, it wor+s here to show that a table with only two attributes is not only possible but also very important and useful. At this point in the game, you should be able to organi;e all these tables in a nice <!/ diagram describing the structure of the classes, connecting primary to foreign +eys and indicating cardinalities. 2ou should also be able to model the #herapistHs table with what you have learned so far! /etHs focus now on the Schedule class. According to our research and the goal statement we did, this class should have the following attributes$ .chedule
"atient I !)oreign key# (herapist I !)oreign key# ate assigned to therapist *lot date *lot hour *tatus of the session ate case closed

-ow are we feeling about thisG 8e can see that in order to identify a slot hour, for e*ample, we need to +now both the patient id and the therapistsH id. So this table uses a compound +ey to identify each cell. 8hat is the rule of normali;ation for compound +eysG Oh, right! Second normal form. #hat rule states that no subset of the primary +ey can also be a primary +ey. 9s there anything li+e this hereG For the most part, 9 really need both elements for the +ey. After all, a patient needs to be assigned to a therapist from which he can have his case closed later on. 2et there is this strange feeling that the date of assignment and the space for storing the date the case is closed will be repeated unnecessarily every time a patient schedules a session. On closer inspection note that the attributes 6ate Assigned and 6ate "losed depend on ,atient 96
F /et me stress that when we actually build them, all our tables will have a primary +ey in order to aid ase with some automatic functions.

B@

AS)

#<#O79A/

only and not on the compound patient-therapist ids. #his table is not in second normal form! Following the rule then, we will decompose this table into one table that only has the ,atient 96, the date he is assigned and the date the case is closed Iwhich seems proper to call the HAssignmentH table5 and have another table that records the patient id, the therapists id and the slot date and time, li+e this$ .chedule Assignment
"atient I !)oreign key# ate assigned to therapist ate case closed "atient I !)oreign key# (herapist I !)oreign key# *lot date *lot hour *tatus of the session

#his is much better. 8e can see that in the schedule table, slot date, hour and status of the session Iwhether the patient came or not or if it was canceled by the therapists or the patient5 depend e*clusively on the compound +ey made by patient id and therapists id. #he assignment table, in turn, records the date a patient is assigned to a therapist and the date his case is closed, data that is functionally dependent only on the patient id +ey. -owever, there seems to be a piece of missing data. 9 donHt +now you but 9 feel uncomfortable by the fact that the assignment table does not record what therapist was assigned. Of course, 9 could simply add the therapistHs id to the table. #his would be correct and not affect the structure of the tables. ut if 9 do so, the assignment and schedule tables will both have the same two attributes of patient id and therapist id. #his opens the door for possible inconsistencies that, of course, we want to avoid. -ow do we solve thisG 7emember that 9 said that there is no one way to design a databaseG #his problem will serve as an e*ample of that. #here is no one rule that helps us here and, instead, we are going to have to use our imagination to solve this one. 6ifferent imaginations will come up with different solutions, and in all honesty, some time devoted to thin+ing about this could provide several options. #he solution that 9 use includes thin+ing of each assignment as its own entity. So 9 will record in the assignment table the patient id and the therapist id along with the dates of assignment and closing. 9 also provide each assignment with its own number primary +ey. #hen in the schedule table, 9 use the assignment primary +ey as a foreign +ey instead of the patientHs and therapistHs id, and leave the slots time and date and the status of the session, li+e this$

BA

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Assignment
(..n (..(

.chedule
$ssignment I !)oreign key# *lot date *lot hour *tatus of the session

$ssignment I !"rimary key# "atient I !)oreign key# (herapist I !)oreign key# ate assigned ate case closed

So far we have given e*amples of data modeling by using normali;ation, by using our +nowledge of the needs of the client and the way he handles business Icoded in our goal statement5 and now, by stretching our imaginations and creativity. )*pect to do all these in your own pro=ects! /etHs finish this e*ercise in data modeling by conforming the #herapist table and the ,ayment table. For the therapistHs table we will start with the necessary data identified by our research and later apply the principles of normali;ation, atomi;ation of categories and applying gender descriptors. 9 will only render an initial and a final version. y now you should be able to describe the reasoning in the changes$

Therapist
I Number !"rimary key# Name $ddress "hone number%, number&, number3 (a, number $cademic degree -icense number .iring date (ermination date

#ransforms into$

BD

AS)

#<#O79A/

Therapist
I Number !"rimary key# )irst Name *urname +ender *treet and number City "ostal code *tate (a, number $cademic degree -icense number .iring date (ermination date
(..n

Therapist)s
(..(

umber

(herapist I !)oreign key# Number escription

Finally, we have the data re0uired by the paymentsH table$ *a$ment


"atient I !)oreign key# ate and time of payment $mount paid Notes /esult

6ate and time appear as one attribute because 9 intend to use the timestamp data type, that records both the date and the hour the record is created. 9 also created a HNotesH attribute to record special data about the payment. For instance 9 can record if the payment was done with cash or chec+. 9 also use H7esultH to record if the chec+ was paid or not and enter a negative number in the amount attribute to reflect that there is still money owed. #his way, the design can handle Iunpleasant5 e*ceptions to payments. 9 should also ma+e a note to myself and ma+e sure that 9 assign a signed numeric variable to HAmount payedH Isee :ariables 6efinition /ists later in this chapter5. Finally, and true to data integrity, 9 should also uniform or restrict the +ind of results 9 can write, so that similar circumstances receive the same entry Ifor e*ample, write H"reditH for every successful payment or H6ebitH for any unsuccessful attempt at payment5. As we will see later, it will be easier for the application to simply count the number of H"reditH or H6ebitH outcomes recorded in H7esultH than to count outcomes that have several different ways to state if the payment was successful or not. At this point we have finished the modeling of our data. 8e have e*panded our initial draft that included only four bo*es and made the necessary class e*tractions, we have determined the structure of each class and their structure of connections. y now you should have a <!/ diagram li+e the one in the ne*t page.
F'

AS)

#<#O79A/

A little bit more: Duplicit$ of roles and super classes.


#he e*ample that we have developed in this tutorial belongs to the very sophisticated field of medical records and medical billing, one obvious area for database applications. #his e*ample pales when compared to the functionality provided by professional applications in this field. For e*ample, we have not recorded what insurance company is in charge of the patientHs payment, most of which have different procedures and time lines. A pro design would be able to handle all that. Also, what happens if the patient is a minor or for any other reason has a legal guardian assigned to himG All these +inds of e*ceptions -and more- can be handled by professional designs. 8hy hasnHt this e*ample gone furtherG First of all, medical billing is a comple* sub=ect in itself, that is taught at the college level and is based on many years of trial and error by many bright minds tampering with it. 9n contrast, this tutorial aims to give you tools to develop more general types of databases, not only medical billing. -owever, most of those e*tra functionalities can be implemented using the same principles described so far$ y understanding the data that your clients need to record and retrieve, by harnessing the power of interconnected tables, by not defaulting normal form, by thin+ing through your designs carefully, by challenging them and by testing and testing and testing them. -owever, there is a characteristic of the design we have arrived to in this tutorial that could become a problem in a different conte*t. !aybe you have even spotted this potential problem already. 9f you remember, one of the goals of proper database design is to minimi;e redundancy. Our design does this 0uite well as long as a therapist of the clinic is also not a patient of it. 9f you review the data structure for the therapistHs and the patientHs tables, you will notice that both start by as+ing name, gender, address and phone numbers. 9f a therapist were also a patient, we would have to repeat this data in the patient table, opening the chance for inconsistent data and, in any event, duplicating records. Now maybe this design ma+es sense in the conte*t of a small mental health clinic where, for ethical reasons, it is not a good idea that a therapist also becomes a patient of it. ut there are many other e*amples where we could e*pect this duplicity of roles and should be ready for it. For e*ample, in a film school we have students and professors. ut it could also happen that a director of photography professor enrolls in a producing course. 9t would also be possible that some third year students ma+e some e*tra money by assisting the audio recording professor in the sound lab. 9n these cases, we have professors that are also students and students that are also teachers. #eachers that also study need to be enrolled, pay for the courses and receive the same benefits other students do, data that is probably not stored in the professorHs tables. #he same way, students that teach need to be paid and ta*es deducted, and re0uire other data that will not appear in the regular studentHs tables.

F&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

9f we record such +ind of person twice, once as a teacher and once as a student, we are duplicating the common records and opening the chance for inconsistent data. 9n cases where a duplicity of roles arises, you might want to thin+ in terms of a super class, a class that stores all the attributes common to the different roles and later relates to them as sub-classes. For e*ample we can create the class H,ersonH, which will have the attributes common to students and professors Iname, address, etc5. 8e then connect this table to the student and professor tables which will record the attributes specific to each role. #his way, one person can be either a student, a teacher or both. /etHs see this in the conte*t of our own e*ample. 8e have the patient and therapists tables. 8hen we analy;e their data structure, we discover that both tables re0uire$ id number, name, address, gender and phone numbers. 8e can e*tract this data to form the H,ersonH table. #he patient table will be left with the following attributes$ a person id foreign +ey, birthday, diagnosis, a medical doctor foreign +ey, a psychiatrist foreign +ey and a time of enrollment. 9n turn, the therapist table would be left with$ person id foreign +ey, ta* number, degree, license number, date of hire and date of termination. #his structural change is summarily reflected in the following <!/ diagram$ *erson
"erson I !"0# Name *urname +ender *treet and Number City "ostal code *ate

*hone

umber

,edical Doctor *atient

(..(

(..(

Therapist
'..(

*s$chiatrist

"erson I !)0# '..( Birthday iagnosis 'edical octor !)0# "sychiatrist !)0# (ime of registry

"erson I !)0# (a, number egree -icense number ate of hire ate of termination

<nless you have a good reason to +eep the subclasses separate, li+e the ethical consideration in the clinic we are deriving our e*ample from, the notion of a super class connected
F4

AS)

#<#O79A/

to related subclasses is the solution you most often will want to apply when you find duplicity of roles.

Attributes8#ariable definition lists.


Our tables will store the data with variables of which we already +now that there are several types. #hese variables will need names, lengths or memory allocations, maybe an initial value.... #o ma+e a long story short, each variable has a set of characteristics we need to specify. 9n order to ma+e sure that we assign the most economic options and that we are consistent in assigning these characteristics, we will write them down in a :ariables 6efinition /ist. #his ta+es the form of a table where we include the variable in 0uestion, the name we will give it, the data type it belongs to, maybe an initial value if it needs one and any other remar+s you might want to remember about them. #his is a table that we -and not the computer- will be using, but that will ma+e coding our application with ase much easier. 8e will see later that itHs possible to give our variables initial values that will be automatically populated by ase when a new record is created. #his is useful when you want to store a value by default which will remain true until it is modified. 9t is also possible to create conditions that ase will loo+ for before accepting data. For e*ample, you can as+ that ase chec+ that the variable >Start6ate? is always older than >)nd6ate?. Or that the variable >Eender? only accept the values H!aleH and HFemaleH. /astly, it could be possible that we use arbitrary code conventions in the code Ili+e 'Pmale, (Pfemale for oolean variables5. #hese +inds of elements should be made e*plicit in this list. /etHs write down the variables definition list for the ,atient class$
Patient C$ass 5aria $e 'e!inition Lists &o# ( & 4 B F C @ A A (' (( (& (4 'es"ri)tion and &ame 96 Number First Name /ast Name Eender 6ate of irth Street and No. "ity ,ostal "ode State 6iagnosis !edical 6octor 96 ,sychiatrist 96 #ime of registry 5aria $e Ty)e 9nteger :ar "har :ar "har "har 6ate :ar "har :ar "har :ar "har :ar "har :ar "har 9nteger 9nteger #imestamp Initia$ va$ue ( )mpty )mpty )mpty )mpty )mpty )mpty ''''' N2 )mpty )mpty )mpty "urrent date Remarks <ni0ue, auto increment /ength P &F chars Not null /ength P &F chars Not null Accept only Female3 !ale Format$ mm3dd3 yyyy /ength P F' chars /ength P &F chars /ength P F /ength P & /ength P C' Not Null Foreign Ley Foreign Ley mm3dd3yyyy $ hh3mm3ss

FB

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

y now you should be able to understand all the information in this table. 8e have used an 9nteger data type for the patient id number, which is a signed B byte number with a range wide enough to store many patients. 8e are also writing the remar+ that this attribute should be uni0ue to each record and should increment automatically for every new record, something that ase will do by itself. -owever, you need to code this - ase will not guess what your intentions are- so it is good practice to write this down so we donHt forget about it. For Name and Surname we use :ar "har. :ar "har means that this attribute will store up to the &F characters we have specified, or less depending on how many are really typed. Also notice the attribute of Not Null, ma+ing this a re0uired field in order to ma+e an entry, as re0uested by our "lient. #he gender has been assigned a "har data type that will only accept H!aleH or HFemaleH as valid entries. 6ate of birth has been assigned a 6ate data type and we ma+e note of the format used to ma+e sure we donHt get confused later. #he postal code has been assigned a :ar "har data type. "ould have 9 assigned this variable a Small 9nteger data type -that uses only two bytes per record- instead of :ar "har that will use at least FG 2es, you could have. Kust bear in mind that if you do so, the general address information and postal code will belong to different data types so you donHt mi* them in ways that the application might not understand, Also, remember your choice so you donHt attempt string manipulation on a variable that is of the numeric type. 9 have also assigned an initial value for the State attribute that the "lient would most commonly find in the geographical area where the clinic conducts business, so they donHt have to type it every time they create a new record. Finally, 9 made sure to ma+e e*plicit that the values for medical doctor and psychiatrist are foreign +eys. #his reminds me that they have to be made of the same data type that they will be assigned in their own tables. 9n general, all auto-generated primary +eys will be an 9nteger type. Notice that the second column in the table is called >6escription and Name?. #hat is because -in this case- the conceptual and physical names coincide. 7emember that in other cases this would not be possible or desirable. For e*ample if you are planning to port the database structure to a software that does not allow spaces in names then for variable number (( the +ariable )escription could be something li+e$ >!edical doctor 96 number Iforeign +ey5? while the +ariable (ame would have to be something li+e >mdRid?. 2ou will see that the S./ commands that we will use with ase to actually create the tables translates almost directly from this "lass :ariable 6efinition /ist. As an e*ercise, you could now write the variable definition lists for the other tables! Now that we have the design of our database, letHs chec+ the forms and reports that we will want to use with it.

FF

AS)

#<#O79A/

FC

Chapter
The forms

"

/etHs now analy;e the forms for data entry the way we envision them for the database design in this e*ample. 9t is possible that the final forms will not loo+ e*actly li+e these ones Ialthough with some wor+ it can be done5 but they need to have the same functionality. After you have completed this tutorial you will be much better in guessing the finally layout of the forms for your own applications. /etHs start with the form for patient information Ifigure (5. Persona$ In!ormation: First Name$ /ast Name$ Eender$ 6ate of irth$ !ale Female $mm,dd,yyyy%

Conta"t In!ormation: Address$ "ity$ ,ostal "ode$ State$ N2 U Phone num er

C$ini"a$ In!ormation: Assigned diagnosis$ -ead !edical 6octor$ ,sychiatrist$ U U

%igure 6: Patient in!ormation entry data !orm#

AS)

#<#O79A/

9 have divided this form into 4 components to aid our analysis. #he first bo*, ,ersonal 9nformation, will receive the first name, surname and date of birth with te*t bo*es. Note that for entering the gender 9 do not need to write anything at all$ not >male? or >female? nor >!? or >F?, nothing. All 9 have to do is clic+ on the appropriate radio button. Of course this means that we are going to do some e*tra wor+ when we actually develop this form. ut that e*tra wor+ will simplify our data entry and will ma+e sure we only enter values within a set e*pected by our design. #he second bo*, "ontact 9nformation, has an interesting feature$ 9f you remember, our design calls for an undefined number of phone numbers for patients, for which we have a dedicated table. #he form we use will have to allow us access to both, the table where we store patient information and the table where we store phone numbers. 8e also are going to need to program this form so that it automatically associates the phone number to the primary 96 number for the patient being recorded. #his automatic registry will not be noticed by the user Isaving him time5, but is fundamental for the design to wor+. For now, 9 will suggest this connection between the two tables with a button that calls the phone number entry form for each number we want to enter. ut this solution is not completely satisfactory and we will learn of better ways ase has to handle this. #he third bo*, "linical 9nformation, also has some interesting features$ Notice that the assignment of a !6 or a psychiatrist is done from a drop-down list. /i+e 7adio buttons, 6rop-down lists allow us to ma+e sure that the data entered belongs to a predefined set of optionsJ but unli+e H!aleH or HFemaleH we will not +now before hand what these options will be. #he 6rop-down lists will be populated from the entries made to the !6 and ,sychiatrist tables. ecause the form will have to read from the database to identify all available !6s or psychiatrists, this is some +ind of dynamic form that is created based on previous entries. #he e*tra wor+ to accomplish this ensures that this information is entered without errors that could ma+e it difficult later to identify the data properly Idifferent or wrong spelling, for instance5. 8hat happens if the !6 of the patient has not been entered yetG 9t will not be available as an option from the drop down menu so ma+e sure that you enter the professionalHs data first. Also notice that the form will provide the name and surname of the !6 but, once we identify and chose one, what ase needs to record is actually the primary +ey of the !6 as a foreign +ey in the patientHs table. 8e will see how all this is done! Of course we, the developers of these forms, will have to program these functions, which will ta+e an e*tra effort, but they will pay with better performance.

FA

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

,atient Name$ <patient name> 3istory o! .edi"ation use: .edi"ation None recorded New !edication$ 'osage Start date

6ate of irth$ <dob>

End date

!edication name$ 6osage$ Start date$ )nd date$

%igure 7: .edi"ation Assignment !orm #he form for medication assignment also needs to be populated with data from previous entries -li+e medications entered in their own table- and be associated with a particular patient Ifigure &5. Note that the name of the medication will be pic+ed from a drop-down list that will be populated from records in the medication table. #his form assumes that the database design will record dosage and the date the medication stared and ended. #he Assignment Form Ifigure 45 is one of my favorites because it seems so simple, but many things are happening under the hood aside from being crucial for the wor+ing of the database. First, notice that the form =ust loo+s to pair a patient with a therapist. -owever, the form will provide options with drop-down lists populated from records in the database. #his will ensure that only recorded patients be assigned, and because this is a point and clic+ operation, we eliminate errors in spelling. 9f you remember, it is also very important that we record the date of this assignment. #his will be done automatically by the form Iwith lots of help form our programming5, so the user does not need to concern himself with remembering what date is today. 9f the final user does not have access to the code or to modifying this record, then this date registry could also have the authority to establish a time line. .uite cool!

,atient Name$ Assigned #herapists$

U U %igure 8: Assignment !orm

FD

AS)

#<#O79A/

For closing a case we could use the form in figure B. Note that all data about the file is populated by the form. For entering the closing date we will use a special gadget that allows us to enter dates with the ease of point and clic+ and thus minimi;e errors in format and even in content. Name$ <patient name> #herapist$ <therapist's name> 6ate Assigned$ <date assigned> "losing file date$ %igure 9: %i$e C$osing !orm #he Scheduling Form Ifigure F5 re0uires elements that we have already discussed. #he purpose of this form is to set the date for a future appointment. #he form will provide the name of the patient and the name of the therapist, which have been assigned previously. #he user will input date and time of ne*t session. 8e will be using very cool tools provided by ase to enter date and time information.

Name$ <patient name> #herapist$ <Therapist's name> 6ate of ne*t session$ -our for ne*t session$ %igure 1: S"hedu$ing !orm #he last relevant form is the Follow-<p 7egistry Ifigure C, ne*t page5. -ere is where the user records whether the patient came or not or if the session was canceled and by whom. #he form will indicate the name of the patient, the therapist assigned and the date and time when the session was supposed to ta+e place. elow, the form offers =ust B radio buttons of which the user must chose only one. #hat will be a simple clic+ but will allow comple* calculations that have to do with generating bills and payments. $mm, dd, yyyy% $-. / -.0 A1, 1%

C'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Name$ <patient name> #herapist$ <therapist's name> 6ay$ <date> P$ease mark one: Session ,erformed ,atient did not show up ,atient "anceled #herapists "anceled -our$ <hour>

%igure :: %o$$ow0U) Registry #o sum this up, the forms that we need to create will receive and understand input from radio buttons, drop-down lists and other automated gadgetsJ and most of these drop-down lists will be dynamically generated based on data previously recorded in the database. #his way we can not only minimi;e data entry errors but will also ma+e these forms easier to use for the user. ,lease note that other re0uired forms Ili+e the forms for the !6s or the psychiatrists, for e*ample5 are not described here because they re0uire features that have already been identified. /etHs now ta+e a loo+ at the reports we would want our database to be able to produce.

C(

AS)

#<#O79A/

C&

Chapter
The reports

9n the specification made earlier we identified at least five reports that the database needs to generate$ (. "linical summary, which displays the patient information and the clinical information for each patientJ &. -istory of services and payment summary, which displays the history of sessions Iwhether they happened or were canceled5 and the history of payments performed in a specified period of timeJ 4. Summary of all sessions performed by a particular therapist in a specified period of timeJ B. Summary of all sessions performed by the "linic and all payments received in a specified period of timeJ and F. Ne*t day Schedule confirmation table, which lists all patients that have scheduled a session for a specified day, with contact data so someone can call and confirm the appointment. /etHs review them in more detail$ (. "linical Summary$ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*atient Information: ate1 <today's date> Name1 ate of birth1 $ddress1 City "ostal Code <Name Surname> <dob> <address1> <city> <zip> !,,,# ,,,2,,,, !yyy# yyy2yyyy !444# 44424444 .ome number 3ork Number Cell Number *ate1 <state> +ender1 <gender>

"hone Numbers1

5555555555555555555555555555555555555555555555555555555555555555555555555

AS)

#<#O79A/

Clinical Information: ate of admission1 <date of admission> (herapist1 iagnosis1 .ead octor1 <Therapist> <diagnosis> <medical Doctor> <psychiatrist> $bilify &7 mgrs.8day (el.1 <phone number> (el.1 <phone number> )rom1 798%&8&7%& until1 (oday ;ntil1 798%&8&7%& ate of termination1 acti6e

"sychiatrist1 'edications1

"ro4ac 7.: mgrs8day )rom1 7:8&38&7%&

5555555555555555555555555555555555555555555555555555555555555555555555555 +nd of Clinical .ummar$

#his report lin+s a patient 96 with all contact information and the corresponding phone numbers, !6, psychiatrist, medication history and assigned diagnosis. #he most recent medications are listed first. Notice that if there is no date of termination, the report will write >Active?. 9n the same line, if a medication has no termination date, the form will write$ >#oday?. Also, notice that this report states todayHs date in the upper right hand corner, so we +now that the report is valid up to that day. Finally, notice that the report ends with a line under which we write $ >)nd of "linical Summary?. #he purpose of this is that, if this report had more than one page, you can easily find where it ends. ,icture yourself producing several of these reports and you can see why a clear end li+e this could be useful. &. ,atient history of services and payment summary$ RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
*atient 9istor$ of .ervices .ummar$ rendered between <date1> and <date2> ate1 <today's date> Name1 <Name Surname> ate of ser6ices1 ate1 7=8%&8&7%: 7=8%98&7%: 7=8&?8&7%: 798738&7%: 798%78&7%: 798%@8&7%: 798&A8&7%: 798378&7%: *tatus1 No *how "atient Canceled "erformed "erformed "erformed (herapist Canceled "erformed "erformed <alue1 >3: >7.7 >3: >3: >3: >7.7 >3: >3: 555555 (otal1 >&%7

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CB

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

*a$ment 9istor$ Name1 <Name Surname> as of <today's date> $mount1 >3: >3: >3: >3: >%7 >:: 55555 (otal "ayments1 >&7: 5555555555555555555555555555555555555555555555555555555555555555555555555 0alance .ummar$ "ayments /ecei6ed on1 7=8&?8&7%:2%31371&& 798738&7%:2%313A1:3 7987@8&7%:2%%1%&133 798%78&7%:2%313&1A% 798&A8&7%:2%313@1%& 798378&7%:2%31&913A total ser6ices amount1 >&%7 2 total payments1 >&7: B 2>: 5555555555555555555555555555555555555555555555555555555555555555555555555 +nd of *atient 9istor$ of .ervices .ummar$

#he report renders all sessions scheduled in the top half and all payments made in the bottom between a specified time window Ithat is, between <date1> and <date2>). #he amounts are added. #hen a balance is calculated. ,atient and date information are repeated to simplify lecture Imaybe this gets to be a long list5. 8e also display the date the 0uery is run and terminate the report with a clear notice. 4. #herapistHs summary$
5555555555555555555555555555555555555555555555555555555555555555555555555 Therapist)s .ervices .ummar$: ate1 <today's date> (herapist1 <Therapist> rendered between <date1> and <date2> ate 7@87%8&7%: 7@87%8&7%: 7@87%8&7%: 7@87%8&7%: "atient <surname> <other> <andother> <yetother> *tatus No *how "erformed "erformed Canceled <alue >&7 >&7 >&7 >7.7

and so on...
7@8378&7%: <lastone> "erformed >&7 55555 (otal *er6ices1 >%&7@

+nd of Therapist)s .ervices .ummar$

CF

AS)

#<#O79A/

#his report is built with all scheduled sessions for a particular #herapistHs 96 and a time range. #he list is chronologically ordered and, within the same date, alphabetically ordered by the surname of patients. #he report would never write >and so on...? this is =ust something 9 wrote so that you get the idea. #he ellipsis represents a continuation of the list of events. 6ate and end of report are also clearly identified. B. "linicHs summary of services rendered and payments received$
5555555555555555555555555555555555555555555555555555555555555555555555555 Clinic)s .ummar$ of .ervices rendered between <date1> and <date2> ate 798%:8&7%: 798%:8&7%: ... 798%:8&7%: 798%:8&7%: ... (herapist < therapists> < therapist> <!therapist> <!therapist> *tatus No *how "erformed "erformed Canceled <alue >3: >3: >3: >7.7

555555 (otal *er6ices1 >:@77 5555555555555555555555555555555555555555555555555555555555555555555555555 .ummar$ of *a$ments: rendered between <date1> and <date2> "ayment /ecei6ed Cn1 798%:8&7%:2%31371&& 798&&8&7%:2%313A1:3 etc. for <Apatient> 798%?8&7%:2%%1%&133 798&38&7%:2%313&1A% 798&A8&7%:2%313@1%& etc. for <Bpatient> 798378&7%:2%31&913A etc. for <Cpatient> By "atient <alue1 < patient> >3: < patient> >3: <!patient> >3: <!patient> >3: <!patient> >%7 <"patient> >:: 555555 (otal "ayments1 >:?@7 5555555555555555555555555555555555555555555555555555555555555555555555555 +nd of Clinic)s .ummar$ of .ervices

#his report has two components$ First it states all sessions performed by all therapists Iin alphabetical order5 in a selected time range. #he form includes the status of the session Iperformed, canceled, etc5 and the value charged to the client. #he H:alueH column has a total sum at the bottom. #he second component lists all payments made for the same time
CC

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

range, ordered by patientHs surname and chronology of paymentJ and includes the timeestamp and the actual values payed by them. A sum of all payments is also done at the end of the H:alueH column. F. Ne*t day Schedule confirmation table
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: !uture .essions Confirmation Table !or Date: <selected day> ame of patient: <name surname> Tel.: <phone number># $<phone number>% Therapist:<therapist> Time slot: <hour> : /e2scheduled for1 55555555555555555 ame of patient: <name surname> Therapist:<therapist> Time slot: <hour> : /e2scheduled for1 55555555555555555 ame of patient: <name surname> number>% Therapist:<therapist> Time slot: <hour> : /e2scheduled for1 55555555555555555 : Confirmed : Canceled : Confirmed : Canceled Tel.: <phone number># $<phone : Confirmed : Canceled Tel.: <phone number>

5555555555555555555555555555555555555555555555555555555555555555555555555 +nd of Confirmation Table

#he bo*es will have no other functionality than letting the user of a printed version of this report chec+ the result of the confirmation. #his report will list every patient scheduled for the specified day. #he final layout of the actual reports we will build with ase might not be identical to these drafts but will need to include all the information and the logical elements described here. 9n the same line, although this tutorial will not produce all of these reports, it will provide you with all the tools you need for ma+ing them. 9t would be a good e*ercise if you do!

C@

AS)

#<#O79A/

Turn on the computers


8e are finally ready to sit in front of the computer and create our application with ase. 8e have a database design, we +now the forms that we need and we +now the reports that we want. 8e have also built variable definition lists for all tables. All the thin+ing about our particular database has been done so now we can focus on the comple*ities of coding it with ase. Our first step will be to actually build the tables. 2ou can do this with the graphical user interface of design mode, with the help of the wi;ard or by coding them with S./ commands. #here are e*cellent tutorials that e*plain how to build your tables using the first two methods and 9 truly hope that you study them. -owever in this tutorial we are going to create our tables using S./ commands. #his might seem less glamorous than creating the tables by using the graphical interface IE<95, but you will 0uic+ly notice how it is as easy and avoids some limitations of the E<9. 8e will then build the forms for this database with all the comple* functionality our design calls for li+e radio buttons, drop-down lists, forms that need to access two tables and lin+ records, etc. Finally, we will produce the reports that, as you have seen, also focus on advanced functionalities. #his is because these reports not only retrieve particular records that depend on e*tra information only available when you re0uest the report Ili+e the name of a particular client or a time frame of performed or paid sessions5 but also offer summary information. 8ell, we have promised to cover a lot. /etHs get started!

CA

,art 999
#hings you need to do while coding a database with ase.

Contents$ Chapter ;: Creating tables in 0ase with .<6 Chapter =: *roducing our forms. Chapter >: *roducing ?ueries. Chapter 1@: Creating reports Chapter 11: ,aintenance of the database

Chapter
Creating tables in 0ase with .<6

At this point we have a <!/ diagram of our database, complete with tables and connectionsJ we have the corresponding table definitions lists, we have a design for our forms and a design for our reports. Now itH-s time to turn on the computer. Eo ahead! 9n fact, most of the te*t in this part will not ma+e much sense unless you are following the >clic+ on this, then clic+ on that? instructions that we provide. #a+e your time and study the screens and dialog bo*es with the aid of the descriptions made here.

-eneral 'verview:
#he first thing that you will notice when you open ase is that the 6atabase 8i;ard pops up. #he interface has two columns. #he small one to the right describes the steps the wi;ard will wal+ you through. #he bigger column offers the different options available to you. First the wi;ard as+s you if you want to create a new database, open a previous one or connect to an e*isting database. y selecting >new database?, ase will wor+ with the embedded -S./ database engine. 9n the second step ISave and proceed5, ase as+s us first if we want to register the database with OpenOffice.org. #his doesnHt mean that your information might be accessible to other fol+s using or developing the OpenOffice.org suite. 8hat it does mean is that other applications of OpenOffice.org, li+e 8riter or "alc, in your own computer, will be aware of the e*istence of this new database and, therefore, will be able to interact with it -for e*ample, to produce and print labels. 8ith all confidence, mar+ >yes?. 8e will not be using the tables wi;ard, so leave the default and hit >finish?. For the last step, chose a name for your database and save. Now the database interface opens. elow the menu bar and the tool bar you will find the screen divided in 4 columns. #he first one to the left is very narrow and has the heading$ >6atabase?. 2ou will see B icons with the following te*t, correspondingly$ #ables, .ueries, Forms and 7eports. #he first one gives you access to the tables in your database and the tas+s that you can perform on them. "lic+ the >#ables? icon and you will see the available tas+s appear in the second column. 9f you position your cursor on top of any of these tas+s, a description of what they do appears in the third column. ,retty nice, ehG One third down the page you can see a hori;ontal gray bar with the te*t >#able?. #here is where the name of each table you build will be stored, so that you can access any of them by clic+ing on it. ecause we have not built any tables so far this section is now empty. 9f you now clic+ on >.ueries? in the first column, you are ta+en to the 0ueries page, and so on for Forms and 7eports. )ach page offers you the available tas+s, a brief description of the tas+ under the mouse cursor, and the bottom section that stores your wor+.

AS)

#<#O79A/

2ou will see that there is always more way than one to do the same tas+ in ase. For e*ample, >"reate #able in 6esign :iew? and ><se 8i;ard to "reate #able? Iin the #ables page5 both allow you to create tables for your database. 9n this case, the difference is that the wi;ard will ma+e the tas+ easier while 6esign :iew gives you more fle*ibility. 2ou still have a third option for doing this$ S./ commands, which gives you the most fle*ibility and control.

Creating tables and relationships with .<6 commands.


8e will start by creating the tables. 9n this tutorial we are going to use S./ commands to build them. ase accepts S./ commands in two distinctive windows$ #he most common application of S./ is for creating 0ueries, done in the >.ueries? page, which is where you should be now. /etHs analy;e this for a moment. 2ou can see that the third tas+ is >"reate .uery in S./ :iew...? ne*t to an icon that reads >S./?. 8e will see later that 0ueries start with the S./ instruction >S)/)"#?. #his instruction does not modify Ior create or delete5 your data or data structure in any way, it =ust displays the available data in the fashion you specify with the >S)/)"#? command. For this reason, ase will report an error for any S./ 0uery that does not start with >S)/)"#? made in the .ueries page. /etHs now move to the >#ables? page. For creating tables we will need another window for S./ instructions. #o reach it clic+ >#ools? at the menu bar and then clic+ on the option >S./...?. #he >)*ecute S./ Statement? window opens. 2ou will find a cursor blin+ing at the >"ommand to )*ecute? bo*. #his is where we will type the instructions to create the tables. S./ commands in this window do modify your data and do not need to start with the instruction S)/)"#. 2ou will have to type the complete following set of instructions. ,ay attention to 0uote signs, capitali;ation and synta*. 2ou can also copy and paste these instructions from the lin+$
http://documentation.openoffice.org/servlets/ProjectDocumentList?folderID=778

8hen you enter the instructions, the >)*ecute? bo* highlights. 8hen you are done, clic+ on it. #his will run your commands and create the tables. After a few seconds, the window will inform you that the instructions have been e*ecuted. Other than that there will be no visible signs on your screen. 9f you now go to the >:iew? menu and clic+ on >7efresh #ables?, a complete list of the tables you have created will appear in the lower section of your screen. I2ou can also try e*iting and re-entering the >#ables? view5. #ry this now. efore analy;ing the S./ instructions that have =ust created your tables, 9 want to show you that the relationships between them have also been created. "lic+ on >#ools? and then on >7elationships...?. 2ou will see a long line of bo*es and some lines connecting them. )ach bo* is a table and their different attributes Icolumns5 are listed inside. Some bo*es have scroll bars. #his is because they have more attributes than the number that can appear in the default si;e for the bo*es. 2ou can read=ust their si;es Iwidth and height5. 2ou can also reposition the bo*es so that the tangle of lines connecting them becomes
@&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

easier to read. 2ou will also notice that these lines connect the primary +eys Iindicated with a small yellow +ey symbol5 with the foreign +eys and display the corresponding cardinalities Ialthough simplified5, =ust li+e a <!/ diagram. 9snHt this fineG 9n fact, by the time that you finish tidying the relationship view, it should appear =ust li+e the <!/ diagram in our e*ample. 9f you right-clic+ on these lines and select H)ditH, a dialog bo* pops up where you can set 6elete options as they were e*plained in page ('. /etHs analy;e the S./ instructions that ma+e all this possible. #a+e the time to read through this and see if you can derive any sense from it. 8e will analy;e them together afterward$
D&'( D&'( D&'( D&'( D&'( D&'( D&'( D&'( D&'( D&'( D&'( T T T T T T T T T T T !)* !)* !)* !)* !)* !)* !)* !)* !)* !)* !)* +(atient ,edication+ -. */-STS0 +,edication+ -. */-STS0 +(ayment+ -. */-STS0 +Schedule+ -. */-STS0 + ssignment+ -. */-STS0 +Therapists Number+ -. */-STS0 +(hone Number+ -. */-STS0 +(atient+ -. */-STS0 +(sychiatrist+ -. */-STS0 +,edical Doctor+ -. */-STS0 +Therapist+ -. */-STS0 S -D*NT-T31ST &T 5-T6 7) N'T

"&* T* T !)* +(sychiatrist+ 1 +-D Number+ -NT*2*& 2*N*& T*D !3 D*. 4)T N4)) (&-, &3 8*3# +.irst Name+ 9 &"6 &12:) N'T N4))# +Surname+ 9 &"6 &12:) N'T N4))# +2ender+ "6 &1;)# +Street and number+ 9 &"6 &1:7)# +"ity+ 9 &"6 &12:)# +(ostal code+ "6 &1:)# +State+ "6 &12)# +(hone Number+ 9 &"6 &117) )0 "&* T* T !)* +,edical Doctor+ 1 +-D Number+ -NT*2*& 2*N*& T*D !3 D*. 4)T N4)) (&-, &3 8*3# +.irst Name+ 9 &"6 &12:) N'T N4))# +Surname+ 9 &"6 &12:) N'T N4))# +2ender+ "6 &1;)# +Street and number+ 9 &"6 &1:7)# +"ity+ 9 &"6 &12:)# +(ostal code+ 9 &"6 &1:)# +State+ "6 &12)# +(hone Number+ 9 &"6 &117) )0 "&* T* T !)* +(atient+ 1 +-D Number+ -NT*2*& 2*N*& T*D !3 D*. 4)T N4)) (&-, &3 8*3# +.irst Name+ 9 &"6 &12:) N'T N4))# +Surname+ 9 &"6 &12:) N'T N4))# +2ender+ "6 &1;)# +Date of !irth+ D T*#

S -D*NT-T31ST &T 5-T6 7) N'T

S -D*NT-T31ST &T 5-T6 7) N'T

@4

AS)

#<#O79A/

+Street and number+ 9 &"6 &1:7)# +"ity+ 9 &"6 &12:)# +(ostal code+ 9 &"6 &1:)# +State+ "6 &12)# +Diagnosis+ 9 &"6 &1;7)# +,edical Doctor -D+ -NT*2*&# +(sychiatrist -D+ -NT*2*&# +Time of registry+ T-,*ST ,(# "'NST& -NT +"8<( T<2ND&+ "6*"81 +2ender+ in 1 ',ale'# '.emale' ) )# "'NST& -NT .8<( T<(S3 .'&*-2N 8*3 1+(sychiatrist -D+) &*.*&*N"*S +(sychiatrist+ 1+-D Number+)# "'NST& -NT .8<( T<D'" .'&*-2N 8*3 1+,edical Doctor -D+) &*.*&*N"*S +,edical Doctor+ 1+-D Number+) )0 "&* T* T !)* +(hone Number+ 1 +(hone -D+ -NT*2*& 2*N*& T*D !3 D*. 4)T S -D*NT-T31ST &T 5-T6 7) N'T N4)) (&-, &3 8*3# +(atient -D+ -NT*2*& N'T N4))# +Number+ 9 &"6 &117)# +Description+ 9 &"6 &117)# "'NST& -NT .8<( T<(6N .'&*-2N 8*3 1+(atient -D+) &*.*&*N"*S +(atient+ 1+-D Number+) )0 "&* T* T !)* +Therapist+ 1 +-D Number+ -NT*2*& 2*N*& T*D !3 D*. 4)T S -D*NT-T31ST &T 5-T6 7) N'T N4)) (&-, &3 8*3# +.irst Name+ 9 &"6 &12:) N'T N4))# +Surname+ 9 &"6 &12:) N'T N4))# +2ender+ "6 &1;)# +Street and number+ 9 &"6 &1:7)# +"ity+ 9 &"6 &12:)# +(ostal code+ 9 &"6 &1:)# +State+ "6 &12)# +Ta= number+ 9 &"6 &127)# + cademic degree+ 9 &"6 &12:)# +)icense number+ 9 &"6 &11:)# +6iring date+ D T* N'T N4))# +Termination date+ D T*# "'NST& -NT +"8<T6(<2ND&+ "6*"81 +2ender+ in 1 ',ale'# '.emale' ) )# "'NST& -NT +"8<T*&,<DT+ "6*"81 +Termination date+ > +6iring date+ ) )0 "&* T* T !)* +Therapists Number+ 1 +(hone -D+ -NT*2*& 2*N*& T*D !3 D*. 4)T S -D*NT-T31ST &T 5-T6 7) N'T N4)) (&-, &3 8*3# +Therapist -D+ -NT*2*&# +Number+ 9 &"6 &117)# +Description+ 9 &"6 &117)# "'NST& -NT .8<T6(<(6N .'&*-2N 8*3 1+Therapist -D+) &*.*&*N"*S +Therapist+ 1+-D Number+) )0 "&* T* T !)* + ssignment+ 1 + ssignment -D+ -NT*2*& 2*N*& T*D !3 D*. 4)T N4)) (&-, &3 8*3# +(atient -D+ -NT*2*& N'T N4))# S -D*NT-T31ST &T 5-T6 7) N'T

@B

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

+Therapist -D+ -NT*2*& N'T N4))# +Date assigned+ D T* D*. 4)T "4&&*NT<D T* N'T N4))# +Date case closed+ D T*# "'NST& -NT .8<( T< S,T .'&*-2N 8*3 1+(atient -D+) &*.*&*N"*S +(atient+ 1+-D Number+)# "'NST& -NT .8<T6(< S,T .'&*-2N 8*3 1+Therapist -D+) &*.*&*N"*S +Therapist+ 1+-D Number+)# "'NST& -NT +"8<")'S*<DT+ "6*"81 +Date case closed+ >> +Date assigned+ ) )0 "&* T* T !)* +Schedule+ 1 +Schedule -D+ -NT*2*& 2*N*& T*D !3 D*. 4)T S -D*NT-T31ST &T 5-T6 7) N'T N4)) (&-, &3 8*3# + ssignment -D+ -NT*2*&# +Slot date+ D T* N'T N4))# +Slot hour+ T-,* N'T N4))# +Status of the session+ 9 &"6 &127)# "'NST& -NT .8<S"6< S,T .'&*-2N 8*3 1+ ssignment -D+) &*.*&*N"*S + ssignment+ 1+ ssignment -D+) )0 "&* T* T !)* +(ayment+ 1 +(ayment -D+ -NT*2*& 2*N*& T*D !3 D*. 4)T S -D*NT-T31ST &T 5-T6 7) N'T N4)) (&-, &3 8*3# +(atient -D+ -NT*2*& N'T N4))# +Date and time of (ayment+ T-,*ST ,(1;) D*. 4)T "4&&*NT<T-,*ST ,(# + mount+ D*"-, ) 117# 2) N'T N4))# +Notes+ 9 &"6 &1177)# +&esult+ "6 &1;) N'T N4))# "'NST& -NT .8<( T<(3,NT .'&*-2N 8*3 1+(atient -D+) &*.*&*N"*S +(atient+ 1+-D Number+)# "'NST& -NT "8<D!T "6*"81+&esult+ -N 1'D*!-T'# '"&*D-T')) )0 "&* T* T !)* +,edication+ 1 +,edication -D+ -NT*2*& 2*N*& T*D !3 D*. 4)T N4)) (&-, &3 8*3# +Name+ 9 &"6 &1?7) N'T N4))# +Description+ 9 &"6 &12:;) )0 S -D*NT-T31ST &T 5-T6 7) N'T

"&* T* T !)* +(atient ,edication+ 1 +(atient -D+ -NT*2*& N'T N4))# +,edication -D+ -NT*2*& N'T N4))# +Dosage+ 9 &"6 &1:7)# +Start date+ D T* D*. 4)T "4&&*NT<D T*# +*nd date+ D T*# "'NST& -NT (8<( T<,*D (&-, &3 8*3 1+(atient -D+# +,edication -D+ )# "'NST& -NT .8<,*D<( T .'&*-2N 8*3 1+,edication -D+) &*.*&*N"*S +,edication+ 1+,edication -D+)# "'NST& -NT .8<( T<,*D .'&*-2N 8*3 1+(atient -D+) &*.*&*N"*S +(atient+ 1+-D Number+)# "'NST& -NT "8<*ND<DT "6*"81 +*nd date+ >> +Start date+ ) )0

#he first thing one can notice is that this set has two types of instructions$
@F

AS)

#<#O79A/

DROP TABLE

and
CREATE TABLE

in that order. #he reason for this is that if you find the need to modify your database structure in any way Iadd a table, omit attributes, change connections, etc5 and you run the modified S./ instructions, the 67O, #A /) command will start by erasing the previous tables, in effect allowing you to start from scratch. #he down side of this is that you will lose any data you might have entered into the tables. Notice that the instructions use capitali;ed letters and that the name of the tables use caps and smalls and are enclosed within 0uotes. 8ithout the 0uotes, ase will consider all letters as caps. #his feature relieves the programmer from =umping from lower to upper case too often. <nfortunately, it also creates potential problems li+e lost tables or columns impossible to find. 8e e*plain this in more detail later Isee 8hat S./ window are you, anywayG5. Also note that the imperative tone$ >67O, #A /)? is toned down by the inclusion of a conditional statement >9F )V9S#S?. #his way, if the table didnHt e*ist to begin with Ili+e when you run these commands for the first time5 then the application will not prompt an error message. For the same reason, be aware that it will also not prompt an error message if you mistype the name of the table, ma+ing you believe that you have erased a table that you really havenHt, so type carefully or chec+ this issue if things are not running the way you want. Finally, note that all the instructions end with a semicolon$ >J?. #his is the S./ e0uivalent of a period in the )nglish language and its omission is bound to create confusion. #he "7)A#) #A /) instruction starts by providing the name of the table to be created, also within 0uotes and using caps and small letters, and then describes the particular characteristics this table will have$ column names, type of variables used, relationships, the way to handle deletions, etc. #hese instructions are written within parentheses. 9t then finishes with a semicolon, more or less li+e this$
CREATE TABLE "Name of the Table" ("Name of Column" COLUMN ATTRIBUTE ! et"#$%

9nside the parentheses you specify first the name of each column, also within 0uote signs, and then the column attributes, li+e the +ind of variable you are using Ie.g.$ integer, varchar, date variable types, etc.5 and attributes li+e not null or auto increment, etc. Note that the instructions inside the parentheses are separated with a comma$ >,? and conse0uently the last instruction does not have one. At this time, please note the close resemblance of the S./ instructions with the :ariables 6efinition /ists we made earlier and how the former can be translated to the later with very little difficulty Iso now you +now why we insisted so much on them5. 9n fact, S./
@C

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

can be read very much li+e a formali;ed )nglish. Eo bac+ and read some instructions creating tables and see if you can identify the components that we tal+ about here. !aybe you are as+ing$ 6o 9 now need to learn S./G #o be e*act, you shouldJ and it can help you greatly in building good ase databases providing even greater fle*ibility than the wi;ard or design views. On the other hand, when you build tables, all your instructions will conform, more or less, to the same structures that appear in this e*ample. Only the name of the tables or their attributes are bound to change Ialthough there will be plenty of recurrences5 and you will be selecting within a +nown set of column attributes, most of which have been described so far. #his means that if you understand the instruction set we use in this e*ample, you should be able to handle most definitions for your own databases without re0uiring a college degree. So ta+e some time and analy;e the way the different tables have been built, and start developing a sense of how S./ wor+s and the synta* and grammar it uses. ,ossibly the more pu;;ling instruction is "ONS#7A9N# found inside the "7)A#) #A /) command. #his is a very useful instruction that allows you to, for e*ample, set the connections between the tables, indicating which column is the primary +ey and which are the foreign +eys. 9t can also allow you to set restrictions, for e*ample, ma+ing sure that only ! or F be accepted as gender entries, re=ecting other input, or ma+ing sure that values in one column are always smaller, greater or e0ual than values in other columns, re=ecting entries that do not conform to those rules. #his is very useful to ensure data integrity. #he "ONS#7A9N# instruction is followed by the name of the constraint. #his name is chosen by us, =ust li+e we gave a name to the tables or to their columns. 9n this case, all names are given in caps, with underscores separating components of the names. #his way we donHt need to use 0uote signs or worry about capitali;ation. For e*ample, find the following name in the last table of the instruction set$
&'(PAT(MED

that appears in$


"Patient"

CON TRAINT &'(PAT(MED &OREI)N 'E* ("Patient ID"$ RE&ERENCE ("ID Numbe+"$

8e came up with this name &'(PAT(MED to, somehow, mean that this constraint creates a foreign +ey in the patient-medication table. After the name comes the instruction that, in this case, defines that the >,atient 96? column in this table is a foreign +ey and holds the value of the >96 Number? column found in the >,atient? table. Now, that wasnHt so difficult. All your foreign +eys will be defined with this same pattern, =ust changing the names of your columns and the tables they reference. Of course, you will need to thin+ of uni0ue names for each declaration. #he "ONS#7A9N# names we chose can loo+ a bit cryptic, but made sense to us because we wanted to capture a rather comple* relationship with few characters. Of course you can define your own names, even using 0uotation mar+s and small and cap characters if you want to. For e*ample, you could have written$
@@

AS)

#<#O79A/

CON TRAINT "Patient &o+ei,n 'e- in Me.i"ation Table" &OREI)N 'E* ("Patient ID"$ RE&ERENCE "Patient" ("ID Numbe+"$

At this point you could be as+ing$ 8hy do we need to name "ONS#7A9N#S =ust li+e we name #ables and "olumnsG ecause in the future, as you optimi;e your database or adapt it to a new business practice, you might want to change the behavior of a particular constraint, maybe even drop it altogether Ibut without erasing the data you have entered in the tables so far5. #his would be impossible if you donHt have a way to reference the constraint that you want to modify. #he easiest way for doing this is to give a name to the constraint when you create it. 9nstructions that shape the type of "ONS#7A9N# you are building include$ ,79!A72 L)2, FO7)9EN L)2, 7)F)7)N")S and "-)"L. /etHs see other e*amples Igo and find the CREATE TABLE instructions that harbor these constraints5$

CON TRAINT C'(END(DT C/EC'( "En. .ate" 01 " ta+t .ate" $

#his instruction chec+s that the >)nd date? column in this table always stores a value that is greater Inewer5 or at least e0ual to the value in the >Start date? column. #his constraint received the name C'(END(DT which, in our mind, stands for >chec+ end date?.

CON TRAINT P'(PAT(MED PRIMAR* 'E* ("Patient ID"! "Me.i"ation ID" $

#his instruction establishes that the primary +ey of this table is formed by >,atient 96? and >!edication 96?, which is to say that this table uses a compound +ey formed by e*actly these two attributes Icolumns5.

CON TRAINT C'(DBT C/EC'("Re2ult" IN (3DEBIT3! 3CREDIT3$$

#his constraint is a bit more tric+y to read. First we need to +now that when using ase with the embedded -S./ engine, the names of tables, columns or constraints that are being referenced need to be enclosed in double 0uotation mar+s. !eanwhile, a string of characters Iany string of characters5 will be indicated by single 0uotation mar+s. 8ith this in mind we can understand that the "LR6 # constraint chec+s that the column >7esult? can only receive the values H6) 9#H or H"7)69#H and will re=ect any other value Ise0uence of characters5 that the user attempts to enter. 8ith this in mind now e*plain to me what does this mean$
CON TRAINT C'(PAT()NDR C/EC'( ")en.e+" IN ( 3Male3! 3&emale3 $ $

6onHt forget to identify in what table these instructions appear in.

CON TRAINT ID4(PAT UNI5UE ( "Patient ID" $

@A

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#his constraint, that we named 96VR,A#, ma+es sure that the >,atient 96? stores uni0ue numbers. Should we want to eliminate this restriction in the future, we could go to the >)*ecute S./ Statement? window Ifound in the #ools menu under >S./...?5 and run the command$ DROP ID4(PAT@ -owever Iand to avoid confusion5 9 have eliminated this instruction from the code set already and you wonHt find it in any table. 9f you happen to declare a constraint instruction that references a table that you have not yet created, ase will prompt an error message. #his is relevant for constraints that reference other tables Ithan the one in which is being declared5 li+e Foreign Leys. 7eview the S./ code again and note how the order on which tables are created avoids this problem, 9n short, when referencing other tables, you need to ma+e sure that they already e*ist. 9 recommend that you go bac+ to the instruction set and read the "ONS#7A9N# instructions again with this new information. 6onHt they ma+e more sense nowG /etHs focus now on the way to define the columns inside the "7)A#) #A /) command. /etHs review the following e*amples$

"&i+2t Name" 6ARC/AR(78$

#his instruction creates a column called >First Name? Inote the use of double 0uotation mar+s for the name5 which will accept u) to &F alphanumeric characters. Aha! Now is when that long and boring analysis of variable types we made before starts to ma+e sense. "an you tell what happens if 9 ma+e an entry to >First Name? that only uses (& charactersG

")en.e+" C/AR(9$ NOT NULL

#his instruction creates a column called >Eender? that accepts e4a"t$y C alphanumeric characters. 9t then adds the instruction >NO# N<//?, which means that ase will ma+e sure that you enter a value here. "an you describe the other available conditions we can set our columns toG

"Patient ID" INTE)ER NOT NULL

#his instruction creates a column called >,atient 96?, assigned to receive integer numbers. "an you tell me what is the biggest number 9 can enter hereG "ould 9 enter a negative numberG /ater 9 add the instruction >NO# N<//? to ma+e sure that there is always a >,atient 96? value.

"Amount" DECIMAL(:;!7$ NOT NULL!

#his instruction could stri+e you as strange. 2ou can easily read that we are creating a column called >Amount? that is to be not null and that is of the decimal typeJ but what are those numbers within parenthesesG 9n alphanumeric variables you specify the number of characters you want inside parentheses but 6ecimal is a number type of variable, not alphanumeric. 8ell, the answer is that you can specify the si;e of the column for any type
@D

AS)

#<#O79A/

of variable, be it a number or alphanumeric. 2ou can also define the precision, if you need to, with the number after the comma inside the parentheses. 9n this case, we have defined that the 6ecimal variable type Iwhich can store very, very large numbers5 used in >Amount? be organi;ed in a column (' digits wide and that it can store numbers with a precision of one hundredth of a point, that is, decimal places that range from '' to DD Iwhich are two decimal places, hence the number two5. 9n other words, >Amount? displays in a column of (' numbers, where the last two numbers represents (3('' numbers. 9f you were to enter the number (&.'4@, ase will store (&.'B. #his definition ma+es a lot of sense when you use a column to store money amounts.

"Me.i"ation ID" INTE)ER )ENERATED B* DE&AULT A <IT/ ;$ NOT NULL PRIMAR* 'E*

IDENTIT*( TART

#his is an important pattern as it defines primary +eys. #his instruction generates the >!edication 96? column and assigns it an integer variable type. 9t then adds the instruction that it should be generated automatically, the first entry being number ;ero, it should be NO# N<// and is the ,rimary Ley of this table. Although not e*plicit, this pattern also ensures that this column has uni0ue numbers. At this point you could be as+ing$ 6o 9 now need to create a "ONS#7A9N# that identifies >!edication 96? as a ,rimary LeyG No you donHt. #his has already been done in the definition of this column. Again, note that there is more than one way to do things with ase. 9f you review the S./ code now you will find that all tables have a primary +ey Ione of them even has a compound primary +ey, can you tell whichG5. 2ou might remember that we said in ,art 99 that, in theory, not all tables re0uired one. So whyG /ater on, when we build forms, we will simplify our wor+ greatly with the use of wi;ards and they might not wor+ properly if they donHt have these +eys as reference. 9n conse0uence it is better and some times re0uired to include them.

" ta+t .ate" DATE DE&AULT CURRENT(DATE

#his is an interesting declaration and we will review it again later when tal+ing about forms and reports. #he first part is very easy to understand$ create a column called >Start date? that will store a 6A#) variable. #he 6)FA</# setting ma+es sure that this variable is populated upon creation. ut, populated with whatG 8ith the content of the "<77)N#R6A#) function. "<77)N#R6A#) provides date information +ept by your computerHs internal cloc+. 8hen we later create a new record Iusing forms5, the 6)FA</# instruction will retrieve the value stored by "<77)N#R6A#) and store it in >Start 6ate? automatically.

"Date an. Time of Pa-ment" TIME TAMP(9$ DE&AULT CURRENT(TIME

-ere we are creating a column called >6ate and #ime of ,ayment? that will be populated automatically by the contents at "<77)N#R#9!) upon creation of the record. 9 want to focus on the number si* within parentheses. #hat is an inde* of precision. TIME TAMP acA'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

cepts a precision value of ' or C. ' means that the variable will hold no sub-second data. 9f you donHt indicate precision, the default is C. /etHs wrap-up all what we have seen so far in a more formal definition of the CREATE TABLE instruction. First, a "7)A#) #A /) instruction starts with CREATE TABLE followed by a name for the table. #hen, within parentheses, you specify one or more column definitions and one or more constraint definitions, all separated by commas. Finally you indicate the end of the instruction with a semicolon. 9f you were loo+ing in the 8i+i or other source for information on the CREATE TABLE command, you would come across a formal representation of the previous definition, which would loo+ li+e this$
CREATE TABLE =name0 ( ="olumnDefinition0 >! ###?>! ="on2t+aintDefinition0###?$%

#he first thing you will notice are the angle brac+ets I>W? and >X?5. #hey indicate that >name? or >columndefinition?, etc., stand for names, or values, that you are going to chose, whatever those names or values will be. #hen we have the s0uare brac+ets I>Y> and >Z?5. #hey enclose instructions that are not mandatory, that is, that we can chose to include or not. So for instance, this formal definition implies that we need at least one column definition but having constraint definitions is optional. /astly, the ellipsis Ithose three points together, >...?5 mean that the last instruction is repeated, that is, that we can ma+e more column definitions. ecause it is enclosed between s0uare brac+ets, in this case it also means that having more than one column definition is optional. Note the comma before the ellipsis. #his reminds you that you must separate column definitions with commas. 8hy are we going through thisG ecause after you finish this tutorial, you might want to +now more about ase and the S./ instructions it uses. 8hen you review the 8i+i and other sources, this is the synta* that you are going to find. Now, A"olumnDefinitionB and A"on2t+aintDefinitionB also have their formal representations. /etHs see$ "olumn 6efinition$
="olumnname0 Datat-pe >("olumn i@e>!p+e"i2ion?$? >ADE&AULT =.efault6alue0 B )ENERATED B* DE&AULT A IDENTIT* ( TART <IT/ =n0>! INCREMENT B* =m0?$C? B >>NOT? NULL? >IDENTIT*? >PRIMAR* 'E*?

2ou should be able to read that after the column name, the only re0uired parameter is the data type Iinteger, varchar, etc.5. 2ou can define column si;e and precision if you want to
A(

AS)

#<#O79A/

Iand even precise column si;e without defining precision5. 8hat does that vertical line Ialso called pipe, >[?5 stand forG #hat means that you have two or more options for a statement. For e*ample, in defining a column you can write$ )ENERATED B* DE&AULT A IDENTIT* ( TART <IT/ ;$ or you can write$ NOT NULL IDENTIT* PRIMAR* 'E*@ Of course, if you wanted the primary +ey incremented by a value other than (, then you would want to use the first option and include the increment that you want. So, in short, the pipe stands for a logical O7. /etHs now chec+ the very powerful constraint definitions$
>CON TRAINT =name0? UNI5UE ( ="olumn0 >!="olumn0###? $ B PRIMAR* 'E* ( ="olumn0 >!="olumn0###? $ B &OREI)N 'E* ( ="olumn0 >!="olumn0###? $ RE&ERENCE =+efTable0 ( ="olumn0 >!="olumn0###?$ >ON ADELETE B UPDATEC ACA CADE B ET DE&AULT B ET NULLC? C/EC'(=2ea+"h "on.ition0$

Notice how constraints allow you to set column properties, search for conditions to match and set delete and update options li+e those available through the 7elationships view. 9 hope that this review motivates you to go and find out more about ase, the -S./ engine and S./.

1hat .<6 window are $ou% an$wa$/


So far we have described two instances in ase where we can input S./ commands$ the 1.ueries1 page and the "ommand bo*. #hroughout this chapter we have described some differences between them that 9 want to summari;e here$ First, the 1.ueries1 page is reached by clic+ing on 1.ueries1 in the narrow column to the left under the heading 16atabase1 while the "ommand o* is found in the 1)*ecute S./ Statement1 window called by the S./ icon in the #ools !enu. Second, the instructions in the 1.ueries1 page do not transform your data or data structure. #his window only receives instructions on how to display the information that you already have in your database. 9t chec+s to see if your S./ statements start with the command 1S)/)"#1 and will prompt an error message if they donHt. !eanwhile, the instructions through the "ommand bo* can transform your data or data structure, that is, you can create, delete or modify your tables, columns and constraints and, in the process, delete data. 2ou can also input instructions that create, delete or modify records. #he "ommand bo* also accepts 1S)/)"#1 commands. #he third important difference has to do with the way they handle names. As you +now by now, tables, columns and constraints receive names that you assign in order to reference them later. #he proper synta* re0uests that those names be enclosed in double 0uotes, particularly if you are using mi*ed case names and spaces Ili+e 1,atient 9615. Now, mi*ed case names defined in the command bo* that do not use 0uotes are silently
A&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

converted to all uppercase but mi*ed case names used in the 1.ueries1 page that are not enclosed in 0uotes are passed as they are typed, without a conversion. #his can create some confusion and you better be aware. /etHs say that you define the following table through the "ommand bo*$
CREATE TABLE T+an2a"tionT-pe ( T+an(T-pe(ID INTE)ER )ENERATED B* DE&AULT A IDENTIT*( TART <IT/ ;$ NOT NULL PRIMAR* 'E*! T+an(De2"+iption 6ARC/AR(8;$! Debit C/AR(9$ NOT NULL! CON TRAINT C'(DBT C/EC'(Debit IN (3DEBIT3! 3CREDIT3$$ $%

and you later, through the same "ommand bo*, issue the following instruction$
ELECT D &ROM T+an2a"tionT-pe%

oth sets of instructions should e*ecute without error. -owever, when you are later creating a report in the 1.ueries1 page and issue the same instruction$
ELECT D &ROM T+an2a"tionT-pe%

2ou would receive the error message$ 1Table happened hereG!

TransactionType does not exist1.

8hat

9f you notice, the CREATE TABLE command in this e*ample does not use 0uotes when assigning a name to your table, so although you named your table 1#ransaction#ype1 Iwithout the 0uotes5, ase really assigned it the name 1#7ANSA"#9ON#2,)1 Iall upper case5. 8hen you issue the ELECT command through the "ommand bo*, although you again used mi*ed case, ase silently converted the name to all caps and didnHt have trouble finding the table. -owever, in the 1.ueries1 page you repeated the name as you wrote it but this time ase did not convert it to all upper case, despite the fact that you didnHt use 0uotes to encase the name. So now the application is really loo+ing for the table 1#ransaction#ype1 and not finding it, because you have really created the table 1#7ANSA"#9ON#2,)1. #he same thing is bound to happen with the column names 1#ranR#ypeR961, 1#ranR6escription1 and 16ebit1, which have also been defined without their double 0uotes. Notice that the CON TRAINT defined in the e*ample uses a name with all uppercase and no 0uote signs. #he silent conversion that will ta+e place here is irrelevant because it leaves the name the same. 2ou can chose to name all your ob=ects Itables, columns, constraints5 with uppercase and forget about 0uotes but it is considered better practice to use 0uotes. #his practice also gives you a bigger set of possible names. 9n this tutorial, constraints are the only ob=ects that we will name using only all caps.

A4

AS)

#<#O79A/

7ecapitulating and to be more precise, any string in the "ommand bo* that is not enclosed in 0uotes will be transformed to upper case. For e*ample$
DROP TABLE "Patient" if eEi2t2

will be converted by ase to$


DROP TABLE "Patient" I& E4I T

which gives you a good hint on why the "ommand bo* behaves this way.

AB

Chapter
*roducing our forms

At this moment we have a sound database design, which too+ a lot of thin+ing, and that we have encoded using S./ language to create the tables and their relationships with ase. Now we are going to focus on creating forms that will help us populate these tables swiftly while minimi;ing errors in data entry. #he first thing will be to remember the considerations mentioned in the first part of this tutorial regarding the need to ma+e forms that are unambiguous on what data are we supposed to provide for each field and to minimi;e errors in the input by offering pre-made options that are easy to indicate. 9n this tutorial we will focus on the following ways to simplify or automate data entry that are very useful$ radio buttons, drop down lists, sub forms, default values and some tric+s for time entry. 8e will further describe these options as we wor+ with them. /etHs get to wor+. On the ase document where you have the tables for our psychotherapy clinic, clic+ on the icon to the left over the word >Forms?. 2ou will see the following options appear in the Task panel Iupper panel to the right5$ 2reate forms in design view and 3se wi4ard to create forms. -owever there is still a third way not made e*plicit yet$ 6efining forms using S./. At this moment it seems necessary to e*plain something$ <sing S./ for creating tables or entering data re0uires that we +now S./. 9n contrast, using the 8i;ard =ust re0uires that we understand what are we being as+ed and chose the appropriate options. #he result using S./ will be as good as the underlying engine that we are using, in this case the -S./ embedded database system. 9n all merit, -S./ is a very good implementation of the S./ standard. <sing the wi;ard or design view, on the other hand, will only be as fle*ible as the software mediating our options and the resulting S./ code can be. 9n all honesty, the coders at OpenOffice.org have done a terrific =ob developing this easy to use graphic interface, but for its very nature, graphical interfaces can not always accommodate the comple*ities and intricacies that raw code can denote. Also, there can always be a bug here or there that could impair the ability of the software to achieve a particular goal Iwhich is why it is so important to report bugs and help achieve better code5. So we will be forced to use S./ code when the Eraphical 9nterface does not provide us with an option that we need or when we suspect that there could be a bug affecting us. #his means, again, that in order to develop robust databases, learning S./ is necessary. 9n short, S./ code gives us fle*ibility and power, design view and the wi;ard give us ease of use. 9t will not come as a surprise to you that in this tutorial we will be using these three options.

AS)

#<#O79A/

9n general, we will use the following approach to building forms$ First we create forms using the wi;ard, which will help us get up and going 0uite 0uic+ly. /ater we use 6esign :iew to customi;e them, clean them and leave them easy to read and understand. Finally we add any S./ instructions re0uired for more comple* functionalities, if necessary.

The !orm 1iAard.


9 want to start with the form for entering the information on the psychiatrists. First, because it is simple enough not to distract us from the process of building and cleaning the form, something we will cover here and later =ust assume that you are repeating with the other forms, and second because it allows us to e*plore how to use radio buttons for data entry. So, letHs recap$ clic+ on the icon over "orms in the left most column in your display, the one under the heading )atabase. Now choose 3se 5i4ard to 2reate "orm... #he first thing that will happen is that a 8riter document pops up, with some e*tra controls on the bottom, and -over it- the Form 8i;ard. So this is the big surprise, a form in ase is really a 8riter document, the one you use for editing and printing documents. Of course, the elements that we will include in this document, li+e te*t bo*es and radio buttons, need to somehow be connected to the database that we are wor+ing on. 6onHt worry about this as the Form 8i;ard will ta+e care of this connection. ut the fact that this is a writer document means that we can en=oy all the fle*ibility usually available for organi;ing the layout of our written documents. 9f you remember, the draft forms 9 made for part 99 in this tutorial were wor+ed with 8riter -although at that moment they were not functional and were made only to illustrate the layout- which means that, if we ta+e the time we can replicate them completely if we want to, now fully functional and all. #he Form 8i;ard is organi;ed in two columns$ the one to the left names the different steps the wi;ard will wal+ us through. #he panel to the right will as+ us the 0uestions that each step needs to +now about. 9n the first step we need to indicate where the fields that we will use are coming from, that is, what columns from what table will be associated to this form. 9n the drop down bo* you will find a list of all the tables available. Find the option >table$ psychiatrist? and select it now. Note that on top of the drop down bo* the caption reads$ Table or 6ueries. #his is because the result of a .uery is also composed of columns and you can use them with the wi;ard as if it were another table Iwe will be using this later5. <pon selecting the psychiatrist table you will see that a bo* in the bottom to the left populates with all the column names that belong to the table. 8e are supposed to select all or some of these for which we want a field in our form. For the sa+e of simplicity letHs =ust pic+ them all. 2ou do this by clic+ing on the button with the sign >XX?. 6o this now.

AC

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

Now all the names for the columns have shifted to the bo* on the right, meaning that there will be an input field for each column. 9f you had wanted input fields for only some of the columns, you would have had to select them with the mouse and then clic+ the button with the >X? sign. /etHs say that you see no reason for a field for the 96 number -because it will be generated by ase automatically, because the user does not need to +now this value and because you donHt want to leave it e*posed to an involuntary Iand fatal5 change. 9n this case you would need to clic+ every other name and then clic+ on the >X? button, every time for each field. 9f this were the only attribute for which you donHt want a field, you could also move all the column names to the right Iwith the >XX? button5, select the 96 number and then clic+ on the >W? button, saving you some time. -owever, for the time being, select all column names and then clic+ on >Ne*t? #he second step as+ us if we want to set up a sub form. 8e will deal with sub forms later and the ,sychiatrist form does not need one, so =ust clic+ on >Ne*t? without changing the content here. Now the wi;ard =umps to step five and as+ us what layout we want for the fields. #he default uses a table configuration Ithird icon from the left5, with the name of the columns in the header Icalled )ata sheet5. 8e will use option number one Icalled 2olumnar #7abels 7eft5. )*periment clic+ing on the other options to get a feel of the alternatives. Step number si* creates restrictions about the use of the data by the form, either allowing the view and modification of all data or not allowing the data to be viewed, modified or some combination of these. #he options are self e*planatory and we will not be using this yet, so we will advance to the ne*t step leaving the default$ This form is to display all data, with no restrictions. Step number seven allows you to chose the bac+ground color for the form and the style used by the te*t bo*es that conform the entry fields. 8hen you choose a color for the bac+ground, ase chooses colors for the fonts automatically. 2our selection here will have no bearing on the functionality of the form other than ma+e it easy to read. 9 believe that the offered combinations are well chosen and 9 li+e dar+ bac+grounds with white characters. ut that is me, you choose whatever you want. #he last step will as+ us for a name for this form and what we want to do with it. #he wi;ard will offer, as a default, the name of the table, in this case >,sychiatrist?. !any times this is enough but 9 would recommend to use a more descriptive name. Some people would add the letters >frm? before the name, to ma+e e*plicit the fact that this is a form. 9 invite you that, this time, you change the name of the form to$ >,sychiatrist 6ata )ntry Form? =ust to see what happens. /ater, you can use your own naming conventions. Finally, ase wants to +now if it should offer the table for data entry or if it should open it in 6esign :iew for further editing. 8e will ta+e the second option. "lic+ on it and then clic+ on >Finish?.
A@

AS)

#<#O79A/

At this moment, the wi;ard closes and the form opens again, this time with te*t bo*es for data entry and corresponding labels. #he form has opened in 6esign :iew and is ready for our editing. 2ou can also notice dotted lines forming a grid pattern. #his is to ma+e it easier to design and position elements on the page.

Design #iew and the *roperties dialog bo3.


9f you clic+ on any of the te*t bo*es or their accompanying labels, you will see small green bo*es appear defining a rectangular limit. #his limit includes both the label and the te*t bo*. 9f you try to move one, the other will drag alongJ if you try to modify one, chances are that you will somehow modify the other too. At this moment 9 want you to double clic+ with the left button of your mouse. A dialog bo* appears with the name roperties8 1ultiselection. #his properties bo* allow us to modify the characteristics of the elements we place on our form, and will become very handy =ust now. !ultiselection means that there are two or more elements alluded by the properties bo* because they have been grouped together. #his is why the label and the te*t bo* are traveling together and changes on one can change the other too. 9f you now clic+ elsewhere on the form, the group becomes un-selected and the ,roperties dialog bo* becomes empty, stating that no control has been selected. 2ou can now clic+ on another element and its properties will become displayed by the dialog bo*. 9f you close the bo*, you can call it again by left-double clic+ing the mouse while on top of an element. "lose the dialog bo* for now and then clic+ Ionce5 over an element with the mouse button to the right. Now we see the green s0uares again, indicating the active element, while the more familiar conte*tual menu appears. Near the bottom of the menu you will find the item >Eroup? and within it the options ungroup and edit group. "hoose ungroup. 9f you clic+ on an ungrouped element now, you will see that they display the green bo*es but only in relation to themselves, not e*tending to include the other elements. 9f you call the properties dialog bo*, you will see that it offers options that are particular to the selected element, in this case, either a label or a te*t bo*. /et us now analy;e what we see on the screen$ there are nine pairs of labels and te*t bo*es. !ost of the te*t bo*es are of the same length e*cept for the one after &) (umber. 9f you analy;e the S./ code that created this table you will see that all the bo*es with similar length are for some +ind of te*t entry while &) (umber is an integer variable. So maybe ase chose the length of the bo*es depending on the type of :ariable they are. 8e might want to change these lengths in order to ma+e the form less intimidating and easier to read. #he other thing you can notice is that the labels describing each bo* give a 0uite accurate description of the +ind of data entry that we e*pect. -ow did ase +nowG 9f you loo+ at the S./ code that created the table, again, you will see that ase actually copied the name of the column as given by us. ecause we too+ the time to use double 0uotes, gave descriptive names and used spaces between words, now these descriptive names appear
AA

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

to the left of the bo*es. 9f instead we had used more cryptic names for the columns, li+e ,LRFS#RN!, then the labels would be displaying =ust that. #his would not be a problem however because we can easily change the caption in the label through the ,roperties dialog bo*. Select the pair with >Number 96? and ungroup them. Now select the te*t bo* only. 2ou can position the cursor over it and, by dragging the borders, ma+e it wider or higher. 2ou can also reposition the bo* anywhere on the form by dragging it while the cursor loo+s li+e a cross with arrow heads. Nice! 8ith these s+ills you can, for e*ample, reduce the ostal code and 9tate fields -they donHt need more than five and two characters respectively- and place them side by side so the person confronted with this form finds it more familiar and less of a chore. Now select the label element and call itHs properties dialog bo*. #his time, the bo* has two tabs$ :eneral and ;vents. #hrough the ;vents tab you can program behavior in response to the events named in the dialog bo*. #his re0uires some macro programming and we will not be using this feature in this tutorial. 8ith the :eneral tab we can change other properties. #he Name property is automatically provided by ase and it is used to refer it with internal code Iconnecting the form with the database5. #he second property corresponds to the caption that we actually read. "hange >Number 96? for >,sychiatrist ,rimary Ley? and then hit return. #he cursor goes down to the ne*t property in the dialog bo* and the value is immediately changed in the label. #his also happens if you ta+e focus from this field. #ry it. 9 feel that the default si;e for the font in the labels is somewhat small. /etHs change this. Find the property "ont in the dialog bo* and clic+ on the >...? button. #his will call a dedicated Fonts dialog bo*. #he first tab, >Font? allows us to change the font, the typeface and the si;e of the te*t in the label. #he ne*t tab allows us to include other effects, including changing the color of the font. Feel free to e*periment with this for a while. "hose a font si;e of (& and see what happens. #he te*t in the label is now bigger but does not display completely. #his is because the boundaries set by the green s0uares did not change after we increased the si;e. 6rag the s0uares until you see the complete te*t of the label. As an e*ercise, change the font si;e of every label in this form to (& and ad=ust the length of the te*t bo*es to something commensurate with the amount of data they will receive. Now scroll to the bottom of the properties dialog bo*. #he second to last property reads >-elp #e*t?. y writing here you activate and populate the tool-tip. #his is a yellow rectangle with helpful information that appears when you place the cursor over an element on a form. 2ou find many e*amples of this in professional software or the 9nternet. ase automatically does this for usJ we only need to insert the useful information. #hat is what you type here. For e*ample, in the bo* for >Name? you could write$ >)nter the first name of the psychiatrist?. 2ou can now save the form edit, close it and call the form. ,lace the cursor over the bo* and see the tool-tip appear.

AD

AS)

#<#O79A/

One important way to ma+e forms more gentle to the eyes of the user is to limit the amount of fields to the ones he will actually have to populate. As mentioned before, there are good reasons to eliminate the Number 96 field and have this form less crowded. ut wait! 8ould not this interfere with the ability of ase to include the auto-generated primary +ey numberG 9t will not. ase will continue to generate uni0ue primary +eys and include them into the records. 8hat we are doing here is to ma+e e*plicit the fields that the user is shown or not. #he automatic generation of primary +ey numbers was coded with the creation of the table itself and is not interfered by this. Now that we are getting a hang on the usefulness of the ,roperties dialog bo*, lets use it to program our radio buttons.

&adio 0uttons.
7adio buttons offer the user a set of mutually e*clusive options. #he user can chose only one of them. 8hat we want to achieve is that the elected option is entered to the corresponding column in our table. Now, pay attention$ #he options for radio buttons better cover all possible alternatives. 9f not, then at least the user should find the option to leave the field unanswered. Eender is a good candidate for using radio buttons. Eranted, male and female are not all the possible options Ihermaphrodites, among other less common options5 but will correspond to a 0uite high percentage of the users. 9n another conte*t however Ia database for gender research, for e*ample5 this could be insufficient. So plan your radio buttons carefully. Another place where radio buttons can be used to an advantage in this e*ample is in the table to register if the session too+ place or not Isee the form layouts in part 995. #he first thing that we need to do is actually obtain the radio buttons. 2ou will find them in the Form "ontrols !enu. #his menu usually pops up automatically when you open a form in 6esign :iew. 9f not, go to >:iew? menu option in the writer document where we are editing our from and select >#oolbars? Ithird from the top5 and clic+ on >Form "ontrols?. Now a floating menu appears, with the name >Form ...?. #his is a small menu that offers several icons. #he icon of a circle with a blac+ spot is our radio button. 9f you leave the cursor on top of it, a message appears Ia tool-tip, actually!5 with the name$ >option button? which is how ase calls the radio buttons. 9f you left-clic+ on this icon, the cursor changes to a cross with a small bo*. #his allows you to place the radio button somewhere in the form page. 2ou can actually place it wherever you li+e. Kust for clarity with this e*ample, try to place it ne*t to the te*t bo* with the >Eender? label, by dragging the cursor and releasing the left mouse button. 9f things happen li+e in my computer, you should see a radio button with the caption >option button?. 9f you chose a dar+ bac+ground color Ili+e 9 did5, the caption in blac+ will be difficult to read. #o fi* this, call the ,roperties dialog bo* for the radio button. 9n the general tab, change the 7abel to >!ale?. #hen clic+ the "ont button, select >bold? and
D'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

change the font si;e to (&. 9n the >Font )ffects? tab, change the font color to white. #hat should be much better. /etHs now program the behavior that we need. #he ,roperties dialog bo* for a radio button offers a tab that we have not seen yet$ #he )ata tab. 9f you select it you will see three fields$ 6ata field, 7eference value Ion5 and 7eference value Ioff5. 6ata field indicates what column this control will reference. ecause the wi;ard built this form for the psychiatrist table, you will find the name of all the columns for such table. "lic+ on the list bo* and see them appear. Of course, select >Eender?. #he 7eference value Ion5 holds the value that will be passed to the Eender column if this radio button is selected. 8rite >!ale? there. eware!$ if you chec+ the S./ code that built the ,sychiatrist table you will find a CON TRAINT that only accepts >!ale? and >Female? as possible entry strings for the Eender attribute. Note that the initials are capitali;ed. 9f you write >male? Iwithout the capitali;ed initial5 in the <eference value $on%, ase will report an invalid entry error every time you select this radio button. Now, on your own, create a second radio button. "hange the label to >Female? and ma+e it readable, relate the radio button to the >Eender? field and write >Female? in the <efer# ence value $on% field. -aving created the second radio button, align both buttons so that they are at the same level Iuse the grid to guide you5 and chose a harmonic spacing between them. !a+ing it pretty ma+es data entry a bit more en=oyable. At this point we no longer need the te*t bo* for entering the gender$ the radio buttons will ta+e care of this. ut we are going to leave it for a while so that you can see the radio buttons in action. First, ungroup the label and the te*t bo* and ma+e the bo* smaller Ienough for C or A characters5. Now ta+e the bo* out of the way and place the radio buttons in its place Iyou can group them and move them as one element5. For reference, leave the te*t bo* near by. 9f you donHt +now how to group elements, here is how$ Select one element by right clic+ing once on it. Ne*t, press the 9hift +ey and select another element. Now both elements appear under the same area defined by the green bo*es. 7epeat this to include as many elements as you need in the group. 7ight clic+ the mouse while the cursor is a cross with arrow heads and in the conte*t menu that appears, clic+ on >Eroup...? and select >Eroup?. Now your elements are grouped. #his would be a good moment to save your wor+ Ilest a crash dissolve it into ether5. "lic+ the save button but then also close the form. 8hen you go bac+ to the ase interface we will find this document under >Forms?. 6ouble clic+ on it to use it. Now the form appears again, but without the grid lines. #his form is active and any data or alterations will end in the corresponding columns. 2ou are actually in the position to
D(

AS)

#<#O79A/

start populating the ,sychiatrist table! 9f you clic+ on either radio button, you will see the corresponding te*t appear in the te*t bo*. #his means that this record has accepted your gender input! 9f you change your mind and clic+ the other radio button, the form automatically changes the value and also erases the dot in the radio button previously selected, placing it in the new option. #his happens because both radio buttons have >Eender? in their )ata field and radio buttons are programed to be mutually e*clusive. Now, how do we ma+e one of the radio buttons be selected by default, say, the >Female? optionG For this to happen, you need to ungroup the radio buttons and call the ,roperties dialog bo* for the radio button with the female option. 9n the Eeneral tab you will find the )efault status property. "hec+ >Selected?. 9mmediately, a small blac+ circle appears, indicating that this options is the current one. As we said, we do not need the gender field bo*, and you should erase it. ut before you do 9 want yo to study its ,roperties dialog bo*. 6onHt worry about the >)vents? tab. Focus on the >Eeneral? and the >6ata? tabs and study and play with the options. #his teaches plenty. /etHs finish editing our ,sychiatrist Form. y now you should have eliminated the >96 number? and >Eender? te*t bo*es, made the labels bigger, re-si;e the remaining te*t bo*es to be more commensurate with the amount of data they will typically receive and organi;e them in a way that is pleasant and easy to read. 9n the #oolbar select font si;e &C, font color white and center te*t. #hen write$ >,sychiatrist 6ata )ntry Form? at the top of this page. 8ell, this is loo+ing very nice. At this moment you could produce the !edical 6octor Form because we are going to need it ne*t and because it is very similar to the one we =ust made. #his should be good practice.

Tab .tops Band &adio 0uttonsC.


!ost people that do data entry li+e to use the +eyboard to navigate the form. 9f the cursor is in the first field, you can travel to the ne*t by pressing the #ab +ey. #hey enter the value for the current field, press the #ab +ey and move to the ne*t field. #ry this. 9 am sure that you noticed that every thing wor+s fine e*cept for the radio buttons. #he navigation of the form =ust s+ips them. "urrently a radio button can only be accessed by the #ab +ey when it has been selected. A group of radio buttons where none is selected cannot be accessed by the +eyboard. 9 have found that even if you leave a radio button selected by default, that particular radio button is integrated into the tab order, but the others are left out, which does not help to change a selection. Also, the button is not necessarily left in a consecutive order, which is not elegant. #his last thing, at least, we can fi*! /etHs go bac+ to )dit :iew$ "lose the active form and go bac+ to the ase interface. 7ight clic+ on the ,sychiatristHs form and chose edit. #he edit view of the form, grid pattern and all, should reappear now.
D&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

9f you call the ,roperties dialog bo* of any ungrouped element you will see in the Eeneral section two properties$ Tabstop and Taborder. #he first one indicates if you want this element to be part of the tab order. For instance, we are using the Eender te*t bo* placed by the wi;ard as a window to chec+ the value assigned to Eender. 8e donHt need the tab to stop here so we could, with all confidence, set the #abstop property of this element to >No?. #he Taborder indicates the se0uence of tab stops in the form. 2ou give each tabor# der property of every ,roperties dialog bo* of every element in your form a consecutive number starting with ;ero. )ach press of the tab +ey will move the cursor in such order. #here is another way to do this that ta+e less time$ 9n the bottom of your form in edit view you can see several buttons. 9f you are not seeing this go to, and clic+ on, :iewX#oolbarsXForm design. 2ou will see seventh from the left a button that shows a chec+ bo* connected to a radio button with a curved arrow. 9f you place the mouse cursor over it a tool-tip will appear displaying the te*t$ >Activation Order?. "lic+ it now and a dialog bo* will appear with a list of all the ob=ects that can receive focus by pressing the #ab +ey. Taborder will follow the up-to-down order of this list. 9f you want to change the tab order all you need to do is reposition the elements in this list, either by dragging and dropping them or by selecting one and then moving it up or down with the arrow buttons.

!orms with .ub !orms.


/etHs now develop the ,atient form. #his form imposes two new challenges$ First, the need to record an unspecified amount of phone numbers for each patient and, second, the proper assignment of medical doctor and psychiatrist. 9f we do not enter the data for medical doctor or psychiatrist e*actly the same way we have them in their own tables, ase could never find the records and thus would provide wrong information when 0ueried. #o prevent this we are going to use a drop-down list that will automate the correct input. #he problem with the phone numbers for the patients is that each patient will have a different and un+nown number of phone numbers that need to be recorded. #rue to first normal form we had decided to place these phone numbers in their own table, using the patientHs primary +ey as a foreign +ey in order to connect each phone number with its proper owner. #he cardinality for this would be$ one patient, one or more phone numbers, or (..n. /ater, when we want to retrieve the phone numbers for a particular patient, we have to ma+e a 0uery that, more or less, reads$ retrieve all phone numbers that have this primary +ey Ibelonging to a patient5 as a foreign +ey. For this to wor+, we need to ma+e sure to include the primary +ey of the current patient while recording his3her phone numbers. 9n the draft we made for the patient form, we had devised a button that would call another form where we would record the phone numbers. #his form would need to handle the recording of these relationships. #he truth is that ase provides a solution that is by far more simple. #his solution allows us to include a second form inside the primary form for tables that hold a (..n relationship, where the sub form is for the table at the n sideJ and will automatically record the primary +ey of the current record at the principal form, in
D4

AS)

#<#O79A/

this case, the current patient. #his is what sub forms do. Obviously, we are going to use this option. /etHs start by calling the form wi;ard and select the patient table. Ne*t, select all column names to receive input fields. 9n the second step we are as+ed if we want to set up a sub form. #his time clic+ the chec+bo* for >Add Subform?. #hen select the option that reads$ >Subform based on e*isting relation?. ase offers you the tables that have a defined connection with the patient table Ias established by the S./ code creating the tables that defined relationships5. 9n this case you are offered to choose between ayment and hone number. Select hone number and then clic+ on >Ne*t?. Now the wi;ard offers you all the column names in the ,hone Number table for you to decide which ones will appear on the form. 9n this case there is hone &), atient &), (umber and )escription. hone &) is the primary +ey of the record and atient &) is the foreign +ey we need to associate for this to wor+. 9t would be a bad idea to include them as fields and ris+ someone altering the numbers. 8e already +now that not including them will not stop ase form recording the data properly, so my recommendation here is that we donHt include them. 8e will =ust select Number and 6escription, which is the data the user really needs to wor+ with. After you have passed them to the bo* in the right, clic+ on >Ne*t?. ecause ase is going to calculate the =oins for itself, the wi;ard is going to s+ip step four and land us directly on step five. -ere we will select the layout for the form and the subform. #his time we are going to select the 2olumnar #7abels left for the principal form and )ata 9heet for the sub-form Ioptions one and three from the left, respectively5. #he reason for choosing 6ata Sheet is that it allows us to see a good number of the recorded phone numbers for the particular patient without having to navigate the records. Anyway, feel free to e*periment. /eave the default in step si* IThe form is to display all data -with no restrictions5 and choose the style of your li+ing in step seven. 9n step eight chose a name for the form I9 used ,atient 6ata )ntry5 and as+ the form to open it for editing. $At this moment you could customi4e the form repeating the steps described before8 1ake the labels readable and ad=ust the si4e and layout of the te*t bo*es. >ou can also take the field for the primary key out of tab order and make it to be read only, so no one inadvert# ently changes it $find the option in the roperties dialog bo*%. Then, use font si4e .? to write @ atient )ata ;ntry "ormA for a title and, hitting the B;nterC key several times, place the cursor above the sub#form and type @ hone (umbers8A%. #o begin with letHs arrange the sub-form. /eft-double clic+ on it. #he green s0uares will appear, indicating that it has been selected and its ,roperties dialog bo* shows up. Analy;e the Eeneral tab to have an idea of the options offered.
DB

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#he first thing we can do is diminish the width of the sub-forms to ma+e it less intimidating. 2ou can do this by dragging one of the green s0uares on the sides, =ust li+e with the te*t bo*es or the labels. Of course, changing the height will change the number of phone numbers in simultaneous display. #he ne*t thing that you can do is ad=ust the width of the columns for (umber and )escription. 7emember that the phone number has been defined for a ma*imum of (' characters and that if you include spaces while ma+ing an input and e*ceed the (' number limit, ase will will re=ect it. "alculate a width accordingly so it gives the user a hint. "lose the design view and open the form. 2ou will see that the sub-forms is not active at first. 2ou can notice this because it does not offer you the chance to input a record. #his is because the data in the sub-forms relates to data in the principal form but the principal form has no records yet. #he principal form has the fields of First Name and Surname as re0uired Ii. e. NO# N<//. 2ou can see this by reviewing the S./ code that created it5. After you introduce the re0uired data, the sub-form activates. 2ou will see a green arrowhead indicating a yellow flash. 2ou can now enter the number and its description, and navigate the form with the #ab +ey. 9f you later decide to erase the record for the patient, ase will act depending on how you have handled deletions. 9f you had chosen "ascade 6elete, for e*ample, deleting the patient would delete all his3her phone numbers along with the record. 9f you had not made any provisions, ase will prompt an error dialog bo* instead. 9n that case you will need to manually erase the phone records and, only after that, erase the patient record. Eive it a try. 9n order to manually delete a record press the icon with a red HVH ne*t to a green arrow head. 9f you havenHt defined how to handle deletions yet, go to the >relationships? view I#oolsX7elationships...5 and find the line that connects the >,atient? table with the >,hone? table. 6ouble clic+ on it Ior right-clic+ and then select H)ditH5 and a menu will appear. Select the >6elete cascade? and confirm. /etHs go bac+ to design view and tac+le our second challenge.

Drop Down lists


8e have hinted that most times a uni0ue number would be better than a surname as a primary +ey. 8hen we associate a psychiatrist to a patient, what we are really doing is storing the primary +ey number -that identifies a psychiatrist- in the foreign +ey column of the patient table where psychiatrists go. 9n other words, relating the appropriate psychiatrist re0uires recording its primary +ey in the field called sychiatrist &) in the ,atient 6ata )ntry form. 9f you chec+ the S./ code that created the ,atient table you will see that the data type assigned to sychiatrist &) is an 9N#)E)7, which handles numbers. 9f you try to write >6r. Kones? you will get an error. #he form e*pects a value li+e >'(&?, which should be the primary +ey for the record of 6r. Kones. #his means that we would need to +eep trac+ of the primary +eys associated to each psychiatrist recorded in order to enter the right information. 8ho remembers thisG #his is not
DF

AS)

#<#O79A/

practical. 8hat we really want is to have ase offer us the names of the psychiatrists but, once we have made our selection, really record only the +ey number. #his is e*actly what a drop down list can do. At this point you have the ,atient 6ata )ntry Form in 6esign :iew. Select the ,sychiatrist 96 label and te*t bo* and un-group them. Now select the te*t bo* and delete it. "all the Form "ontrols menu and select the /ist o* icon, the one that loo+s li+e a rectangle with lines of te*t and up and down arrowheads to the right side. #his icon is usually ne*t to the radio button icon. ,lace a /ist bo* to the right of the label. 8hen you release the mouse button, the List o4 wi<ard appears. #his wi;ard goes through three steps in order to identify the list bo*Hs source and destination values. 9n the first step you are shown a list of all the tables in this database and are as+ed to select the source table, that is, the table from which the list bo* will gather its data. 9n this case you will need to choose the ,sychiatristHs table. #hen clic+ ne*t. 9n the second step you are shown a list of the names of all the columns in the ,sychiatristHs table Ithe chosen table5 and are as+ed to indicate which one will provide the data to appear in the list bo*. 9n this case, chose the 9urname attribute. #his means that, when active, this list bo* will display all the 9urname records found in the sychiatrist table. 9n the third step you indicate what data from the source table Ithe sychiatrist table in this case5 is going to what column in the destination table Ithe atient table in this case5. ,lease note that you are entitled to chose any column from the source table and any column from the destination table. #hey are all listed in their respective bo*es. #here is only one condition$ the data type of the source must match the data type of the destination. #his ma+es sense$ it would be impossible to try to insert a :A7:"-A7 type of data into a #9N29N#. 9n this third step, the wi;ard shows you two bo*es. 9nside the bo*es the wi;ard lists all the names of the columns in the corresponding tables. #he bo* to the left, under the caption >Field from the :alue #able? corresponds to the destination table Iin this case, the atient #able5. 8hen you chose a column here, this will be the receiving column. 9n this case you should select sychiatrist &). #he bo* to the right, under the caption >Field from the /ist #able? corresponds to the source table Iin this case, the sychiatrist table5. #he name you chose here will be the name of the column from which the values will be copied. 9n this case you should select &) (umber. After you have chosen a destination and a source, clic+ on finish. #his will close the wi;ard and leave you to edit your /ist bo*. Arrange position and si;e to your li+ing.

DC

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

"all the /ist bo*Hs ,roperty dialog bo* and study the attributes given to it by the wi;ard. #he more important ones are in the )ata tab. ,articularly, Type of lists contents specifies the use of S./ and 7ist content holds the S./ instruction to be e*ecutedC. For now, letHs go and see how this table wor+s. "lose design view and call the psychiatrist form. !a+e sure to include some valid entries. #hen, close this form and call the patient form. 8hen you clic+ on the arrow head you will see the surnames of all the psychiatrists in your database. #he beauty of this is that this list is prepared, by the S./ instruction that we saw, every time we use this control. #his means that if you include more psychiatrists in your database, their names will also be included in the drop-down list. #his list updates itself! 8hen you select a psychiatrist, it is the primary +ey number, not the surname, that is passed to the patient table. 2ou can monitor this by creating a te*t bo* and associating it to the corresponding field. 2ou will see it displaying the appropriate number. -owever, you could e*press concern because the list bo* is displaying surnames only. 8ith two psychiatrist with the same surname, which is the one 9 want to selectG 9n order to decide, it could be good if the list bo* included the first name of the psychiatrist too. -ow do we do thisG -ere is where we will need to use S./ again!

6ist 0o3es with compound fields.


y now you +now that the /ist o* wi;ard will as+ you to chose a table and the name of one, and only one, column to populate the data. 8e have chosen >Surname? but now feel that it is not enough. 8e would li+e the /ist o* to display both, the surname AN6 the first name, in order to ma+e the selection clearer to the user. #he thing is, how do we produce a table -or something similar- that will have the first name and the surname of the psychiatrist table as one columnG #his is where a +iew comes in handy. A :iew is the result of a 0uery. As you +now, the results of 0ueries are displayed in columns and, conse0uently, can be thought of as tables. 9n fact, ase stores :iews with the tables. So we need to ma+e a 0uery that will produce the result we want, transform that 0uery into a view and then use the resulting view with the /ist o* wi;ard. .ueries are built with S./ code. Although ase allows us to create simple 0ueries with the ease of point and clic+, this particular 0uery uses a synta* available to the embedded
C 8hich in this case should read$ ELECT " u+name"! "ID Numbe+" &ROM "P2-"hiat+i2t". 2ou can also do the wor+ of the wi;ard by hand as e*plained in pages ('A-('D. ut for now, let the wi;ard ta+e care of this. D@

AS)

#<#O79A/

-S./ database engine but not incorporated into versions of ase earlier than 4.&, so we are going to produce it manually. /etHs start. First, in the ase interface, select the icon over the name >.ueries? #his is the second icon from top to bottom in the column under the name >6atabase?. #hree options will appear in the top panel under the name >#as+s?$ >"reate .uery in 6esign :iew...?, ><se 8i;ard to "reate .uery? and >"reate .uery in S./ view?. Select this last one. A screen will open with a blin+ing cursor. -ere is where you will enter the S./ code. #ype the following$
ELECT " u+name" BB 3! 3 BB "&i+2t Name" A "P2-"hiat+i2t"% "Name"! "ID Numbe+" &ROM

Actually, this code is 0uite simple to understand e*cept for those >[[? signs, called Hdouble pipesH, between surname and first name. /etHs analy;e this statement$ #his instruction commands the database to se$e"t 9urname, "irst (ame and (umber &) from the sychiatrist table. #he double pipe is a concatenation instruction accepted by -S./ Ibut, as said, not understood by recent earlier versions of ase5. 9n this case, a double pipe is connecting the contents of Surname with a comma and a space and a second double pipe is connecting the previous with the contents of First Name, and all of these is to be placed inside one column called >Name?. #his is =ust what we needed. 7emember that with ase, single 0uotes are used for string literals, in this case, the characters for the comma and the space, and that double 0uotes are used for the names of tables, columns or constraints Iunless they only use capitals and no spaces in those names, in which case the 0uotes are not needed5. 9f you run this 0uery you will see a table with two columns$ #he first one would have the surname and first names of all the psychiatrists in your table, separated by a comma Iand a space, very important5, and the second column would have the primary +ey number. #he editor in which you have typed this 0uery has two buttons for running it$ One that loo+s li+e two pages with a green tic+ where they overlap Iwhose tool-tip reads$ >7un 0uery?5 and another one that says S./ with a green tic+ over the letters Ithat displays >7un S./ command directly? when you place the cursor over it5. #he first button runs the instruction by ase first but if your version of ase does not understand the double pipes, it will throw an error message of improper synta*. 9n such case you must select the second button, which runs the S./ instruction directly. ,ress it and you will not see any changes in your screen e*cept that the button remains depressed and the other run 0uery button becomes deactivated. Now save this 0uery. 9 used the name >0ry,sychiatrist? to remember that this is a 0uery. 2ou can double clic+ on the 0uery and a table will come up. 9n my computer, and after previously inserting three fictional psychiatrists through the ,sychiatrist 6ata )ntry form, 9 have$
DA

F7O! N)8 ame *mith, Dohn "ere4, $delaide -ecter, .annibal ID umber & 3 :

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

!y 96 Numbers are not consecutive because 9 had made some deletions and -S./ does not recuperate numbers, it =ust +eeps incrementing its counter. Another important thing to +now is that if any of the fields that were =oined by the double pipe 0uery command, in this case surname and first name, were empty, then the entire record in the >Name? column would appear empty too. #hat is, 9f 9 had not entered the first name for 6r. ,ere;, for e*ample, my little table would loo+ li+e this$
ame *mith, Dohn -ecter, .annibal ID umber & 3 :

8e have two options here$ we include conditional clauses in the S./ command, loo+ing for empty strings and instructing to include the non empty element, or we ma+e sure that both, Surname and First Name are defined as NO# N<// so that they can not be empty when 9 need to use them. 9 will chose the second solution for simplicity. /etHs go bac+ to producing our compound list bo*. For the ne*t step we cannot use the 0uery. 8e need the table produced by the 0uery, which is called a :iew. 2ou can thin+ of a :iew as a virtual table. 9t is generated by the 0uery when itHs called, at which moment it becomes a table you can use. #he good news is that this virtual table will update every time itHs called, incorporating new records or deletions to the psychiatrist table. #he bad news is that this calculation will add some time to the production of the form, ma+ing it slower the more records it needs to process. #o produce a :iew, right clic+ the 0uery we =ust created and, in the conte*t menu that appears, select the option >"reate as :iew?. A little bo* will as+ you for a name for this view. 9 used >v,sy/ist?. After you confirm this, the bo* disappears and not much more happens. 9f you now go to the #ables section, you will see our new addition, with a particular icon showing that it is not a regular table but a view. Now you can produce your list bo* as normally. Eo to the Form section and select the >,atient 6ata )ntry? form in edit mode. "reate a new list bo*. 8hen the /ist o* wi;ard appears, it will include the >v,sy/ist? view along with your tables. Select it. "hoose >Name? to populate the list bo* and chose >Number 96? as the record to be copied to >,sychiatrist 96? in the receiving table. #A6AAA-!

DD

AS)

#<#O79A/

Now, create a list bo* for the medical doctors that will also display both the surname and the first name. 2ou will need to adapt the S./ code accordingly.

Default values.
#he address component of the tables we have used in this tutorial all include a >State? attribute. One can e*pect that most of the patients for this psychotherapy clinic will reside in the same state. 9t is possible to have the forms display this state automatically and simplify the process of data entry for the user. Of course, if the user encounters a patient that actually lives in another state and comes in for therapy, then he can change the value in the form. 6efault values can be set by the ,roperties dialog bo*. Select the te*t bo* for the >State? field. Find the property >6efault :alue? and enter the string that you want. For this e*ample 9 will use >N2?, which is where 9 live at the time of writing this tutorial. Now, the forms will include the >N2? value in the >State? field for each new record. 6efault values can also be made possible by editing the tables. #he big difference is that default values through the ,roperties bo* only affect the fields in the form. #his means that if you decide to include records writing directly to the tables, there will be no default values in the assigned fields. -owever, if you assign default values through the design of the table, these values will appear in both, the forms and while using the tables to enter data. /etHs see how to do this$ First, clic+ on the #ables icon and right clic+ on the >,atient? table. 9n the conte*t menu that appears, clic+ on >)dit?. #he table now opens in 6esign !ode. 2ou can see a list of all column names and the data types each accept. 9n the lower part you can set some parameters for the variable, which are specific to each data type and will change when you change the +ind of variable you select. Find the >State? column name and select it. #he bottom of the page shows the parameters specific to #e*t I"har5 data types. #he third parameter from top to bottom is )efault value. -ere we will type >N2?. Now save the table and we are ready. 9f you open the form you will see that the ne*t record already has N2 in the field for State. Of course, if the user needs to change the value to >NK?, for e*ample, all he needs to do is overwrite on the field. :ery nice. /etHs now see how to do the same with 6A#) variables.

+ntering time and date.


#he patient table has two columns that store date information$ the 6A#) for registering the birthday of the patient and a #9!)S#A!, for registering the moment she3he is admitted as a patient. 2ou might remember that 6A#) records year, month and day information while #9!)S#A!, records year, month, day, hour, minute and second. #o e*pand
(''

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

this e*ample let me also reference the >Schedule? table, which is where we record the ne*t session for a patient. #his table records both 6A#) and #9!) information. #9!) records hour, minute and second. Our goal here is to either set some date information automatically or help the user minimi;e error at entry. /etHs wor+ the first approach. 2ou tell ase to automatically set date or time information when you are building your table Iwith S./ code5$ First you create the type of date variable you need and then you specify that, as a default, it should receive the current date. -S./ has the following built-in functions for doing this$
CURRENT(TIME fetches the time at the moment this function is being used, CURRENT(DATE fetches the date and CURRENT(TIME TAMP fetches both date and time information.

So your code would loo+ something li+e this$


"Moment of +e,i2t+-" TIME TAMP DE&AULT CURRENT(TIME TAMP!

9n fact, if you analy;e the S./ code that created the tables for this tutorial you will find some columns for date information that use this code. /etHs analy;e this command$ #he string inside the double 0uotes is the name of the column. #hen we assign a #9!)S#A!, data type to it. /ater, we specify that it will ta+e a default value with the instruction >6)FA</#? and finally we call the >"<77)N#R#9!)S#A!,? function, which fetches date and time information from the internal cloc+ of the computer. #he final comma assumes that this is not the last instruction in the creation of the table. 9f it were, =ust omit it. 8hen you run the form wi;ard with a table that includes TIME TAMP! it produces what seems li+e a bo* with a line inside separating it into two fields. #he truth is that these are a time bo* and a date bo* which have been grouped. 8hile the user is filling the form, the TIME TAMP bo* does not show any particular behavior. ut when you come bac+ to a record you have entered, you will see that the TIME TAMP bo* displays date and time information. 9n theory, if you change any information in a form, this change should modify the timestamp to reflect the time that the record has been updated. 9n practice 9 have seen that the TIME TAMP bo* does not change if 9 modify the records and achieving this would re0uire some Kava programming, which is beyond the scope of this tutorial. #he user can do it manually, however. Now read and interpret the following$
"Time of +e,i2t+-" TIME DE&AULT CURRENT(TIME! "Da- of +e,i2t+-" DATE DE&AULT CURRENT(DATE!

('(

AS)

#<#O79A/

#hese instructions would create columns that would automatically insert time and date information, respectively, when a record is created. 9n my e*perience, these instruction also do not update if you modify a record and the user will need to manually ad=ust them, if re0uired. -owever, there are some times when you do not want the date and3or time records modified. #his is particularly true when your database stores historical information. For e*ample, at what moment was one patient assigned to a therapist is such +ind of historical information. 8hen the patient was transferred to another therapist or when he stopped being a client of the clinic are all historical information which you would want to preserve, for administrative reasons. Not having them modified automatically would be a good thing. 8hat you need to do now is prevent the user from modifying them manually. 9n order to accomplish this you have several options. First, you could set 6ate or #imestamp by default and not display the corresponding field in the form. 7emember that this automatic assignment is accomplished through the instructions that created the table, and not displaying the field does not stop the process, it =ust prevents the user from modifying the data. /ater, when you are producing a report, you can retrieve this information. Or you could display the field anyway, but change its property to >7ead only?, and prevent anyone from changing the data. #o try this, build the form for the >Assignment? table. I8hile you are at this, ma+e the labels bigger and easier to read, eliminate the >Assignment? primary +ey field, set the therapist and patient fields to drop-down lists that display both name and surname, provide some useful tool-tips and give this form a descriptive title at the head of it5. Now, in the ,roperties dialog bo* set the >date assigned? te*t bo* to read only. 8ith this form you can assign patients to a therapist with simple point and clic+ and let ase automatically record the time of the assignment. #his is really cool! 6ate and #ime bo*es are customi;able, allowing the display of widgets that aid the input of data . /ets see. 9n the >Assignment? form, ungroup the 6ate bo* from itHs label and call the ,roperties dialog bo* of the date bo*. Study the >Eeneral? tab to see the goodies that it offers. Find the 9pin and <epeat properties Ithey are right ne*t to each other5 and set them to >yes?. Further down you will find a )ropdown property. Also set it to yes. y now you will discover that the date bo* has changed$ it offers two buttons, one on top of the other, with arrows in opposing directions. 9t also offers a bigger bo* with an arrow head pointing down. Save and run the form. 9f you now clic+ on the big arrow head you will see a small calendar for the month appear. 2ou can swiftly change months by clic+ing on the arrows to the sides of the title where the name of the current month is in display. 2ou can also select any day within the month =ust by clic+ing on it. At the bottom you will find two buttons$ One for selecting the current day and one for erasing any date selected previously. Feel free to play with this.
('&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#he nice thing about this small calendar is that the user can enter a date in the pro*imity of the current date chec+ing with a simple glimpse if it falls on a wee+end, in this wee+ or the ne*t, etcetera, minimi;ing errors while entering date information. Some other circumstances in date entry could not need this widget$ 9magine that you need to enter the birth day of a person who was born the (Bth of 6ecember in (D4C. -ow many times do 9 -ave to clic+ on the left arrowhead to reach such dateG 8ell, about (& times for each year separating us from (D4C. For sure, =ust typing (D4C3(&3(B Ior in the corresponding format5 seems lightning fast by comparison. -owever, 9 could not thin+ of a better tool for entering the >ne*t session scheduled? information. So, again, the appropriateness of this tool depends on the conte*t. 7emember that simplicity and ease of use are our primary goals. #he smaller buttons with opposing arrow heads increment or decrement the unit of time selected. 9f you =ust press one of the buttons now, the cursor will appear in the first domain to the left, which holds the month information in the <SA, and will increment or decrement it accordingly. 9f you move your cursor to the day or year section, the arrows will increment or decrement them, respectively. 2ou can do something similar for #ime bo*es, which you can try in the form for the >Schedule? table. 9f you set the 9pin and <epeat properties to yes, the bo* will show the two opposing arrowheads, with which you can increment the time displayed by the bo*. #ime bo*es do not have a )ropdown property. As said before, the #9!)S#A!, bo* is really a grouped 6ate and #ime bo*es. 9f you ungroup them and call their respective ,roperties dialog bo*es, you can activate these widgets. #o finish this e*ercise, set the drop-down calendar as a property of the 16ate case closed1 date bo* in the Assignment? form.

!orms with two or more sub forms.


8e are now going to tac+le a special but not uncommon case of forms$ 8here you need to lin+ three or more tables. #his usually happens when we confront intermediate tables that help with many to many relationships. #hin+ about this$ the intermediate table usually only holds combinations of primary +eys from two different tables, sometimes some e*tra information. ut these combinations ma+e sense only when we can relate them to the tables they derive from. 8e need to handle information from -or for- three tables in one form. Our e*ample records the medication some patients are ta+ing. #he atient table provides the data of a particular patient. #he 1edication table provides information about the medication. #he intermediate atient1edication table records one or more medications for each patient that is ta+ing medication. #he thing is$ how can we have all this information in the same formG y now we +now about sub-forms and the help the wi;ard provides in
('4

AS)

#<#O79A/

setting them up. ut the wi;ard only adds one sub-form per form, which allows us to enter data for a second table only. 8e need to add a third sub-form and we need to do it manually. #his is what we will study ne*t. As we +now, the forms that we have built with the wi;ard are really =ust writer I.odt5 documents over which the wi;ard has added a form. #he wi;ard has been +ind enough to connect the form to a particular table in our database. 9n this sense, the .odt document is =ust li+e a canvas and we can add more forms to it. 8e usually record information from one table to another in the form through the /ist o* control. #he wi;ard is also +ind enough to ma+e the proper connections by as+ing us which cells we want to connect. 9t will now be left to us to place the forms, connect them to the corresponding tables and later interconnect them using one or more list bo*es. /etHs establish some generalities that can help us with this$ )ach form is associated with one table. 9n the case of forms with sub-forms, we have two forms in one .odt document$ #he original or principal form and the new or sub-form. #he table for the principal form establishes a (..n relationship with the table for the sub-form. 8hile the principal form displays a particular record, the sub-forms displays all the records in the associated table that belong to the record in the principal form. So the principal form dictates what records the sub-form must display. #his is why the sub-form is called >sub-form? or >Slave form?. #he principal form is called the >,arent form? or the >!aster form?. #he process of creating a .odt document with several forms is basically li+e this$ 8e insert two or more forms in the writer document. )ach form will be connected to a particular table. #hen we will need to indicate which form will be the master form Ior forms5 and which will be the slave form Ior forms5. )ach form will receive controls that display and allow the recording of information. )ach control is usually connected to one particular field Icolumn5 e*cept for list bo*es that will connect two. #o follow the implementation we will do now, be sure to review the S./ code that created the atient, 1edication and atient1edication tables. ,ay attention to the variable data types of the columns. #hen, ma+e sure you study the way they interconnect by reviewing the <!/ diagram. ,articularly, notice that the ,atient table has a (..n cardinality with the intermediate table and that the !edication table also has a (..n relationship with it. #he intermediate table will want to record the primary +ey of the patient and the primary +ey of the medication. #his table also records data about the dosage assigned and the date such medication3dosage was started and ended. ecause each patient could have more than one medication, it would be better to use a sub-form in the tabular format so we can read several entries at once, very much li+e the sub-form for telephones for the patient form. Finally, notice that the 1edication table stores a description of what the medication does, info that would be useful to display in this form. 8hile following the coming instructions, ta+e some time to study the properties dialog bo*es for forms and controls, so you can readily identify the properties that we need to set. #o learn more about them, donHt forget to study the help files that describe them.

('B

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

/etHs start by using the form design wi;ard to create a new form. Select the ,atient table but then only select the First Name and Surname columns. #hatHs all the information we will need to display from this table. 9n the second step do not chose >Add a Subform? because we are going to create it manually. Finish the process by allowing the editing of all data, pic+ colors of your li+ing and open in edit mode. y now we have about one third of our form. For the ne*t two thirds our new best friend will be the %orm &avigator. 6onHt confuse the Form Navigator with the Navigator. #he Navigator is called by clic+ing on the button that resembles a compass located in the toolbar. #he Form Navigator, by contrast, is located in the Form 6esign toolbar, which is usually found at the bottom of the form you are editing. #he button for the Form Navigator loo+s li+e a compass over a form and is usually the fifth button from the left. 9f you canHt see the Form 6esign toolbar, clic+ on :iewX #oolbarsX Form 6esign. #he Form Navigator displays all the forms associated with the current .odt document. 9f we e*amine the contents of the Form Navigator we will see a folder with the name >Forms? and then a folder with the name >!ain Form?. #his >!ain Form? is associated with a label called >lblFirstName?, a te*t bo* called >t*tFirstName?, a second label called >lblSurname? and a second bo* called >t*tSurname?. 2ou can see that this describes e*actly our current form. 9f you clic+ once on >!ain Form? you will see green handles surround the labels and te*t bo*es in our form. #he rest is =ust the writer I.odt5 document. Obviously, the content of this Form Navigator was written by the wi;ard after accepting our selections. Now, we are going to write directly to it. /etHs start by creating a sub-form. 9n the Form Navigator, right-clic+ on >!ain Form? and from the conte*t menu that appears chose NewXForm. Now a new form has appeared, with the name >Form? or >Standard? that is as a dependency of Ithat is, with a line connected to5 >!ain Form?. 2ou can actually drag this form and place it as an independent form, appearing connected to >Forms? instead. Or you could have created a new form Iwith controls and all5 and only later drag it to become dependent of >!ain Form?. 9t wor+s either way. y creating this dependency, you establish that the form called >Form? or >Standard? is a sub-form of the form called >!ain Form? /etHs review the properties of this form. 7ight clic+ on >Standard? and select >,roperties?. Now, the ,roperties dialog bo* for this new form appears. 2ou can see that a Form has three tabs$ :eneral, )ata and ;vents. #his last tab is reserved for !acro programming, so we will leave it unattended. #he 6ata tab allows us to ma+e all the connections that we need, so we will be spending some time here. #he Eeneral tab is 0uite small and we wonHt need much of its functionality. -owever, you can change the name of the Form here. >Standard? is not very descriptive so change it now to >,at!ed form?. 8e have created a new form but this form is invisible to the user because it has no controls yet. /etHs add the control >#able "ontrol? which has the appearance of a grid. 2ou
('F

AS)

#<#O79A/

can find a panel to your left with the Form "ontrol elements. 9f you donHt see it, go to :iewX#oolbarsXForm "ontrols. "lic+ on the bo* for$ 1ore 2ontrolsD and then select >#able "ontrol?. Now find a good position in your form and place it by dragging and releasing the mouse button. At this moment a Ta $e E$ement 8i;ard appears, re0uesting that we connect this table to a data source. 8e could do this trough the )ata tab in the ,roperties bo* Iand we can change selections there later5 but doing it here is fine too. First, we must select a table. 9n this case we need to connect to the atient1edication table. Select it and then clic+ on ne*t. Now we are re0uested to chose the columns that will be displayed by this #able "ontrol. 8e donHt need the ,atient 96. Kust select !edication 96, Start 6ate, 6osage and )nd 6ate. 9f you now clic+ on finish, you will see the table with column names for the data re0uested. 2ou can also inspect the Form Navigator. 9f things have gone as e*pected, you should see the #able control associated to our new sub-form. Now pay attention to this as things can get a bit confusing$ #he #able "ontrol has a set of properties. 9f the ,roperties dialog bo* is open, you can see them by selecting the #able "ontrol. )ach of the fields inside the table control Ithe columns5 also have properties that are uni0ue to them. 2ou can see them in the ,roperties dialog bo* when you clic+ on the header of the columns. Finally, the form itself also has its own properties, which you can call by clic+ing on the name of the form in the Form Navigator. 6o practice now calling for these properties and study their options until you become familiar with them. 9t feels terrible and is 0uite easy to be loo+ing for properties that belong to the Form when you have really selected the #able "ontrol, for e*ample. So ma+e sure that you can access them at will and can tell them apart. Now is time to ma+e our assignments. 8e have wanted this new form to be a sub-form of the form with the patient data. #hat is why we have placed it as a dependency of it. ecause of this, ase assigns special properties to this form that allow us to lin+ the corresponding primary and foreign +eys so that the sub-form displays appropriate data. /etHs see this$ "lic+ on the sub-form name Ithat is >,at!ed form?5 in the Form Navigator and call its properties dialog bo*. Select the )ata tab. 2ou can read that the first option is >"ontent #ype? and that itHs assigned to #able. 9f you pee+ on the options you will discover that we can also chose a 0uery or a S./ command. #able is selected here as a conse0uence of our earlier interaction with the wi;ard. For the same reason the atient1edication table is selected in the second option$ "ontent. Further down we have the options$ >/in+ master fields? and >/in+ slave fields?. #he 7ink master fields option selects the data field of the table associated to the parent form that is responsible for the synchroni;ation between parent and sub-form. #his is usually the primary +ey and in our e*ample itHs the >96 Number? field from the atient table. #he slave field is the field of the table associated to the sub-form that holds the foreign +ey. 9n this e*ample itHs the >,atient 96? field from the atient1edication table. 2ou can write down these column names or you can clic+ on >...? to the right. A dialog bo* will appear that allows you to find and select both fields simultaneously. Notice that the field for the
@ 7ead the tool-tips. #his bo* is usually number 4rd from the right. #he button for H#able "ontrolH loo+s li+e a table.

('C

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

sub-form is located to the right in the dialog bo*, under the name of the table it derives fromJ and that the field for the master from is offered to the left. Select them now. -ow does the wi;ard +now from which tables to offer options to lin+ master and slave fieldsG ecause we have them connected as shown by the Form Navigator. y the time you clic+ OL, confirming your selections, >!ain form? and >,at!ed form? become form and sub-form, respectively. #his means that when you select one particular patient, the sub-form >,at!ed form? will show you any medications associated solely with the particular patient selected in >!ain form?. /etHs now go to the third leg of this e*ercise$ 9ncluding the >!edication? #able. 8hat we want to achieve is that when we select a medication in the >,at!ed form? we can read some information about that particular medication. #his means that the >,at!ed form? will be the master in relation to a third form we will have to include although it is the slave form in relation to >!ain form?. 7ight clic+ on >,at!ed form? in the form navigator. 9n the conte*t menu that appears select New... and then clic+ on >Form?. A new form appears in the form navigator, with the name >Standard? or >Form?. "all its properties dialog bo*. 9n the :eneral tab, change the name to >!edication info?. Now go to the )ata tab. For >"ontent type? select >#able? and for >"ontent? select the table 1edication. Now s+ip to the part where we lin+ master and slave fields and call the wi;ard Ithe >...? button5. From the >!edication? option select >!edication 96?. 7emember, this is going to be the slave field. From >,atient!edication? select >!edication 96?. #his is going to be the master field. 6onHt get confused by the fact that both columns are called >!edication 96? and instead notice that what we are doing is =oining foreign +ey with primary +ey. 2ou might notice that it is the intermediate table, which provides the foreign +ey, the one lin+ed to the master form and that the 1ed# ication table, which provides a primary +ey, is associated to the slave form. #his is perfectly fine$ 9t is not the primary +ey which defines who gets to be the master form but our need that the >!edication? table provide information selected in the >,at!ed form?. Our third form has no controls yet. Select it now and add a label and a te*t bo*. !a+e them big so that they balance the big #able control if you place them side by side li+e 9 did. 9n the properties dialog bo* name the label >!ed 6escrip? or something li+e this and ma+e it display >!edication 6escription?. Also give it a bac+ground color that will ma+e it stand out I9 chose Erey &'\5. 9n the )ata tab of the #e*t bo* select >6escription? for 6ata field. #his way, every time you pic+ a medication in the ,at!ed form, a description of the chosen medication will be displayed in this bo*. Our last tas+ will be to have a list bo* display medication names Ibut really record primary +ey numbers in the >,at!ed form?5 so that we can assign medications to the chosen patient. Now for a big surprise$ #he #able "ontrol is not really a control but a container of controls that are displayed in tabular form. 9f you select a column header you will see, upon calling the properties dialog bo*, that each column holds a control relevant to the column
('@

AS)

#<#O79A/

data type defined by the S./ code that created the table associated to the form. So, for e*ample, if you select the >6osage? column in the #able control, the header of the properties bo* calls it a te*t bo*, >)nd 6ate? is described as 6ate field and so on. 9f you e*amine their respective )ata tabs, you will see that they were appropriately assigned by the wi;ard to the columns. "onse0uently, >!edication 96? corresponds to an 9nteger. 8e donHt need this and we will change it to a /ist o*. /etHs first review what is it that we want to achieve$ 8e want to record the primary +ey of the medication that is being assigned to the patient in display. Of course, we donHt want to memori;e which primary +ey belongs to which medication. 9nstead, we want the /ist bo* to display the names for each medication and assign the primary +ey of the one we clic+ on. #his also relives us from needing to type the name of the medication and ma+ing a mista+e that can come and haunt us later. #he selection we ma+e will be recorded in the >!edication 96? field of the atient1edication table, which we have associated with the >,at!ed form?. /etHs get started$ First, right clic+ on the >!edication? column header in the #able control and select >7eplace with...? and then chose >/ist o*?. 8ith this column still selected, call the properties dialog bo*. 9n the :eneral tab, change the /abel to >!edication?. Now call the )ata tab. #he )ata tab of the /ist bo* has four properties relevant to the tas+ at hand. #hese are$ 6ata field, #ype of list contents, /ist content and ound field. #he 'ata !ie$d specifies the receiving cell of the table associated with the form. 9n this case, this would be >!edication 96? of atient1edication. ecause this control has already been assigned to such table, this property option has a drop down list that offers you all the available fields. Select it now. Ty)e o! $ist "ontents is as+ing how the items to appear in the /ist bo* Ithe names of the medications5 are to be generated. 8e are going to use some S./ code for this so you can select S./. #he S./ code that we are going to use is no more comple* than the e*amples we have used so far. 9n any event, the ne*t section e*plores the S)/)"# command in depth, if you want to have that information as bac+ground. List "ontent is going to be generated by the following type of S./ statement$ S)/)"# Wfield 'X, Wfield (X F7O! Wselection tableXJ #his instruction displays all the records in >field '? and >field (? of the table >selection table?, which is the table from which we are going to ma+e our selections. 9n our e*ample, it must loo+ li+e this$
ELECT "Name"! "Me.i"ation ID" &ROM "Me.i"ation"%

('A

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

After we have entered it, ase is going to enclose the entire instruction in its own set of double 0uotes. 6onHt be alarmed by this. Note the order in which the S)/)"# statement was designed$ first we call for >Name? Ifield '5 and only secondly do we call for the primary +ey >!emeber 96? Ifield (5. #his is relevant for our last property$ Bound !ie$d specifies how to bind the fields for the list bo*. 8hen you select the option (, field ' will provide data to be displayed in the drop down list while the field ( will provide the data to be entered in the field specified in 6ata field. 9n our e*ample, then, field ' I>Name? from the table 1edication5 will populate the drop down list while field ( I>!edication 96? from the same table 1edication5 will be entered in >!edication 96? of the table associated with this form I atient1edication%. OL, we are ready! /etHs test our form. First, populate the patient table with three or more fictitious patients. #hen populate the medication table. 2ou can use the following$
ame -ibra, -opro, 'a,aEuin Description (reatment of peptic ulcer and irritable colon. (opical fungal skin conditions. Fuinolone antibiotic for lower respiratory infections.

Now call our form. 2ou should see that the >!edication? column has a bo* with an arrow head pointing down. 9f you clic+ on it you should see the medications previously entered for you to select from. After doing so, a description of the medication will appear under >!edication 6escription?. ecause we have set >Start 6ate? to be populated automatically, we should see the date displayed when we return to an entered record. >)nd 6ate? is supposed to be populated by us. #o ma+e this easier for the user, you can open the form in edit mode and call the properties dialog bo* for this column. #hen assign the >6rop down? property to yes. #his will bring out the calendar widget. 8hile you are here, donHt forget to give this form an appropriate title. 8rite a header with$ >,atient !edication Assignment and -istory? or something li+e this.

('D

AS)

#<#O79A/

(('

Chapter
*roducing <ueries.

&

Now we are ready to really ta+e advantage of all the hard wor+ we have done so far. ,roducing and reviewing 0ueries can be truly e*hilarating because this is the moment that all the data you have stored becomes information you can use. #hin+ about this$ 9f you were the director of the psychological clinic we have been using for our e*ample, wouldnHt you find it informative to +now that @B.C \ of all patients with a form of depression are female, that (&.@\ of all the psychiatrists that handle the medication for your patients are in charge of actually @@.C\ of all the patients that receive medication or that &C.A\ of patients at your clinic have been diagnosed a form of post-traumatic stress disorderG 8ell, if you as+ your database appropriately, this is the +ind of information you can e*tract from it. So, now you +now that databases are much more than =ust a way to store names and addresses and later print labels for mailing. #his +ind of information can help you distinguish trends, calculate pro=ections and help you ma+e decisions. For all this wonder to happen, you need to ma+e sure that the information that you e*tract is valid information. #his in turn rests on )ata &ntegrity, the idea that you have stored the right information in the right place and that your system has not changed it for some obscure reason. 2ou have been wor+ing on data integrity from the very beginning of this tutorial$ #he careful design of your tables and relationships -including column attributes and the handling of deletions, compliance to first, second and third normal form, ma+ing sure that the input of data minimi;es entry errors... all this is aimed to ensure data integrity. Now, the tric+ is to learn how to 0uery your database in order to get this information out. 9f you have read other tutorials that describe reports and 0ueries with ase, you +now that a very friendly graphic user interface IE<95 has been developed to help you 0uery your tables. 9n this tutorial, however, we are going to rely on the use of S./ code to create 0ueries. First, because comple* 0ueries are really easier when formulated with S./ code Iand sometimes, itHs the only way to go5. Second, because learning how to ma+e S./ 0ueries is not difficult and, third, because if you learn how to 0uery with S./, the E<9 will be really easy to use. /etHs start with some generalities$ A 0uery always produces a table, that is, the result of your 0uery will always be delivered as columns and rows. )ven if it only has one column, it will still be a table. 7eports are a fancier rendition of a 0uery$ 2ou can include the logo of your company, include the day Idate5 or the person who designed the 0uery and even organi;e the layout of your information. -owever, reports are based on 0ueries. 2ou should +now that the 7eport 6esigner in ase can only use one table at the time as source

AS)

#<#O79A/

for creating your report. #his means that we have to create a 0uery that integrates the information that we need into one table before we can give it a fancy loo+ with a 7eport. 8e have already done something similar when creating compound list bo*es for data entry. Are you readyG /etHs get started.

.<6 ?ueries with 0ase.


2ou might remember that ase offers two places to enter S./ instructions. #his time we are going to use the .uery section. "lic+ on the icon over the te*t >.ueries? in your ase interface, located in the column to the left under the heading >6atabase?. #hree options will appear in the Tasks panel. Select the last one that reads$ 2reate 6uery in 967 view... #he wor+horse for creating 0ueries is the S)/)"# command. #his command is very versatile and powerful and will be the focus of attention for the rest of this section. 9n its most basic form, the S)/)"# command needs only one parameter$ #he table from which you want to e*tract your information, li+e this$
ELECT D &ROM "P2-"hiat+i2t"%A

/etHs analy;e this statement$ First, the statement ends with a semicolon, which is true for all statements in S./ and, therefore, for -S./. 8e saw this when we analy;ed the code for creating tables earlier in this chapterD. #he H]H sign is a wild card, that is, it replaces the actual names of the columns in your table and represents them all. 9f you were to read this statement aloud, you should say something li+e$ HSelect >all columns? from Ythe table$Z ,sychiatristH. #his would produce the entire >,sychiatrist? table. /etHs see if it is true. #ype the statement and then clic+ on the icon that has two papers and a green chec+ where they intersect, which is the >7un .uery? button. 9f you made no typos, then the >,sychiatrist? table should appear. 2ou see, this is all. Not that difficult. 8hat we want to accomplish now is to be able to reduce the data displayed, by filtering it, so that we can e*tract information that is not immediately apparent.
A /oo+ at this code$ ELECT D f+om FP2-"hiat+i2tG%. Notice that the double 0uotation mar+s re0uired by the name of the table are slanted. 9f you introduce code li+e this to the 0uery window ase will throw a synta* error. #he double 0uotation mar+s re0uired by the S./ code must be straight. 9t seems li+e a small thing but they are different characters and +nowing this will spare you a big headache. D -owever, -S./ is 0uite forgiving if you donHt include it. #his might not be true with other database systems. ((&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

/etHs say that you want your assistant to contact all the psychiatrists by phone. She could review record by record and write down their phone numbers or you could ma+e her life easier and swiftly produce a printed list for her. #o do this, instead of selecting all columns in the table, you =ust want the name and phone number. #hen, we should try this$
ELECT "&i+2t Name"! " u+name"! "Phone Numbe+" &ROM "P2-"hiat+i2t"%

Notice that 9 am indicating the names of the three columns that 9 want, inside double 0uotes and separated by commas, and the table from which 9 want them e*tracted. 7un the 0uery. Ah! #his list is easier for the assistant to use. 7emember that if 9 had not used different case si;es and blan+ spaces for the names of columns and tables we would not need to use double 0uotation mar+s. #o ma+e this list clearer to your assistant, we would li+e to ma+e e*plicit that these are the psychiatrists and not patients or the medical doctors. For this we can use an alias. 2ou can see that every first row in the resulting table is appropriately labeled with the name of the columns they represent$ >First Name?, >Surname? etc. ut we can change this and re0uest that the column be referenced with another name. 8e do this with the +ey word >AS?, li+e so$
ELECT "&i+2t Name" A "P2-"hiat+i2t"! " u+name"! "Phone Numbe+" &ROM "P2-"hiat+i2t"%

Note that the command has been fragmented. 8e have done this =ust to ma+e it easier for humans to read. #he S./ window will not pay attention to this and still understand, and e*ecute, the instruction as if it were one long line. 8e should ta+e advantage of this because it ma+es finding mista+es easier when we are composing comple* instructions. 9f you run this 0uery now you will have almost the same output than before, e*cept that the column with the first names will have the heading >,sychiatrist?. #he alias command not only changes the label in the column, it also allows us to reference this column by the new name given. 8e will do this later. 9f you are starting to get the hang of this you could be as+ing$ -ey, can we concatenate the name and surname into one column li+e we did for the list bo*esG #hat would really ma+e the resulting list a very cool one! And, of course, we can. 2ou could =ust copy the instruction we used then, with the concatenation pipes and the strings within simple 0uotes. Kust remember not to run the command by ase if your version of ase is previous to 4.& and use instead the >7un S./ command directly...? button Ithe one that reads S./ with a green tic+ on top5. ut instead of going this way 9 want to introduce the use of functions.

((4

AS)

#<#O79A/

0uiltDin !unctions in 9.<6.


Functions are statements in -S./ code that return a value. !ost of these are understood and used by ase. 8e already +now some$
CURRENT(TIME

returns the time in the cloc+ of your computer at the moment the function

is called. Other functions ta+e one or more parameters. #hin+ of the "OSId5 function$ you give it the parameter HdH Iwhich is supposed to be an angle5 and it will return the cosine of the angle. /etHs imagine that you have a database that has collected some measured angles and you need their cosine. #his would be as easy as$
ELECT "An,le Data" A "An,le H"! CO ("An,le Data"$ A "Co2 H" &ROM "Mea2u+ement2"%

Note that we have given the name of a column as a parameter. Again, because of capitali;ation and spaces, this name is within double 0uotes. #his instruction produces a result table with two columns$ #he angles you stored in the column >Angle 6ata? in the >!easurements? table, and the cosine of those very same angles, and all clearly labeled for ease of use. #here is a great deal of interesting functions available for -S./, and you can find them in their website$ http$33hs0ldb.org3web3hs0l6ocsFrame.html 9f you chec+ their documentation, you will find a function li+e this$ "ON"A# Istring(, string&5 #his one would allow us to concatenate name and surname, li+e this$
ELECT CONCAT(" u+name"! "&i+2t Name"$ A "P2-"hiat+i2t"!

/etHs replace our first line in the previous e*ample with this instruction and run the 0uery. 8hat happensG #his should really ma+e your assistant very happy!
ELECT CONCAT(" u+name"! "&i+2t Name"$ A "Phone Numbe+" &ROM "P2-"hiat+i2t"% "P2-"hiat+i2t"!

2ou will see that there is no space or comma between name and surname in the resulting set$ #hey have =ust been =oined. 9n this respect, the method using the pipes is better. 9t also happens that this function accepts only two parameters$ string( and string&, while the pipes allow you to connect as many clauses as you want. For instance, we could be adding name, middle name and surname. 8e canHt do that with "ON"A# directly.
((B

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

-owever, there is a wor+around to solve this problem that also helps us understand the versatility of functions and how we can use them. /etHs thin+ about the end result that we want$ 8e want the column that displays the names of the psychiatrists to have the following format$ Surname T comma T space T first name. asically this means that we want to =oin the surname with a string containing a comma and a space Iremember that with -S./ strings are enclosed within single 0uotes5 and then =oin this result with the first name. 8e can represent this idea li+e this$
CONCAT(H! "&i+2t Name"$
H

where

means$ CONCAT(" u+name"! 3! 3$ so our statement should loo+ li+e this$

CONCAT(CONCAT(" u+name"! 3! 3$! "&i+2t Name"$

#his could be somewhat difficult to read, with so many 0uote signs and with commas that are both part of the end result and also part of the definition of the function. ut after you analy;e it for a while it ma+es perfect sense. 9t also shows that -S./ will not complain about applying any combination of functions as long as we donHt default the synta* and the data type. #his allows for a very powerful use of functions. "an we use the "ON"A# function instead of the double pipes in building compound list bo*esG 2es, which will also allow us to run the instruction through ase and not s+ipping directly to -S./. #his ma+es for a nice introduction to the versatility of functions. 8e will see later that our ability to synthesi;e data and produce global numbers Ili+e percentages, averages and sums of columns5 are all based on functions. 8e will come bac+ to this when we finish e*ploring the S)/)"# command.

.aving and Calling a <uer$.


At this point you should save your 0uery IFileX Save, or clic+ the icon with the dis+ette5. 2ou will be as+ed a name for this 0uery I9 used >0ry,sy,hone/ist?5. 9f you close the 0uery now and go bac+ to the ase interface, you will see that this 0uery has =oined our list of available 0ueries. 9f you double clic+ on it, the resulting table will appear. ecause this 0uery is e*ecuted when it is called, any additions or deletions to the ,sychiatrist table will be reflected here, that is, the 0uery updates itself every time it is called. Now, that is very useful. Should you want to edit this 0uery, right-clic+ on the name of the 0uery and select >)dit 0uery in S./?. 9f, after you amend your 0uery, you want to +eep both versions, simply save this new 0uery with >Save as...?.

((F

AS)

#<#O79A/

1here/
So far you +now how to select columns for a 0uery, give them an alias if necessary and even run them through a function. #he S)/)"# command also allows you to pic+ a subset of your total data. 2ou do this by imposing a condition with the 8-)7) clause. -S./ will go through all the records chec+ing this condition. 9f the evaluation returns #7<), that record will be displayed with the resulting set. 9f the evaluation of the condition for that record returns FA/S) then the record will be s+ipped. /etHs imagine that you have an interest in listing all the patients of the clinic that are male only. 9n this case, you would use$
ELECT D &ROM "Patient2" </ERE ")en.e+" 1 3Male3%

2ou can see that we are using the wild card, which means that all columns from the >,atient? table will be returned. -owever, only the records that have H!aleH in the >Eender? column will satisfy the condition imposed by the 8-)7) clause and, conse0uently, only those records will be displayed. Notice the use of the e0uality sign >P?. 2ou have all comparison operators at your disposal$ W, X, WP, XP and even WX Ior !P5. 2ou can compare columns to strings, dates and numbers and even to other columns. <sing these operators with numbers is 0uite straightforward. 8hen you compare dates you should +now that an older date is considered >less? that a more recent one, so$ I6ate( W 6ate &5 will return true only if 6ate( is an older date than 6ate&. String comparison can also use these mathematical operators. 9n this case, they represent the position of the letter in the alphabet. HAH is less than HMH, H"H is bigger than HAH. 9n the comparison, if the first letters are e0ual then the second letters are compared, and so on. /etHs say that you want to brea+ down your list of patients so several assistants can wor+ on them simultaneously. /ets say that your first assistant will wor+ with all patients where the surname starts with A, or ". #hen you can produce this list by re0uesting$
ELECT D &ROM "Patient2" </ERE " u+name" = 3D3%

,lease note that in all these e*amples, the name of the tables are enclosed by double 0uotes while the string literals are enclosed by single 0uotes. #his is how S./ tells them apart.

((C

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#he 8-)7) condition accepts e*pressions comparing the value in a column with the N<// value, li+e this$ 8-)7) WcolumnRnameX 9S YNO#Z N<//. #he s0uare brac+ets mean that you can decide to include or not the >Not? statement, depending on what you are loo+ing for$ the record to have a null value or the record NO# to have a null value in the particular attribute. 9n order to find a more comprehensive list of accepted e*pressions, chec+ the documentation provided by the -S./ website at$ http$33hs0ldb.org3web3hs0l6ocsFrame.html Now, you can as+ for e*act matches Iwith the HPH sign5 but also can re0uest similar matches using the /9L) operator, which you use instead of the mathematical operators. ecause you, more or less, +now the kind of matches you are loo+ing for, S./ offers you two other wild cards to help you be more precise with your condition$ #he H\H Ipercent5 sign and the HRH Iunderscore5 sign. #he H\H stands for any character, any number of times Iincluding 4ero times5. #he HRH sign stands for any character, e*actly once. /etHs see this in action$
ELECT D &ROM "Patient2" </ERE " u+name" LI'E 3BI3%

#his will select all names that start with the letter > ?, no matter what characters -or how many characters- appear after the H H. 9f you had a record that only had a H H for surname, it would also be included in the result.
ELECT D &ROM "Patient2" </ERE "A..+e22" LI'E 3IMain t#I3%

#his 0uery will select all records that have H!ain St.H somewhere in the address. Notice that 9 used the H\H sign not only at the end of the string literal to match but also at the beginning. 9f 9 had omitted the first H\H, it would have meant that 9 am loo+ing for records whose address start with H!ain St.H. 9f 9 had omitted the last one, it would have meant that 9 am loo+ing for records that end with H!ain St.H. elieve it or not, these two wild cards are enough for many comple* combinations you could want to match.

Compound ?ueries
2ou can include more conditions to the 8-)7) clause with AN6, O7 and NO# to ma+e more comple* 0ueries. /ets say that you are planning a surprise party for elinda, one of the psychiatrists, and wish to invite all female psychiatrists that practice in your same M9, code Iwhich, for this

((@

AS)

#<#O79A/

e*ample, will be (4'BB5. Of course, elinda should not get an invitation or the surprise would be spoiled. #he list your assistant needs could be composed with the following$
ELECT D &ROM "P2-"hiat+i2t" </ERE ")en.e+" 1 3&emale3 AND "Jip" 1 3:K;LL3 AND NOT "&i+2t Name" 1 3Belin.a3%

Note that this 0uery will e*clude all psychiatrists that have H elindaH as a first name, not only our elinda. #o avoid this you might want to include the surname as part of your 0uery. ut you see where 9 am going$ you can ma+e S)/)"# commands as comple* as your search might re0uire.

'rder in the room% please7


Now, the output table of your 0uery might not show any particular order. #he database went about collecting the records that conform to your conditions and then displayed them in the order they were found. !any times you need to sort the result based on some parameter. 9n order to achieve this, the S)/)"# command accepts an O76)7 2 clause. /etHs say that you want the list for the party ordered alphabetically according to the surname. #hen you should ad the following clause$
ELECT D &ROM "P2-"hiat+i2t" </ERE ")en.e+" 1 3&emale3 AND "Jip" 1 3:K;LL3 AND NOT "&i+2t Name" 1 3Belin.a3 ORDER B* " u+name" A C%

AS" means that you want the list in ascending order Iremember that HAH is less than HMH5. Optionally, O76)7 2 also accepts 6)S" for descending, that is, from more to less Ifrom HMH to HAH5. For e*ample, if you wanted a list with all your therapists, ordered according to years of service, with the more recent additions to the top of the list, you should re0uest$
ELECT D &ROM "The+api2t" ORDER B* "/i+in, .ate" DE C%

Eser defined parameters.


/etHs say that as the director of the clinic you need to find a particular patient whose name was Sanders or Sando; or something li+e that, that was admitted sometime between &''B and &''C. 9nstead of going through &F'' records one by one, you can create a 0uery$

((A

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

ELECT D &ROM "Patient" </ERE " u+name" LI'E 3 anI3 AND "Time of Re,i2t+-" =M7;;NO;:O;:M AND "Time of Re,i2t+-" 0M:7OK:O7;;KM ORDER B* " u+name" A C%

Note that the dates are enclosed by >=? signs, so ase can tell that they are dates. Also note that 9 have used two formats for entering date$ the 9SO format that uses yyyy3mm3dd and the 0o#al format used in the <S that uses mm3dd3yyyy. Of course, 9 should stic+ to using one or the other for consistency but 9 want to show that 9 can use either. 9f you live in )urope or /atin America, your /ocal format would be dd3mm3yyyy. #he local format is set when you chose the /anguage Settings for OpenOffice.org. #his could be a very useful 0uery for finding patients, e*cept that you will have to write it again, changing name and dates, every time you are loo+ing for patients with other parameters. Actually, ase allows you to leave variables in place of your parameters, and as+ you to fill them at the time you run the 0uery, without having to change the code. #his is how it wor+s$ instead of defining the parameters Iin this case, the name and the date limits5 you write the operator followed by a colon Ithe >$? sign5 and then a variable name. 9t will loo+ li+e this$
ELECT D &ROM "Patient" </ERE " u+name" LI'E: patientName AND "Time of Re,i2t+-" =: topDate AND "Time of Re,i2t+-" 0: bottomDate ORDER B* " u+name" A C%

#his is what itHs going to happen when you run the 0uery$ ase will display a small window called >,arameter 9nput?. At the top of the window you will see a label that reads >,arameter? and immediately below it a bo* with the three variables present in this 0uery$ patientName, top6ate and bottom6ate. <nder the bo* you will see another label the reads$ >:alues? and then a single te*t entry bo*. 2ou then enter the parameters for your search in the order they are as+ed for, pressing the )N#)7 +ey after each one. #he window also displays the buttons$ O!, 2ancel and (e*t. 2ou can also enter the values by clic+ing on (e*t after each value and O! after you enter the last one. After that, the matches will appear in table format ordered by surname from A to M. ecause we built our 0uery with the /9L) operator for patient name, you are entitled to use the wild cards >\? and >R? =ust li+e we have been doing so far. #he dates you enter need to be enclosed by >=? signs(', so ase can tell that they are dates. Note that the dates given are e*cluded from the search. For e*ample, you could enter this$
(' 9 have also entered date information without the HOH sign and ase responded without problem.

((D

AS)

#<#O79A/

Smi\ O'(3'(3&''FO O(&34(3&''4O #he 0uery will loo+ for all Surnames of patients that begin with Smi Ili+e Smith or Smithers5 that were admitted in &''B Ibut not in the last day of &''4 or the first day of &''F. For that you would need to include the e0uality sign >P?5. 2ou can run the 0uery again and again, ma+ing new searches without having to amend your S./ code.

<uer$ing more than one table at a time


#he things that you can do by now with the S)/)"# statement are already pretty impressive. 8e ta+e this to the ne*t level when we thin+ about the ability to use the data in more than one table to create a 0uery. 9magine the following circumstance$ 2ou need a list of of all your patients and their psychiatrists. #he first and last name of patients is in one table and the first and last names of the psychiatrists is in another table. -ow do we do thisG First, we need to reference both tables being used in the F7O! clause of the S)/)"# command. Also, we need a convention to ma+e e*plicit what tables are we e*tracting our columns from. Notice that both, the >,atient? table and the >,sychiatrist? table have columns called >First Name? and >Surname?. 9n order to tell them apart we are going to use the following synta* in our 0uery$
<table name>.<column name>

#his is to say that we are going to use the name of the table and the name of the column, separated by a period, to une0uivocally reference the columns that we need. Following the e*ample, we should write$
ELECT "Patient"#"&i+2t Name"! "Patient"#" u+name"! "P2-"hiat+i2t"#"&i+2t Name"! "P2-"hiat+i2t"#" u+name" &ROM "Patient"! "P2-"hiat+i2t"%

,lease note that, because our names for columns and tables use upper and lower case and spaces, we need to enclose them in their own set of double 0uotes. /etHs assume that you have e*actly the following three patients in your database$ Ale* Smith, Kohn Serrato and Fran+ #hrungJ and e*actly the following two psychiatrists$ Amanda ,ere;, 6ebbie 6obson. Also, we +now beforehand that Ale* and Kohn have Amanda as their psychiatrist and Fran+ has 6ebbie. -owever, if we run the above 0uery we get something li+e the table in the ne*t page$
(&'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

!irst $le, $le, Dohn Dohn )rank )rank

ame

.urname *mith *mith *errato *errato (hrung (hrung

!irst $manda ebbie $manda ebbie $manda ebbie

ame

.urname "ere4 obson "ere4 obson "ere4 obson

#his is clearly not what we e*pected. First of all, and if we loo+ carefully, what we really have is a result where every patient is combined with every psychiatrist. 8e have 4 patients and & psychiatrists and a resulting set of & * 4 P C combinations. 8hat we really want is the information of which patient has which psychiatrist. Second, both columns read >First Name? and >Surname? and, with no other clue, we canHt tell which is a patient and which is a psychiatrist. 8ell, this last thing is easy to correct. All we need to do is add an alias for each column. 9n general, when we are wor+ing with more than one table, it is a very good practice to use an alias for each column to avoid these uncertainties. 9t is also more elegant. Now, the first problem is also easy to solve. 9f you remember, each psychiatrist has a primary +ey that appears as a foreign +ey in the patientHs table. 9f you donHt remember, review the S./ code that created the tables and the </! diagram that describes them. 9t is this foreign +ey that tells us which psychiatrist sees which particular patient. So what we want to do is produce a result set where the foreign +ey in the >,atient? table is identical to the primary +ey in the >,sychiatrist? table. Of course, we will use a 8-)7) clause to include this condition. "onse0uently, our S./ code will loo+ li+e this$
ELECT "Patient"#"&i+2t Name" A "Patient Name"! "Patient"#" u+name" A "Patient u+name"! "P2-"hiat+i2t"#"&i+2t Name" A "P2-"hiat+i2t Name"! "P2-"hiat+i2t"#" u+name" A "P2-"hiat+i2t u+name" &ROM "Patient"! "P2-"hiat+i2t" </ERE "Patient"#"P2-"hiat+i2t ID" 1 "P2-"hiat+i2t"#"ID Numbe+"%

)very time we are =oining tables, we will need to match foreign and primary +eys. Otherwise, we will get results li+e the one on the top. Such result, that shows all possible combinations between patient and psychiatrist, is +nown as a 2artesian Eoin. #he 8-)7) clause that help us match +ey numbers transforms this into an &nner Eoin, which gives us the information we want. 8ith an inner =oin we only select the instances that match our conditions. #his is fine most of the times but not always. /etHs imagine that instead of two psychiatrists you have twenty three and that instead of three patients you really have five hundred and twelve. 8hat you donHt +now is that two of your psychiatrists are currently not seeing any pa(&(

AS)

#<#O79A/

tients. 9f you run this inner =oin you will produce a list that associates every psychiatrists that has a patient with her corresponding patients but that e*cludes from the result set all psychiatrists that do not have patients. #his fact will not be obvious with a long list li+e this one and it will ta+e you a serious analysis of the list and memori;ing the names of all the psychiatrists to note the e*clusions. 9t would be much better if the result of our 0uery includes all psychiatrists, even if they donHt match our conditions. #o accomplish this we can use an Outer Eoin. 8ith this =oin we are re0uesting to include all the information in one table even if it is not associated with the corresponding information in the other table. #his result set will display all the psychiatrists but will leave blan+ the cells for patients if they donHt have one. #his would help you +now that there is information that you donHt have, which can be a valuable bit of information in itself. ecause S./, li+e )nglish, is a linear language, you need to write the name of one table first and then the name of the other table second. 9f you want the 0uery to produce the complete information in the table written to the left then you want a 7eft Outer Eoin. 9f you want the 0uery to include all the information from the table written secondly Iwhich would be placed to the right of the first one5 then you want a <ight Outer Eoin. #he synta* for an outer =oin is a bit more comple* at first but you will see that it ma+es complete sense. /etHs produce the 0uery that will include all the psychiatrists even if they do not have a patient in our database -so that this fact becomes obvious!
ELECT "P2-"hiat+i2t"#" u+name" A "P2-"hiat+i2t u+name"! "P2-"hiat+i2t"#"Name" A "P2-"hiat+i2t Name"! "Patient"#" u+name" A "Patient u+name"! "Patient"#"Name" A "Patient Name" &ROM AOP "P2-"hiat+i2t" LE&T OUTER POIN "Patient" ON "P2-"hiat+i2t"#"ID Numbe+" 1 "Patient"#"P2-"hiat+i2t ID"C

Note that the F7O! clause starts with an opening curve brac+et I H^H 5 and HOKH for Outer Koin. #hen we write the name of a table, in this case the sychiatrist table which, because we wrote it first, is placed to the left in the declaration. #hen we write H/)F# O<#)7 KO9NH and then the name of the second table, in this case atient. ecause we are as+ing for a left outer =oin, it is the table to the left I sychiarists5 from which all names and surnames will be e*tracted even if they do not have patients that will match foreign +eys. Note that instead of writing H8-)7)H we use the +eyword HONH to set our matching conditions. Finally, we finish with a closing curve brac+et I H_H 5. 7un this 0uery now. Nice! /etHs now return to our inner =oin in the previous e*ample. Say we also want to include the patientHs phone number as a result of the 0uery. 9f you remember, this data had been placed in its own table because we wanted to record an unspecified amount of phone numbers for the patients. 8hat we will need to do is to include the ,atient ,hone table to the 0uery Iwith the F7O! clause5, use the proper BtableC.BcolumnC synta* and include an AN6 condition to the 8-)7) clause that lin+s the primary +ey of the patient with the patient 96 foreign
(&&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

+ey in the ,hone table. #ry writing such 0uery now. 9f you notice, =oining two tables re0uires one 8-)7) statement. Koining three tables re0uires two 8-)7) statements, connected by an AN6. 2ou can start seeing a pattern here$ Koining four tables will re0uire three statements. 9n general, if you are =oining n tables, you will re0uire n-( =oins. As an e*ercise, do write this 0uery that as+s for a psychiatrist and lists all his3her patients with their respective phone numbers. Intermediate ta $es are no more difficult that what we have done so far. 9f you remember, we use intermediate tables between two tables that have a !any to !any relationship Im..n5. #he use of an intermediate table transforms that cardinality to a manageable (..n. -owever, an intermediate table basically =ust stores several combinations of foreign +eys. 8hat we want to do is to e*tract the meaning from those combinations. 9n our e*ample we have an intermediate table between patient and medication. One patient can use one or several medications. One medication can be used by one or more patients. /etHs say that we want to list all the medications used by a patient. #his is stored in the intermediate table, which holds the patientHs +ey number associated with the +ey numbers of the medications he3she uses. ut this table only lists such combination of +ey numbers. 9n order to +now what they mean, we also need to consult the >,atient? table and the >!edication? table. #o avoid a "artesian =oin, we need to include the appropriate conditions. ecause we are =oining three tables, we +now that we will need two =oins. #o ma+e the result of this 0uery easy to read, we will also include informative aliases. "an you write this 0uery before loo+ing furtherG 2ou should!
ELECT "Patient"#"&i+2t Name" A "Patient Name"! "Patient"#" u+name" A "Patient u+name"! "Me.i"ation"#"Name" A "Me.i"ation"! "Me.i"ation"#"De2"+iption" &ROM "Patient"! "Me.i"ation"! "Patient Me.i"ation" </ERE "Patient Me.i"ation"#"Patient ID" 1 "Patient"#"ID Numbe+" AND "Patient Me.i"ation"#"Me.i"ation ID" 1 "Me.i"ation"#"ID Numbe+" ORDER B* "Patient"#" u+name" A C%

/etHs dress up this 0uery by including other elements reviewed in this part$ /etHs ma+e the 0uery as+ us for the patient for which we want the report and letHs have the output of the name be displayed in one column$
ELECT CONCAT(CONCAT ("Patient"#" u+name"! 3! 3$! "Patient"#"&i+2t Name"$ A "Patient Name"! "Me.i"ation"#"Name" A "Me.i"ation"! "Me.i"ation"#"De2"+iption" &ROM "Patient"! "Me.i"ation"! "Patient Me.i"ation" </ERE "Patient"#"&i+2t Name" LI'E: PatientName AND "Patient"#" u+name" LI'E: Patient u+name AND "Patient Me.i"ation"#"Patient ID" 1 "Patient"#"ID Numbe+" AND "Patient Me.i"ation"#"Me.i"ation ID" 1 "Me.i"ation"#"ID Numbe+" ORDER B* "Patient Name" A C%

(&4

AS)

#<#O79A/

Note that the order clause uses the name given to the column by the alias. 7emember that aliases not only change the heading of the column but also allow us to reference the column with that name in the S./ code. #his is as comple* as our S)/)"# statements will ever get, but by now you should be able to read them, and produce them, with no problem.

Aggregate !unctions:
Aggregate functions also return a value, li+e regular functions, but instead of returning one value for each record evaluated, they return one value that represents the entire collection of evaluated records. #he most clear e*ample of this is the "O<N# function. "O<N# will return the number of records in a specified table. /etHs say that you need to +now how many patients have been recorded in the database. #hen you can run the following instruction$
ELECT COUNT(D$ &ROM FPatient2G%

which, in my computer, returns a result li+e this$

CC;N(!G# =

I ecause 9 only entered data for eight patients5 Now, believe it or not, this result is still a table, albeit with only one column and only one row Iplus the header row with the name of the column5. "ompare this result with the "OSId5 function that we reviewed earlier. 9n that e*ample the parameter HdH stood for a column name and the function returned the cosine for each and every angle recorded in that column. Aggregate functions, on the other hand, return a summary number that represents an aspect of the entire set. 8e will briefly review the following aggregate functions$
COUNT! MIN! TDDE6( AMP# MA4! UM! A6)! 6AR(POP! 6AR( AMP! TDDE6(POP!

9n general, these functions use the following synta*$


ELECT BfunctionC ("Column Name"$ &ROM "Table Name" >###?

where BfunctionC stands for one of the D aggregate functions named above.
(&B

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

/etHs chec+ them out$ ` As sated, "O<N# returns the number of rows in a table. Of course, we can filter this number to obtain a count of subsets. For e*ample, say that you need to +now the number of male patients in the patient table. 9 am sure that you can already anticipate the needed code$
ELECT COUNT(D$ &ROM "Patient2" </ERE ")en.e+"13Male3%

2ou can also change the header row for a more descriptive name of your result with an alias.
ELECT COUNT(D$ A "Numbe+ of Male Patient2" &ROM "Patient2" </ERE ")en.e+"13Male3%

/etHs say that you need to +now the number of uni'ue phone numbers in the ,hone Number table. 8e can imagine that two or more family members that live together share at least the home number, so a simple count instruction will not do$ there will be repeats that are counted. 8e can use the 69S#9N"# 0ualifier to eliminate repeats from a 0uery, li+e this$
ELECT DI TINCT COUNT("Numbe+"$ &ROM "Phone Numbe+"%

9n short, if the 69S#9N"# 0ualifier is included, only one instance of several e0uivalent values is used in the aggregate function. 9f we wanted the contrary, that is, to ma+e sure that we include all instances in our 0uery, we can use the 0ualifier A//. 2ou should +now that the data type of "O<N# is 9nteger, in case that you want to do some +ind of arithmetic operations with it or wish to use this result with a drop-down list. 8e will come bac+ to this. Also note that "O<N# will include rows even if they have null values. For e*ample, if you re0uest the 0uery$
ELECT COUNT(" u+name"$ &ROM "Patient"%

even if you have some records that do not yet have a surname, they will be counted anyway. eing able to obtain the total number of records in a table and the count for subsets of it allow us to determine all +inds of percentages that can describe the entries in our database. 2ou can do this calculation by hand or have ase produce it for you. #he truth is that getting such a number re0uires some wor+ but, once you have it all in place, you can get updated results with a simple double clic+ of a mouse. /etHs say that we want to calculate

(&F

AS)

#<#O79A/

the percentage of patients in the database that have been diagnosed with post traumatic stress disorder I,#S6 for short5. From a conceptual point of view, we first want to calculate the total number of patients in the database. 8e can use a simple S)/)"# "O<N# clause for this. Ne*t we need to calculate the number of patients that have been assigned a diagnosis of ,#S6, for which we include a 8-)7) clause to match the condition. Now we divide the number of ,#S6 patients by the total number of patients, which gives us a decimal number between ;ero and one, and then multiply this number by one hundred to get the percentage, something li+e this$

\ ,#S6 ,atients P

n ptsd * ('' ntotal

Notice that in calculating a percentage, the subset always goes in the numerator Iabove the division line5 and the total always goes in the denominator Ibelow the division line5. One difficulty of this procedure is that we need two S)/)"# clauses to produce this result, one with a 8-)7) clause and one without it. 8e canHt have both S)/)"# instructions in the same 0uery. -ow do we solve thisG 8ell, we produce two 0ueries for each S)/)"# and then we produce a third 0uery that combines the results of the previous 0ueries. -ere is when you could say$ (ah! leave it. &'ll =ust calculate the two 2O3(T9 and then divide their results with my calculator. Fair enough. ut with the three 0ueries in place, in the future, after the database has seen new additions, you =ust call for the third 0uery and you will have an updated percentage of patients diagnosed with ,#S6. #he complete procedure is as follows$ 2ou create the first 0uery for the total number of patients with code li+e$
ELECT COUNT (D$ A "Total Patient2" &ROM "Patient2"%

#hen save the 0uery with a name li+e >0ry#otal ,atients?. Ne*t you create the 0uery for the subset, patients with ,#S6, with code li+e$
ELECT COUNT (D$ A "Total PT D Patient2" &ROM "Patient2" </ERE "Dia,no2i2"13PT D3%

and save it with a name li+e$ >0ry#otal ,#S6?. Now, at the ase interface in the .ueries view, we right clic+ on these 0ueries and select >"reate as view?. 9f you remember, this will create virtual tables with the result of the 0ueries. :irtual, because the tables will be updated reflecting any relevant changes to the
(&C

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

records in the database every time they are called. For the names of the views, leave the same name but delete the H0ryH component of the name. 2ou find these views in the #ables section of the ase interface. For the third 0uery we will call the results from the two previous 0ueries with our dot synta* using first the name of the view and then the name of the column as established by the HASH clause, with code li+e the following$
ELECT ("Total PT D"#"Total PT D Patient2"O"Total Patient2"#"Total Patient2"$D:;; A "Pe+"enta,e of PT D Patient2" &ROM "Total PT D"! "Total Patient2"%

Notice that this S./ code not only selects the columns that we want but also includes arithmetic operations Ithe H3H sign for division, the parentheses and the >]? sign for multiplication5. #his is completely valid code and, in fact, most database engines li+e -S./ allow S)/)"# to modify the output with mathematical operations li+e these. ut alas, if we run this 0uery we get a result of ;ero! 8hat happenedG! 8ell, we +now that the division produces a number between ;ero and one Ibecause the subset is a fraction of the total5 but, if you recall, the "O<N# function produces an 9nteger data type, which means that the result is always rounded down -in this case to ;ero. Mero by one hundred is ;ero. 8hat can we doG One very clever solution is to change the formula, multiplying by one hundred before ma+ing the division, something li+e this$
###("Total PT D"#"Total PT D Patient2"D:;;$O"Total Patient2"#"Total Patient2"

From a mathematical point of view both formulas are e0uivalent and from a practical point of view we avoid being completely rounded down to ;ero. ut this solution is not entirely satisfactory because we still lose all decimal numbers, which can add to produce important error in our calculations((. #he problem is the 9nteger data type of the "O<N# result. #he functions will save us again. 9f you chec+ the -S./ documentation that we have cited you will discover two functions that allow us to change the data type of our result. #hese functions are$
CA T (te+m A t-pe$

converts term to type data type converts term to type data type

CON6ERT (te+m! t-pe$

(( 2ou could multiply by ten thousand to +eep two decimal numbers, but because we do not have a decimal separator Icomma or period5 this solution ma+es reading the result ambiguous.

(&@

AS)

#<#O79A/

#heir descriptions in the documentation suggest that they are e0uivalent in their result and only change in the synta* they use. !aybe this is not complete and there are differences in the way they behave. 8e will only +now this by trying them in different situations and comparing them. For now, 9 will =ust use the "AS# function to achieve my goal, and will assign my results a 7eal data type, li+e this$
CA T ("Column :" A REAL$ O CA T ("Column 7" A REAL$ D :;;

8here$

"olumn ( P "Total PT D"#"Total PT D Patient2" and "olumn & P "Total Patient2"#"Total Patient2"

so the total code of our last 0uery would loo+ li+e this$
ELECT( CA T ("Total PT D"#"Total PT D Patient2" A REAL $ O CA T ( "Total Patient2"#"Total Patient2" A REAL $D :;;$ A "Pe+"enta,e of PT D Patient2" &ROM "Total PT D"! "Total Patient2"%

#his way we will get enough decimal numbers and the proper format in the calculation of the percentages. 7emember that we can change the data types in the last 0uery, li+e in the e*ample above, but could also change them in the 0ueries that produce the partial results that we need. "or the fun of it, create a 'uery that compares the percentages of T9) patients that were active three, two and one year ago with the patients active today. ` !9N and !AV will browse the specified column and will identify the smallest and the biggest number, respectively, of your set. Obviously, these functions apply to numeric data types only. #he resulting number will be of the same data type as the column over which the function operated. ` S<! will do e*actly that$ it will return the sum of all the values in the specified column. #his comes in very handy, for e*ample, when we need to +now the total of sales, earnings or losses that we have tabulated. Again, S<! applies to numeric data types. -S./ will assign a variable type to this result in a way to ensure loss-less results, that is, with a level of precision commensurate to the result of the sum. 8e can describe S<! mathematically. /etHs assume that you have n records Iof numerical data5 in a column, then the S<! of that column returns$ S<! IV5 P * i
i =( n

&ote that SU.> .I& and .A? wi$$ e4"$ude nu$$ va$ues !rom the "a$"u$ation#
(&A

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

` Statistical functions include$ A:E, S#66):R,O,, S#66):RSA!,, :A7R,O, and :A7RSA!,. A:E calculates the average of the numbers in the specified column by calculating the sum of all the records and then dividing that by the total number of records. #o be precise, this function performs the following calculation$ A:E P F P ( F n i=( i
n

#he average is a tool of statistics that allows us to describe a collection of 0uantitative measurements. For e*ample, we cite the average income of the people living in one neighborhood or the average time of reaction to a specific environmental signal. #o fully appreciate how representative that average is of the set it describes, we will also want to +now how close of far apart each particular measurement is from that average. #he standard deviation is an average of the deviation of all the particular measurements from the setHs average(&. A smaller number means that the individual measurements are close to the average, a bigger number means the opposite. Not surprisingly, S#66):R,O, calculates the standard deviation of the numbers in the specified column. "onceptually, S#66):R,O, represents the following formula$

S#66):R,O, P

F i F &
n

-owever, it is more li+ely that the standard deviation is calculated by -S./ using the following formula, which mathematical science has shown to be e0uivalent to the previous one but does not re0uire the computation of the average$

&

& * n

#he average is of the same data type as the column from which itHs calculated. !eanwhile, the standard deviation is always assigned a 6ouble data type, to ensure its precision. S#66):R,O, assumes that the values in the column belong to all the members of the population that we are trying to describe. 9f this is not the case, we say that the measurements belong to a sample Ia subset5 from the population. 9n this case, statistical theory re0uires that we ad=ust the formula to account for this$
(& "omputed using the sum of s0uares of the distance between each measurement and the setHs average.

(&D

AS)

#<#O79A/

S#66):RSA!, P

9P

F i F &
n (

"onceptually, that is the value that S#66):RSA!, will produce, although it is more li+ely that -S./ will compute it using the e0uivalent formula$

* n* n(
&

&

#he :ariance is another measure of variability used in statistics. From a mathematical point of view it corresponds to the s0uare of the standard deviation. :A7R,O, assumes that it describes the entire population, and is defined by$ :A7R,O, P

&

while :A7RSA!, assumes that it is describing a sample from it and, conse0uently, corresponds to$ :A7RSA!, P 9
.

-owever, it is more li+ely that these values are calculated by formulas li+e the ones used by S#66):R,O, and S#66):RSA!,, correspondingly, but without e*tracting the s0uare root. :ariance is also assigned a 6ouble data type by -S./. &ote that none o! these statisti"a$ !un"tions a$$ow !or ALL or 'ISTI&CT /ua$i!iers and that they wi$$ e4"$ude nu$$ va$ues in their "a$"u$ations# /etHs now tac+le a problem that uses statistical functions$ letHs produce a report that calculates the average age Iand the standard deviation, to ma+e sense of this number5 of all women with a diagnosis of depression in our database. "an you imagine the e*citement of a researcher that is hinted on the idea that most women attending for depression significantly belong to the same age3phase in lifeG 9 am sure that you have spotted the need to use the 8-)7) clause to e*tract the group we are interested in$ 8omen with a diagnosis of depression. !ore subtle is the fact that we have not recorded the age of any woman but instead we have their dates of birth. 8hat do we do nowG

(4'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

.ome time functions:


9f you are thin+ing that maybe there is a function for this... you are absolutely right. 9n fact, time calculations seem to be very important in our society Idetermining when to pay dues, when to collect, the calculation of compound interest rates, analysis of last 0uarter, pro=ections for ne*t year, etc.5 so it is not strange that S./ code comes with very mature tools to handle time calculations. 2ou really need to chec+ this out in the website for -S./ that we have cited before. 9n order to obtain the ages of our sample we will need to calculate the difference between their birthdays and todayHs date. "an we do thisG Not only we can, but we can also specify the time unit that better suits our needs$ do you want the result in yearsG 9n monthsG 9n years and monthsG 9n daysG 9n secondsG I2eah, seconds5. For our needs, months seems precise enough. 9f you review the -S./ website at http$33hs0ldb.org3doc3&.'3guide3s0lgeneral-chapt.htmlOs0lgeneralRtypesRops-sect you will see that the code re0uired for this loo+s li+e$
(Qalue: R Qalue7$ =time unit0

8here value( and value& can be columns that hold datetime data, can be constants Ia particular date or time value5, can be the result of a function that provides datetime data, li+e CURRENT(DATE($ and can even be another time interval# #he only condition is that both values are of a comparable nature$ you could not compare a time value Ithat gives hours, minutes and seconds5 with a date value Ithat provides year, month and day5.W#ime unitX options include$ year, month, day, hour, second and year to month which provides the result in years and months. 9n order to get our age data, we try the following snippet of code$
(CURRENT(DATE R "Date of Bi+th"$ MONT/

#his code calls for the "<77)N#R6A#) function, which fetches todayHs date, and subtracts from it the date of birth of the patient, providing the difference in months. Now, this grammar is correct according to the cited documentation. #here is also a 6A#)69FFI5 function. 9t essentially wor+s with the same logic but you write it differently, li+e this$
DATEDI&& (=time unit0! Qalue:! Qalue7$

where value( is the starting date of the interval and value& is the ending date Imost current date5 of the interval. "onse0uently, the code we need would loo+ li+e this$
DATEDI&& (MONT/! "Date of Bi+th"! CURRENT(DATE$

Now, comparing the date of birth with todayHs date ma+es sense only for cases currently active. #o filter this we should include a 8-)7) clause that selects only those patients
(4(

AS)

#<#O79A/

that are female, that have a diagnosis of depression AN6 have an empty >6ate "ase "losed? cell in the Assignment table. For a more general evaluation, we would want to get the age in relation to the >6ate assigned? that we stored in that same table. #hen, the snippet of code could loo+ li+e this$
("Date a22i,ne." R "Date of bi+th"$ MONT/

Or, depending on your version$


DATEDI&& (MONT/! "Date of bi+th"! "Date a22i,ne."$

Now 9 am going to divide this result by (&, which will provide the age in years with a decimal e*tension for the months Iso &@ years and si* months of age will appear as &@.F5 and then 9 will re0uest the calculation of the average and the standard deviation. #he final code could loo+ something li+e this$
ELECT A6)((("A22i,nment"#"Date a22i,ne." S "Patient"#"Date of bi+th"$ MONT/$O:7$! TDDE6(POP((("A22i,nment"#"Date a22i,ne." S "Patient"#"Date of bi+th"$ MONT/$O:7$ &ROM "A22i,nment"! "Patient" </ERE "Patient"#")en.e+" 1 3&emale3 AND "Patient"#"Dia,no2i2" 1 3Dep+e22ion3 AND "Patient"#"ID Numbe+" 1 "A22i,nment"#"Patient ID"%

For completeness, if you want to +now the interval of time between dates in a column and a specific day -that is, a constant-, you can specify the constantHs format and then provide the data. For e*ample, if 9 want to calculate the age Iin years and months5 that all patients had in, say 6ecember (Cth, &''@ then the code would loo+ li+e this$
ELECT ("Date of bi+th" S DATE 37;;NS:7S:93$ *EAR TO MONT/ &ROM "Patient"%

2ou can also wor+ with time and timestamp data types, defining them li+e this$
TIME 3hh:mm:223 TIME TAMP 3----SmmS.. hh:mm:223

As an e*ercise, write the 9;7;2T code that compares the average age $and standard deviation% of men with T9) that were receiv# ing therapy -G years ago, H years ago, I years ago and that are active today.

(4&

Chapter
Creating reports with 0ase.

1'

9f you notice, there is currently no way to print on paper the tables you have created in the >.ueries? view. For this to happen you need to create a report. #he report will provide the same information found in the table created by your 0uery. (4 #he nice thing about a report is that you can customi;e its layout, add a company logo, add info about the date or the person who created the 0uery and things li+e that so that when you print it, these elements will frame the validity of the information provided in your report, will ma+e it easier to read and will also ma+e it loo+ 0uite professional. For our master e*ercise 9 want to create the "linical Summary 7eport. #his is the report where we provide contact and clinical information about a particular patient, his3her medical doctor, psychiatrist if there is one, medication and other data. 9f you now clic+ on >7eport? in the left column of the ase interface, the tas+ bar will offer you the option ><se 8i;ard to "reate 7eport?. #his option is 0uite straightforward$ #he wi;ard will ma+e a series of 0uestions about what table or 0uery you want to use, what fields you want to write, how do you want to group them and what template for layout you want to use. Actually, by now you should be able to understand most of the options offered and 9 recommend that you play with the wi;ard and become familiar with the way it wor+s. For most things, the wi;ard will be =ust the right tool. #he only thing is that the 7eport 8i;ard will always display the result of your 0uery as a table. #his way, the result of the 0uery for the "linical Summary will be displayed as one long row. ecause we are only interested in one particular patient, there will be no other rows to fill the page. 2ou will end with one I0uite long5 row, spanning several pages, but leaving most of the printed page empty. #his is not a satisfactory solution and departs greatly from the layout we did in ,art 99. 6onHt despair. Sun !icrosystems has made available a >7eport uilder? that allows you the fle*ibility of design view in re-organi;ing the layout of your reports. #here is no reason why you should not download it. So go ahead and install it now.(B After you download and install the e*tension you will find that the #as+s menu in the 7eport section offers you a second option$ >"reate 7eport in 6esign :iew?. Kust to get ac0uainted, clic+ on this option to see what we get.
(4 Actually, you can even chose to omit, reorgani;e or summari;e certain items in your 0uery before printing them. (B Although one of the beauties of the e*tensions is the way they integrate with OpenOffice.org so that you can use them straight out of download without having to restart, the integration with the S7 is not so seamless. 9 found that it is better if you 0uit OpenOffice.org and the .uic+starter before you open it. 9n the case of 8indows V, 9Hve had less trouble if 9 simply restart the computer after download.

AS)

#<#O79A/

8ow, 9 bet that this was more than what you bargained for! 6onHt worry, all these options are here to help us. elow all the menus and toolbars there is a page divided in three. #o the left you can see that the top section is the -eader, the middle section is the body of the report, called >6etail? and to the bottom we have the footer. #o the right we have a column with two tabs$ :eneral and )ata. #hey wor+ =ust li+e the ,roperties 6ialog o* that appears while wor+ing with the Forms in 6esign :iew, providing the characteristics of any ob=ects we select and allowing us to customi;e them. -ere is an important tric+$ in the )ata tab of the reportHs properties you find the bo* that allows you to connect the report you are editing with one particular table or 0uery. 9f you select any section of the report, or a particular label or te*t bo*, the ,roperties 6ialog o* and the corresponding tabs change to reflect the properties of that particular ob=ect. 9f you need to go bac+ to the properties that belong to the report then you must clic+ outside of the report, typically, on the gray area below the report layout. /etHs focus on the three sections in the page. 2ou can clic+ on any to activate it. #he tab to the right shows options to customi;e each section. 2ou should read them now to become familiar with them. 9f you donHt see a tab to the right, go to :iewX,roperties, or clic+ on the roperties bo* button Iusually second from the left in the lower row of the toolbars5. #he header section will receive data that you want displayed on the top of every page in the report Igood for titles, dates, company logos and things li+e that5. #he footer is similar, displaying the info at the bottom of every page Igood for page numbers, contact info and the li+e5. #he central part of the page, labeled >6etail? will receive the information from the tables and will repeat itself for every record collected by the 0uery. #his info will appear in #e*t o*es, which we will tag, if needed, with /abels. 2ou will notice the property$ >-eight? followed by some unit in the properties panel. 2ou can change the height of any section by either changing the value here or by dragging the hori;ontal line that separates the two sections. /etHs assume that you want to insert a label. First you select the /abel button I=ust to the right of the ,roperties button5. Now you can clic+ and drag the label bo* anywhere in your form. 9mmediately after, you will see this ob=ectHs properties appear in the column to the right. Find the >/abel? option and write there >Name$? to see the te*t in the label change in your form. /etHs now place a #e*t o* ne*t to our label. 2ou will find the #e*t o* button ne*t to the /abel button. "lic+, place and drag. 2ou will see that in the column to the right there are two tabs this time$ :eneral and )ata. Study them. 9f you e*amine the "ield property in the )ata tab you will see that it is empty. #his is where the connection to a particular field in our table is defined and can be set automatically by the report builder or by you, as we will see later.

(4B

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

9t goes without saying that you should also read a very good reference found here$ http$33wi+i.services.openoffice.org3wi+i3S<NR7eportR uilder36ocumentation

'ur first &eport with 0ase:


efore attempting our more ambitious pro=ect of developing a "linical Summary report, letHs do something simpler, =ust to get the hang of it. For this e*ercise we are going to use both, the 8i;ard 7eport and the Sun 7eport uilder. /ater on, when we tac+le the clinical summary, we will only use the Sun 7eport uilder from beginning to end. -owever, there is nothing wrong with using this dual approach$ the report wi;ard will have us up and running 0uite 0uic+ly and then we can use the 7eport uilder to fine tune our wor+. Our report should produce a list of all patients in our database with their corresponding phone numbers. #his e*ercise should be interesting for a number of reasons$ First, it uses data from two different tables that need to be properly lin+edJ second, we have an un+nown number of phone numbers for each patient$ some patients will have one but others can have two, three or more phone numbers. #his gives our report a degree of unpredictability. /astly, we are going to use the "ON"A# function to create a column that we will name with an alias and then we are going to reference that column with the alias in another part of the S./ for our 0uery. 9t is going to be very interesting and informative to see how do the report wi;ard and the report builder respond under these circumstances. efore advancing further, ma+e sure that you have some entries in the ,atient #able and that you give them differing amounts of phone numbers. 8e should start by coming up with a desirable layout for the report. 9 would li+e it to have a heading that identifies the report clearly, something li+e >,atientHs ,hone Numbers?. 8e should also include the date in which we generated the report so that we +now up to what moment in time this report is valid. 9 also want to number the pages so that 9 +now if one has gone missing. #hen we should have the name of the patients, surname first and separated from the first name by a comma and a space, and ordered alphabetically. 9 want to have the phone numbers underneath the names and in line with a reference to which number this is$ home, office or mobile phone, etc.. Now that 9 am scribbling the layout of this report on a nap+in, 9 reali;e that 9 would also want to include some +ind of graphic, li+e an hori;ontal line, that would help me separate each record, ma+ing it easier to scan. 8e will obviously need the >,hone Number? table, which holds the number and descriptor. ut the names are not located here. For this 9 need the >,atient? table. 8e will need to use two "ON"A# functions to produce the output for the name that we re0uested in the previous paragraph and we will have to name this new column with an alias so we can reference it in our O76)7 2 instruction. 8e are going to need other columns so that we can properly =oin these two tables -mainly primary and foreign +eys, although those columns will not be part of the output. ecause we are =oining two tables we +now that we need only one =oin.

(4F

AS)

#<#O79A/

All right then, can you produce the S./ code for the 0uery that we need before reading furtherG 2ou should!
ELECT CONCAT( CONCAT( "Patient"#" u+name"! 3! 3 $! "Patient"#"&i+2t Name" $ A "Patient Name"! "Phone Numbe+"#"Numbe+"! "Phone Numbe+"#"De2"+iption" &ROM "Patient"! "Phone Numbe+" </ERE "Patient"#"ID Numbe+" 1 "Phone Numbe+"#"Patient ID" ORDER B* "Patient Name" A C%

/etHs produce our 0uery now. "lic+ on the 6ueries button in the ase interface and then clic+ on 2reate 6uery in 967 view.... Now type the S./ code and, =ust to ma+e sure it wor+s, run it Iby clic+ing on the bo* with the green tic+ on top of the two overlapping papers5. 9f every thing goes fine, you should see three columns, one with the header >,atient Name? and the other with the names$ >Number? and >6escription?. #he names should be in the >Surname, First Name? format and ordered alphabetically. #he names should be repeated for every different phone number the patient has. At this moment we need to save the 0uery. 2ou do this by clic+ing on FileXSave or by clic+ing on the dis+ette symbol. 9 used the name 'ry atient hone(umber but hey, that is =ust me and you can use any name you feel comfortable with. 8e are ready to build the report now. "lic+ on the 7eport button on the and then select 3se 5i4ard to 2reate <eport... ase interface

At this moment you will see the 7eport uilder pop up and, over it, the 7eport 8i;ard. #his is fine. #he 7eport uilder provides the ground for our wor+. 2ou will see that all our selections -while using the wi;ard- will be placed, or otherwise affect, the page on the report builder. #he wi;ard is composed of two columns. #he one to the left names si* steps that the wi;ard will wal+ us through and highlights the current step. #he column to the right is wider and holds the options and stores our selections that correspond to each step. #he first thing the wi;ard wants to +now is which table will provide the information and which columns will constitute our report. #he drop-down list under >#ables or .ueries? displays all the available tables and 0ueries in this database. Find the 0uery we =ust built Ithat 9 named 'ry atient hone(umber% and select it. .uite immediately you will see that the bo*es below are populated with the columns that belong to this table. 2ou can select now which columns from this table you want in your report. 8e want them all so clic+ on the >XX? button. INotice that the other columns part of the 0uery do not appear as options here. #his is because they were not really selected. #hey were used by the 8-)7) clause to match the info on the tables but were not called by the S)/)"# command5. "lic+ on >Ne*t?. 6id you notice how the 7eport uilder, in the bac+ground behind the 8i;ard, has been automatically populated with the selections we have made so farG Nice!
(4C

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

9n the second level, the 8i;ard wants to +now what labels to use to name each field. #he wi;ard uses the names of columns provided by the S./ code that either created the tables used or are defined in the code of our 0uery. ecause we too+ the time to enter informative names that use caps and spaces Iand the double 0uotes they need5, the names are actually 0uite appropriate. -owever, and =ust to get a feeling of how this wor+s, change the >6escription? label to >,hone type?. #hen clic+ on >Ne*t?. Again, the 7eport uilder is updated by the 8i;ard. 9n the third step, the 8i;ard needs to +now if we want to use any grouping levels and offers us the names of the columns in our 0uery. /etHs e*plain what this means. 9magine that you have a patient, Stan Smith, that has a home phone number and an office number and a mobile phone and even a pager. 8hen we display this information, we get something li+e this$
*atient ame *mith, *tan *mith, *tan *mith, *tan *mith, *tan Htc. ... umber %&3A:?@=97 A:?@=7%&39 =:&9?37%A@ =9A:?%&37@ ... *hone t$pe .ome Cffice 'obile "ager ...

...repeating the name of the patient for each phone number she3he has. #his is not very satisfactory. 9nstead we would li+e to group this information by name. #his means that the name is displayed only once, followed by all the phone numbers that belong to him. #hat is what this step is offering us. #o re0uest for this we should select atient (ame from the bo* to the left and transfer it to the bo* to the right by clic+ing on the >X? button. 2ou can see that the wi;ard offers us to transfer more columns if we wanted. 9magine that you have a database of movie and video producers from all over the world. 9f you were ma+ing a report of them you could group them by country, for e*ample, and then add a second layer grouping them by specialty. 2ou can notice some buttons to the right of the right bo* that display >@? and >v?. #hese allow you to change the order of precedence. 9f you place the specialty on top of the country then the report would organi;e your producers first by specialty and then by country, and this is not a minor difference! -owever, for our e*ample it is enough that we group our results by patient name only. Select this and clic+ on >Ne*t?. 9f you can pee+ at the 7eport uilder in the bac+ground you will see that, automatically and following our instructions, it placed the patient name on top of the other two fields. 9t also created a new section on the structure of the page, indicated by a blue shade at the left margin called >,atient Name -eader?. #his is a header because it will head a section of multiple results. #his structure is repeated for every record in the patient table. /ater, when we want to create groupings without the help of the wi;ard, we will be loo+ing to place headers li+e this. ecause now we +now what they mean, it will be as simple and more fle*ible.

(4@

AS)

#<#O79A/

Now the 8i;ard wants to +now if we want to give any particular order to the display of our data. "onsistent with the S./ code in the 0uery, the >,atient Name? column appears selected in ascending order, that is, alphabetically. #his is enough to conform the re0uirements of the specification we did earlier. ut now that we are here we can have a little fun and re0uest that the >6escription? field be also ordered. Eo to the drop-down bo* under the >#hen by? label and select >6escription?. Now clic+ on )escending order. #his means that Stan SmithHs number would appear in the order$ ,ager, Office, !obile and -ome. Notice that the 8i;ard gives us up to B levels of sorting. #he levels also denote a hierarchy. 9n our e*ample, the data will be ordered by name first and then by description Iphone type5. 9n the fifth step the wi;ard gives us some options to organi;e the layout of the information in our report. Of course, the options are not many and in this tas+ the 7eport uilder will e*cel, giving us enormous fle*ibility. At this moment 9 will select the >9n bloc+s, levels above? option. Notice that the wi;ard has no options for the footers and headers. #hat is fine$ the 7eport uilder will help us with this. elow, the wi;ard as+s us what orientation we want to give to the page. ecause most of the time the information appears as tables with long rows the default option is >/andscape?, which ma+es plenty of sense. ut in this case we only have three columns and one of them is being used as a header, so the >,ortrait? orientation results in a better use of our paper. Select this option. #he report builder ad=usts immediately and changes the layout of the graphic interface. 6onHt get startled by this. Now clic+ on >Ne*t?. 9n the last step the wi;ard needs to +now three things$ i5 the name we want to give to this report, ii5 whether we want to create a dynamic or a static report and iii5 whether we want to +eep on wor+ing on the layout of the report or if we want to produce it now. For the name of the report, the 8i;ard will offer us the name of the 0uery used to build it. 8e could change it to something li+e$ ,atient ,hone /ist or whatever you find informative. 9n any event, if you used my suggestion for the name of the 0uery, erase the >0ry? prefi* so you donHt get confused. A 9tatic <eport is built with the data in the database at the time the report is created and is not updated when the data is edited. #his could be necessary for information that is time sensitive and that you are interested in trac+ing, allowing you something li+e ta+ing a photo of the data at a moment in time. 9n contrast, a )ynamic <e# port acts as a template of a report, rebuilding itself every time itHs called and reflecting any editions to the database. #his is necessary when you need the reports to always be up to date. At this time select )ynamic <eport. 8e could go to fine tune the report and select the >!odify report layout? option but instead 9 am curious about the result so far so 9 am going to as+ for the 8i;ard to create the report now. 6o the same. #A6AAA-! -ere we are$ Our first report! #his appears in a viewer as a .rpt document which is 7ead-Only. Now we have icons that allow us to print it directly or e*port it as a ,6F document. #his is very cool!

(4A

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#he information is 0uite clear. 9 see that the wi;ard included a hori;ontal line to separate the patient name header from the numbers and this helps to ma+e the report easier to browse. 9 li+e this. #he font chosen is a Sans Serif, which loo+s modern and is easy to read in a tabular conte*t. Fine too. After initial happiness, however, 9 begin to notice several things 9 would li+e to change. First, we need a header with urgency. Only because 9 =ust created this piece of paper 9 understand what it is but give me a couple of wee+s and 9 will have to scan it for several seconds before 9 remember what is this report about. #hen, 9 see than the label >,atient Name? is completely redundant. Actually, all labels are redundant in this report. #his is because we donHt have many categories and the information is 0uite self e*planatory. Also the boldness of the labels attracts a lot of attention. 9n reality 9 would li+e the patient names to be in bold, so it can help me structure the layout of the page. Finally, 9 would also li+e the distance between phone numbers to be less, as 9 feel that it ma+es it more difficult to perceive the structure of the page and also ma+es me feel that we are wasting too much paper. #he font si;e could also be smaller, allowing more records per page and ma+ing the page easier to read. -owever, 9 do admit that the actual font si;e also fills the page 0uite nicely, providing with an harmonious balance of in+ and white. Of course, this fine-tuning is done with the 7eport uilder. /etHs go. Start by closing the viewer and then go to the 7eport section of the ase interface. Find your report and right clic+ on it. #hen select the option >)dit?. #he 7eport builder opens. First of all, ma+e sure that you have the ,roperties panel on Iusually found to the right of the screen5. !ost of the times it appears automatically. 9f not, you can clic+ on :iewX,roperties or you can clic+ on the second button at the lower level of the toolbar and to the leftJ the one whose tooltip indicates as >,roperties? and that displays several form controls. /etHs start by providing a title to the report. First select the page header and then clic+ on >/abel Field? Ithe button to the right of the ,roperties button5. 8hile on the header, your cursor changes to the shape of a cross and a small bo* to the right. <se this to clic+ and drag a rectangle. 9mmediately, the ,roperties panel displays its properties. #his label ob=ect only has a :eneral tab, but here we find all we need. First, enter into the 7abel attribute the te*t that you want. 9 used >,atient ,hone "ontact 9nformation?. #he default font si;e is not very impressive for a title. "lic+ on the >...? button ne*t to >Font?J this calls the Font dialog bo*. /eave the defaults but change the si;e to &&. 2ou will notice that the te*t is now bigger than the boundaries of the bo* that holds the te*t. /eft-clic+ on it to reveal the green bo*es delimiting the boundaries of the te*t bo* and drag them until the entire caption can be read. Actually, drag the left boundary of the bo* all the way to the left margin of the page and drag the right boundary to the right margin of the page. Now loo+ in the ,roperties panel for the >Alignment? attribute and select >"enter?. #his ensures that the title will be centered. Now, =ust to show you the possibilities, call again for the

(4D

AS)

#<#O79A/

>Font? dialog bo* and select the >Font )ffects? tab. "lic+ on the ><nderlining? dropdown bo* and clic+ on >6ouble?. Now select the >,atient Name? label and delete it. Actually, delete all the labels. #he rectangles that remain are #e*t o*es. 2ou can notice that the te*t bo* for the patient name field is somewhat to the right of the page. Select it by left-clic+ing on it and positioning your cursor over the bo*. #he cursor will change to a blac+ cross with arrow heads. 2ou can now drag the bo* to the left. <se the guide lines that appear to align it with the bo* underneath it. #he #e*t bo*es donHt really need to be so long. 2ou can ma+e them smaller by positioning the cursor on top of the green bo*es. At that moment, your cursor changes to a white double-headed arrow with which you can change the si;e of the bo*es in any direction. 7eorgani;e them to your own taste. /etHs ma+e sure that the patient name will be displayed in bold. Select this te*t bo* and clic+ on the >...? button of the font properties. 2ou can see that you can add any effect that you could li+e, even color the field. For this e*ercise, clic+ on the >Font? tab and select > old? under typeface. )*it by selecting >OL?. #o arrange the distance between the phone numbers we need to select the )etail section under the ,atient Name heading. 9f you chec+ the Eeneral tab of the ,roperties panel after ma+ing the selection you will see the -eight property, which, in my computer, is set to '.F'?. 2ou can change the height here, by changing the number in the bo*, or you can drag the gray line that separates the detail from the page footer. #ry this now and see how the height data in the ,roperties bo* is automatically updated. I!a+e sure that no other ob=ect is selected.5 #o ma+e the detail slimmer 9 found that 9 also needed to ad=ust the position of the bo*es for number and phone type, moving them closer to the header I9 also gave them some indentation by moving them to the right5 and finally left the detail with a height of '.B'?. /etHs finish this by including the date the report is created and folios to number the page. 7emember that we made this a dynamic form, so we need to update this data each time the report is called. 9f we used a label to write down the date, we would need to change it every time, which is not helpful. 9n contrast, the 7eport uilder offers us an automatic option$ For this, activate the page header by clic+ing on it. #hen select on &nsert in the !enu bar and clic+ on )ate and Time... . At this moment the 6ate and #ime dialog bo* appears. #he dialog bo* shows two chec+ bo*es so you can decide if you want to include the time, the date or both. 6rop-down bo*es allow you to chose the format in which you want them displayed. 9 donHt want the time in the report, only the date, so 9 unchec+ed the time bo*. #hen 9 selected the format that 9 fancied best. 6o the same. After clic+ing on >OL? a bo* appeared on the page header at the upper-left margin. Now you can drag it, re-si;e it and, in general, change any attributes permitted by the ,roperties dialog bo*. 9 moved mine to the right and under the report title. 9 also added a label to the left of this bo* wit the caption$ >7eport created on$?. #his way 9 ma+e obvious the

(B'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

meaning of the date. Although not completely necessary, it provides a good e*cuse to practice your new s+ills. Eo ahead and do the same. Finally, letHs add folios to our page. Select &nsert and then clic+ on age (umbers... . #he corresponding dialog bo* appears. First, select a format that you li+e I9 pic+ed n of m5. For the position, indicate that you want this on the footer. Finally, select a left alignment and clic+ on >OL?. A bo* will appear on the footer. 8ith this, 9 believe that our wor+ matches the specifications we previously did for this report 0uite well! /etHs see our masterpiece in action. /ets first save it, =ust in case we have a crash Iit could happen5 by clic+ing on the blue dis+ette or clic+ing on FileXSave. Now find a button in the first row of the toolbar with a page and a green arrow pointing to it from the left. #his is the )*ecute 7eport button. Alternatively, you can find it under )ditX)*ecute 7eport or you can activate this function directly with "trlT). 8hat do you thin+G Fell free to e*periment and analy;e the attributes in the ,roperties dialog panel for the different ob=ects. e curious about the menus and the functions of the buttons. ,lay with them. #his is the very best way to learn! Now that we have the basics. /etHs produce our "linic Summary report.

.teps in designing a report:


9n general, when you are producing a report, you should follow more or less the following se0uence$ (. Analy;e the reportHs re0uirements and decide on the overall layout. &. Select needed tables and columns. 4. "ompose 0uery Iinclude functions5. B. uild the report. 9f you notice, this is e*actly the same procedure we did while developing our first e*ample. Not surprisingly, the first two steps can be carried away with paper and a pencil. 9n composing the 0uery you need to ma+e sure that you are using the S./ language properly, for which the earlier part of this tutorial should come in handy. Only the fourth step is done sitting in front of the 7eport uilder. So you see$ plan before e*ecuting.

Creating a report with &eport 0uilder Bthat is not in tabular formC.


#he first thing that we need for our "linical Summary is to design the layout for our report. 9 am going to base this report on the draft presented in part 99. Note that this report is divided into two sections$ ,atient 9nformation and "linical 9nformation. #he first section displays information that we are mostly going to find in the ,atientHs table, so selecting
(B(

AS)

#<#O79A/

this should be 0uite straightforward. #he second section is a bit more tric+y as it combines information form several tables Iseven, actually!5. -owever, this should not be difficult for us. According to our draft, if the case is still active then we will want to write >Open "ase? where the >6ate of #ermination? goes. #his should be fun and we will tac+le it when we wor+ with the report builder later on. /etHs first focus on the challenges facing the S./ code for the 0uery$ Note that we have two distinct sections that would re0uire grouping$ the phone numbers and the medication, both of which can display un+nown and differing amounts of information. /etHs focus on these for a moment. Of course, we want to display all available phone numbers and all corresponding medications, the only condition is that they belong to the selected patient. Note that there are no conditions lin+ing them to each other, they both relate only -and independently- to the selected patient. ecause of this independence we are going to find that our result set Ithe data organi;ed in tabular form selected by our S./ code5 will appear as a "artesian =oin with a number of rows e0ual to the number of phone numbers times the number of medications that the particular patient has. oth the wi;ard and the report builder allow us to nest our groupings but what we really want is two separate and independent groups. #his could be solved if we could compose two 0ueries that produce two result sets that we then display in the same page. <nfortunately, neither the wi;ard nor the report builder allow us to wor+ with more than one result set per report. <ntil this changes our only solution is to produce two 0ueries that will be printed independently. 9 can divide my desired report into two result sets in several ways. For e*ample the >,atient 9nformation? could be one result set and the >"linical 9nformation? could be the second one. Or 9 could ma+e all the information in the >,atient 9nformation? and all the information in the >"linical 9nformation? up to the >medication history? be in one result set and have the >medication history? alone as the second result set. No matter how 9 divide it, however, this report will always be at least two pages Ione for each result set5 because each page will be a different report file. 9 can call each section a >logical page? even if in theory they could be longer than one physical page. As long as we are being creative, we can thin+ of other possible solutions. One could be to limit the number of phone numbers we display so that we donHt need to do a grouping around them and we reserve the grouping for the medication history. -owever, this would mean losing some information. 9t could also result in empty records if the patient we want a report from does not have the phone number we have decided to include. 8e could use a /9L) operator in order to be as+ed for the number we +now beforehand the patient will have, but this will render the production of this report less automatic. 8e could also thin+ about e*cluding the phone information from this report completely Iin the understanding that the medication history is essential in this report5. As you can see, not being able to include two or more result sets in one report creates some limitations. 9n the future, if you see yourself facing such a problem you might be considering options similar to those outlined here. 9n any event, we can thin+ that one beefy report, with several parts that analy;e comple* relationships of data could be composed of several 7eport type files, that is, be made up of several logical pages.
(B&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

9n this e*ample 9 will do one S)/)"# for the ,ersonal 9nformation and another one for the "linical 9nformation. 2ou will notice that they are basically identical in form so 9 will guide you through the first report and you will do the ne*t one as homewor+. /etHs get started. Anal$Ae the report)s re?uirements and decide on the overall la$out. Overall, the header of the report should include the name of the clinic and maybe a logo. ecause this header will appear for every page in the report and because this report displays data related to only one entry Ithe particular patient5 9 find that it ma+es sense that 9 also include the name of the patient in the header, =ust in case the report re0uires more than one page. #he footer could have the page number, the date the report was created and maybe a disclaimer about confidentiality and contact data for the clinic. Again, because this report displays data for only one entry -as opposed to most reports that would display data for several records where a tabular format is better suited- 9 will prefer a portrait orientation for it. .elect needed tables and columns. #he result set for ,atient 9nformation will basically include information stored in the ,atient #able and the ,hone Number table. 9f you analy;e the "linical Summary report drafted in part 99 you will see that the data re0uired by the "linical 9nformation is scattered among the ,atient #able, the Assignment #able, the #herapist #able, the !6 #able, the ,sychiatrist #able, the !edication #able and the ,atient3!edication #able. ecause we donHt want to re-write the code every time we need a particular report, we will use the >/i+e? operator with the parameters First Name AN6 Surname. 2ou should be able to produce the re0uired S./ code. See if yours loo+ li+e my versions. Compose ?uer$. S./ for ,atient 9nformation$
ELECT CONCAT(CONCAT("Patient"#"&i+2t Name"! 3 3$! "Patient"#" u+name"$ "Patient Name"! "Patient"#"Date of Bi+th"! "Patient"#")en.e+"! "Patient"#" t+eet an. numbe+"! "Patient"#"Cit-"! "Patient"#" tate"! "Patient"#"Po2tal "o.e"! "Phone Numbe+"#"Numbe+"! "Phone Numbe+"#"De2"+iption" &ROM "Patient"! "Phone Numbe+" </ERE "Patient"#"&i+2t Name" LI'E: PatientName AND "Patient"#" u+name" LI'E: Patient u+name AND "Patient"#"ID Numbe+" 1 "Phone Numbe+"#"Patient ID"% A

(B4

AS)

#<#O79A/

-ow was thatG Notice how 9 have changed the format in which 9 want the patientHs name because 9 want to conform as close as possible to the specification for this report. 8hen you run this 0uery, ase will as+ you for the name and surname of the patient you want and then will display all the information that our report as+s for. Not bad. Now letHs wor+ on the "linical 9nformation. 8e +now that we will need information from @ tables and therefore we will need C =oins. /etHs start selecting$ S./ for "linical 9nformation$
ELECT CONCAT( CONCAT( "Patient"#"&i+2t Name"! 3 3 $! "Patient"#" u+name" $ A "Patient Name"! "Patient"#"Time of +e,i2t+-" A "Date of a.mi22ion"! "Patient"#"Dia,no2i2"! CONCAT(CONCAT("P2-"hiat+i2t"#"&i+2t Name"! 3 3$! "P2-"hiat+i2t"#" u+name"$ A "P2-"hiat+i2t"! "P2-"hiat+i2t"#"Phone Numbe+" A "P2- Phone"! CONCAT(CONCAT("Me.i"al Do"to+"#"&i+2t Name"! 3 3$! "Me.i"al Do"to+"#" u+name"$ A "/ea. Do"to+"! "Me.i"al Do"to+"#"Phone Numbe+" A "MD Phone"! CONCAT(CONCAT("The+api2t"#"&i+2t Name"! 3 3$! "The+api2t"#" u+name"$ A "The+api2t"! "A22i,nment"#"Date "a2e "lo2e." A "Date of te+mination"! "Me.i"ation"#"Name" A "Me.i"ation"! "Patient Me.i"ation"#"Do2a,e"! "Patient Me.i"ation"#" ta+t .ate" A "Me. 2ta+t .ate"! "Patient Me.i"ation"#"En. .ate" A "Me. en. .ate" &ROM "Patient"! "P2-"hiat+i2t"! "The+api2t"! "A22i,nment"! "Me.i"al Do"to+"! "Me.i"ation"! "Patient Me.i"ation" </ERE "Patient"#"&i+2t Name" LI'E: PatientName AND "Patient"#" u+name" LI'E: Patient u+name AND "Patient"#"P2-"hiat+i2t ID" 1 "P2-"hiat+i2t"#"ID Numbe+" AND "Patient"#"Me.i"al Do"to+ ID" 1 "Me.i"al Do"to+"#"ID Numbe+" AND "Patient"#"ID Numbe+" 1 "A22i,nment"#"Patient ID" AND "A22i,nment"#"The+api2t ID" 1 "The+api2t"#"ID Numbe+" AND "Patient"#"ID Numbe+" 1 "Patient Me.i"ation"#"Patient ID" AND "Patient Me.i"ation"#"Me.i"ation ID" 1 "Me.i"ation"#"Me.i"ation ID"%

8ow! .uite long S./ code. 9s this what you had arrived toG -ere, again, ase will first as+ you for the name and surname of the patient for which you want the "linical Summary and then will produce the report. 8e now have the 0ueries for the patient information and the clinical information of our "linical Summary report. ecause reports can include the information from only one result set IS./ 0uery or table5 each page will be its own report. 8hen the time comes that the clinic needs a clinical summary on one of its patients, they are going to need to produce both reports Iproviding the same name and surname each time5, print the pages and staple them. A note on SELECT /ueries that use intermediate ta $es: All intermediate tables must be included in the F7O! component of a 0uery, even if their columns are not selected for display. #his is not obvious in the S./ code of the previous e*ample because we are
(BB

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

selecting 6A#) information stored in the >,atient !edication? table and therefore it could loo+ li+e we are including this table for that reason(F. Now that we have our 0ueries ready, lets create our reports using the 7eport uilder. #his should be step four of our little process of producing a report but because we will go into the S<N report uilder with some depth, we will ma+e it a section of its own.

Esing the .E

&eport 0uilder.

9n principle, the S<N 7eport uilder IS7 for short5 is all about giving you ma*imum fle*ibility when it comes to present your data. Not only can you chose not to organi;e your information in tabular format Irows and columns5 and instead try other layouts but you can also display graphics, collect, process and display information from your result set Ithe table or 0uery you are basing your report on5 according to conditions decided by you and even organi;e your data in charts of several +inds. Of course, all this fle*ibility and power means that you need to apply more +nowledge. <nfortunately, at the time of the writing of this tutorial the information on how to use the S7 is rather cryptic and sparse. 9 really hope that this will change in the future. Also, there are bugs in the way the S7 and ase interact which means that things not always happen as planned. 6espite these caveats, having and using the Sun 7eport uilder pays off every time in proportion to the e*tra effort it re0uests. .E &eport 0uilder overview.

#he S7 wor+s with basically the following elements$ a5 #he report layout, organi;ed in sections, b5 /abels to print static te*t li+e titles or tags and c5 #e*t bo*es that will display the data produced by a 0uery or a table. !ost of the buttons in the S7 interface are there to help you display, position, format or si;e these elements. a, The re)ort $ayout is organi<ed in se"tions. <pon opening, the layout offers three sections$ ,age -eader, 6etail and ,age Footer. #he ,age -eader holds information that will appear at the top of every page in your report. -ere you might want to include information li+e the name of the report, the company that has produced it, the date in which it was produced and other data that frames the validity of the information presented and that you need repeated at the head of each page. #he 6etail is the area where all the rows collected by your 0uery or that belong to the table used for the report will appear. -ere is where you organi;e the te*t bo*es that represent column data and the labels that tag them. #he ,age Footer is a section that appears at the bottom of every page where you can add more information about the report, li+e a disclaimer, the name of the author of the report or the page number, for e*ample. 2ou can ad=ust how much from your physical page will be ta+en by these sections by ad=usting their lengths. A ruler to the left is offered for measuring. 2ou can see to the left of the ruler that there is a colored area that designates each section. 8hen you clic+ on one to wor+ with it, a white frame appears indicating

(F See the section >.uerying more than one table at a time? and the note on intermediate tables in chapter D.

(BF

AS)

#<#O79A/

that the section is active. At the same time the ,roperties dialog bo* changes to reflect the options available to the section selected. #ry this now. Should you not want to have a page header and footer you can go to )dit and clic+ on 6elete ,age -ead3 Footer. #here are more sections available. Kust below this option in the )dit menu you can find the 9nsert 7eport -eader3 Footer. #his header will display information that will only appear in the first page of the report and will not be repeated at the head of the following pages. /i+ewise, the 7eport Footer will display information at the very end of the report, in the last page, although not necessarily after the page footer. 2ou can further customi;e the way these headers and footers appear by modifying the options that appear in the :eneral tab of the reportHs properties dialog bo*. y the way, 9n order to call the reportHs properties dialog bo* you must clic+ on the gray area below the reportHs layout, deselecting whatever section, label or te*t bo* was active at that moment. Finally there are headers and footers available to Eroups. 8e form groups when we as+ the report to associate a number of records to one attribute. 9n our first e*ample we grouped phone numbers around the >Name of ,atient? so that the name of the patient appeared only once and, below, we had all the phone numbers that belonged to the named person. 8e will do something similar in this e*ample Ibut without the aid of the report wi;ard5. /ater on we will see how Eroup footers can become very useful. #o display headers and footers for groups clic+ on :iewXSorting and Erouping or clic+ on the tenth icon from the left at the first toolbar row(C, the one that loo+s li+e a page with nested lists Iyou can also use the +ey command$ "trl.TE5. #he Sorting and Erouping dialog bo* appears, which offers the options to have the header or footer visible, how to sort the results and whether to force the elements together in the same page or display some in the ne*t page if there is overflow. , The ne4t e$ement is the La e$ . #he S7 will create many labels for you automatically, particularly those based on the names of the attributes as they have been assigned by the S./ code. Any written tags that you might need are written with labels. #o place a label you clic+ on the third icon that appears in the second toolbar row and that displays >A0C?. #he tool-tip for this button reads$ >/abel Field?. 2our mouse cursor changes to reflect your selection. Now you can drag and drop a label of any si;e on any section of your report. #he labelHs ,roperties dialog bo* will appear. 6o this now and study the properties offered. 2ou can see that labels only have a :eneral tab and that the properties are 0uite self e*planatory. 8ith Font you can change si;e, color and other attributes by clic+ing on the button with the ellipsis Ithose three dots5. ", %ina$$y we have the te4t o4es. #hey represent where the data for the attribute they are connected to will appear. !ostly, the te*t bo*es will be created automatically by the S7 when you are inserting the fields your report will use. 2ou can select them to change their properties Iincluding dimensions5 or relocate them. #he other way to introduce a
(C According to the default configuration of the S7 interface. All toolbars can be relocated, left floating or even be closed at your convenience.

(BC

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

te*t bo* is by clic+ing the fourth icon at the second toolbar row, the one that shows the letters >A0C? enclosed by a bo* and whose tool-tip reads >#e*t o*?. After you clic+ on the icon the mouse cursor will change to reflect your selection. Now you can drag and drop the te*t bo* wherever you want it. "reate a te*t bo* now so that you can study itHs properties dialog bo*. 2ou can see that, unli+e labels, te*t bo*es have a )ata tab in addition to the :eneral tab. #hrough the )ata tab you can associate the te*t bo* with a particular field. #e*t bo*es and labels have a rectangular limit surrounding them that becomes visible when you select them than+s to small green s0uares. #heir presence indicates that the ob=ect has been selected, that the current display of the ,roperties dialog bo* belongs to such ob=ect, that you can relocate it and that you can drag and modify the dimensions of the ob=ect. ,lease note that the S7 will never allow you to overlap two ob=ects. 9f you need to get them closer, you are going to have to reduce their dimensions. Note that a label or te*t bo* too small could result in partial display of your information or even its complete omission from the final result. 0uilding a report with the .&0. Now that we +now the basics of the S7 , letHs build our report. For this e*ample we are going to produce the "linical 9nformation report. #ypically, when you open the S7 a small bo* with names in it pops out. #his is the Add Field dialog bo* and the names included belong to the attributes3columns of the selected 0uery or table. Start by right-clic+ing once on the gray area bellow the reportHs wor+ing area to ma+e sure you deselect any ob=ect and can access the reportHs properties dialog bo*. Eo to the )ata tab and ma+e sure that the >"ontent #ype? states >.uery?. ellow it ma+e sure that the >"ontent? bo* has the name of the 0uery you gave to the "linical 9nformation. 9f you clic+ on the bo*, a drop down menu will offer you all the 0ueries you have composed for this database. Select the one we need. After you hit )nter or ta+e focus out of this bo*, the Add Field dialog bo* will display the name of all the attributes selected by our S./ code. For this e*ercise we will only need the page header and footer and the detail area. !a+e sure no other sections are present. According to the design decisions we made earlier for this report, we want the name of the patient to be repeated in every page in the improbable but plausible case that a long history of medication use re0uires the printing of more than one page. #his means that we are going to want the name of the patient to appear in the page header of this report. First, clic+ on the ,age -eader section. 2ou will see that it becomes selected and the properties dialog bo* changes. Now either right clic+ twice on >,atient Name? in the Add Filed dialog bo* O7 clic+ =ust once and then clic+ on the >9nsert? button once it becomes highlighted. 2ou can see that the S7 places a label and a te*t bo* in the upper margin of the
(B@

AS)

#<#O79A/

header section for the ,atientHs name. 9 recommend that you now relocate it to the bottom of this area. 9f you place the mouse cursor inside of the area defined by the green s0uares it changes to a cross with arrow heads. 2ou can now clic+ and drag it with the mouse or move it with the arrow +eys in your +eyboard. Notice hori;ontal and vertical guide lines that help you position these ob=ects. 9f you deselect these ob=ects and select them again, only one of the pair becomes selected, either the label or the te*t bo*, depending on which one you made the clic+. Now you can access its properties and modify it to your hearts content. 9f you want to re-select them as a group, you first select one by right clic+ing on it and then clic+ on the second while holding down the Shift +ey in your +eyboard. Select the label. 9n the dialog properties bo* you can change the content in the second row Iappropriately called >/abel?5 #he caption is 0uite informative but 9 want to add a colon. 6o this now and hit )nter. 2ou will see the label update in the report. Now clic+ on the ellipsis button of the Font property and change the typeface to bold. 2ou can see that the te*t bo* where the name will appear is 0uite distant from the colon. 9 want them to be closer. ,osition your mouse cursor on top of the right green s0uare. #his time the cursor changes to a hori;ontal line with arrow heads. Now you can clic+ and drag a new width for this label. Notice how the 8idth attribute in the properties dialog bo* changes correspondingly. Now clic+ on the te*t bo* for the patientHs name. 6rag it closer to the label and then change the typeface to bold as well. Also, ta+e some time to study the )ata tab for a moment. 2ou can see that only two of four bo*es appear active at the moment. #he first one states that the 6ata Field #ype is either a Filed or a Formula. 9n this case it is e*actly a field. Further down the 6ata Field correctly connects this bo* to the atient (ame field. Now that we are wor+ing on the header, lets add a title to the report. Select a label and position it above the ,atient Name. !a+e it read$ >"linical 9nformation? give it a font si;e of && and a bold typeface. 9f necessary, change the dimensions of the surrounding bo* Idefined by the green s0uares5 to fit your te*t. 2ou have several options if you want to center this caption. First you could e*pand the surrounding bo*Hs width to go from margin to margin and then, in the properties dialog bo*, change the alignment property to >centered?. Or you could =ust clic+ on the second button of the Align toolbar, the one with a blue rectangle Iwith blue guide lines5 flan+ed by two opposing orange arrows whose tool-tip reads >"enter?. Notice that this will appropriately center the surrounding bo* Inot necessarily the te*t5 so ma+e sure that there is no asymmetric space between the te*t and the margins of the bo*, or the te*t will seem off-center. 8e are now going to place the remaining information. 8hat we want to achieve is to have all the clinical information, including diagnosis, head medical doctor, psychiatrist
(BA

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

and the rest under the patientHs name and, at the bottom, list the medication history. 9f we place all these in the detail, we are going to have the big bloc+ of information repeated for every medication in the record. #his is not what we want. "learly, we need to ma+e a grouping here. "all the Sorting and Erouping dialog bo*. ecause this report will produce information for only one patient at the time you can chose any field for grouping that is not part of the medical history. 9n the Eroups bo*, under Filed3)*pression clic+ on the list bo* and chose -say... 6iagnosis. 8hen doing so, a new section will appear for the report called >6iagnosis -eader? with a nice blue shade in the left margin. -ere we will place all of our grouped elements. "lic+ this area to select it. 8e will follow the design we made in part 99 for this report. 2ou can start by adding a label that will read >"linical 9nformation$? with the colon and all. /eave it to the top of the section, ma+e it bold and give it a font si;e of ('. elow this insert the >6ate of Admission? field. Note how the S7 places it automatically under the previous label. Now insert >6ate of #ermination? and position this pair to the right of >6ate of Admission?. Notice how the guide lines aid you to place them neatly. 9nsert >#herapist?, >6iagnosis?, >-ead 6octor?, >!6 phone?, >,sychiatrist? and >,sy phone?, following our design. 9f you need e*tra space in the group header =ust position the cursor over the lower limit and when it changes to vertical arrows drag the limit down. Notice that the S7 will also enlarge the area to fit new elements. Finally, insert a label at the bottom of the Eroup -eader the reads >!edication$?. "hange the font by ma+ing it bold. 8e also donHt want to repeat this label more than once, which is why we are placing it here. -owever, it will serve here as a header for the detail section. Now we will place all the elements for the medication history in the detail area. Select the detail and insert >!edication?. Select the label and erase it because we will not need it. Now, flush the te*t bo* to the left margin. Following, insert 6osage. Again, delete the label. ,osition this to the right of the !edication te*t bo*. Now insert >!ed start date?. "hange the label to >From$? and ad=ust dimensions. ,lace this pair to the right of 6osage. Finally insert >!ed end date? and change the label to ><ntil$?. Finally, place the pair to the right of !ed start date on the same hori;ontal line. 8hat you should have now is one hori;ontal line in the detail area with all the medication information. Now drag the lower limit of the detail area up until there is very little space between it and the boundaries of the labels and te*t bo*es. 6onHt get startled if some gray area appears$ that is fine. At this moment you better save your wor+. efore running the report you might want to add some elements li+e a disclaimer at the page footer Iwith a label5, page numbers and current date Ias we did in our first e*ample5
(BD

AS)

#<#O79A/

and maybe insert a graphic as a logo. 2ou will find most of these options in the 9NS)7# menu. 6o this to get a hang of using the S7 . Now clic+ on the eleventh button in the first toolbar row, the one that loo+s li+e a report with a green arrow in it. 2ou should be as+ed for the name and surname of the patient you want the report for and then the clinical information should appear, ready for you to print or save as pdf. Kust ma+e sure there is data in the tables to appear in this report. !aybe the spacing between lines and sections is not what you thought you were getting. ,ractice moving the boundaries for each section, and even reposition your page elements, until you get a layout that doesnHt disconcert you and seems natural. -ow is it goingG /etHs ta+e this a notch further. #here are two te*t bo*es of interest here$ #he one to the right of the label$ >6ate of termination$? in the grouping header and the one to the right of ><ntil$? in the detail. #hese bo*es will display data if the patientHs case is closed and medication regime has been terminated, respectively. 9n real life, if the patientHs case is still active then the >6ate of termination? cell in the table will be empty. #he same thing if the patient is still being administered any medication. "onse0uently there would be no data displayed in the report. 9n order to dismiss any ambiguity, we would li+e the report to print something different, li+e$ >"ase Open? or >Still Active?. #his could be managed by altering the S./ code that created the 0uery or by modifying a table if we are wor+ing directly with one. -um! #his could be 0uite cumbersome and we donHt really need to$ 8e can have the S7 ta+e care of this for us. #o accomplish this we use formulas and functions. -owever, before you get to this, consolidate what you are learning and produce the ,atient 9nformation report.

Esing formulas and functions with .&0.


#he S<N 7eport uilder allows us to introduce formulas or functions with which we can collect data from some of the te*t bo*es, process it and achieve a new result or piece of information, very much li+e we did with functions in S./. For e*ample, we can calculate sums of numbers, averages, replace te*t in strings or change case, we can as+ for te*t to be inserted when S7 finds a blan+ cell and a long lists of etceteras. #he only difference is that this time we will not be tal+ing in S./ to the -S./ engine. 9nstead, we will be tal+ing directly to the S7 in its own lingo. 6onHt panic because you only need to understand some simple conventions and later let the very friendly Function 8i;ard ta+e care of the rest. #he first thing you need to +now is how to denote a field value. #his is basically the name of a column in the table or 0uery that we are wor+ing with, either belonging to the table or established by the use of an alias in the 0uery. 8hen we wor+ with -S./ we identify these with double 0uotes. 8hen wor+ing with the S7 we identify them by enclosing them within s0uare brac+ets I>Y> and >Z?5.
(F'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

9n order to identify te*t strings we will now use double 0uotation mar+s. 9f you remember, when wor+ing with -S./ we used single 0uotation mar+s. ut that was then. Finally, composing a function or formula is basically about connecting field names and maybe string literals with S7 Hs built-in functions. Esing !ormulas. 2ou can get a complete overview of the available built-in functions for the S7 here$ http$33wi+i.services.openoffice.org3wi+i3 ase37eports3Functions 9f you chec+ carefully, you will find many functions you already +now about$ !athematical functions Ie.g. the calculation of averages5, date and time functions, Ie.g. the calculation of date differences5, string manipulation and others. 2ou will also find other types of functions li+e logical functions, that allow us to ma+e decisions in the way the function behaves, and metadata functions that allow us to introduce info about the author or title of the report. 6o ta+e a loo+. Furthering the e*ample we have been wor+ing, we want the "linical 9nformation report to write >Open "ase? if there is no termination date for a particular patient. /etHs brea+ this down$ 9f the field with the termination date in the report is empty then write >Open "ase?. Otherwise, =ust write the date in which the case was terminated. 9f you chec+ the documentation, you will find two very useful functions$ 9F and 9S /ANL. 9F is defined in the following way$ &"$test0 trueJvalue0 falseJvalue%. #his means that an 9F function ta+es three parameters$ A condition that is evaluated, a value to return if the condition proves true and a value to return if the condition proves false. Note that each of the parameters are separated by a semicolon and that the entire e*pression is enclosed within parentheses(@. #he 9S /ANL function ta+es only one parameter$ A name of a fieldJ and results true if the field is empty and false if not. #his is all we need really! #o compose our formula we =ust need the name of the field as +nown by the 0uery. 9f we chec+ the S./ 0uery we see that this field is called >6ate of termination?. So we write$
I&(I BLAN'(>Date of te+mination?%"Open Ca2e"%>Date of te+mination?$

(@ #he documentation also states that the test parameter is optional and that only the return values are needed. ut this e*ample will use the three.

(F(

AS)

#<#O79A/

#his formula captures our logic with no problem$ 9f >6ate of termination? is empty then return the value HOpen "aseH. Otherwise return the value in >6ate of termination?. Notice how the string is enclosed by double 0uotation mar+s and the field name is enclosed within s0uare brac+ets. Also, notice that you donHt need to leave white space between parameters, unli+e written )nglish. /etHs now go bac+ to our report in edit mode. Select the te*t bo* that displays the >6ate of termination? data. #he properties dialog bo* will change, offering you the bo*Hs )ata tab. "lic+ on it. #his tab offers only four bo*es and two of them are not active at the time. #hat is =ust fine because we will not need them for now. #he first bo* is called >6ate field type? and specifies what type of origin determines the content of it. y default the bo* states$ >Field or Formula?. #his is correct$ at this time, the content of this bo* is determined by a Field. Other options include Functions and <ser 6efined Functions. 8e will use these later. #he second bo* is called$ >6ata field? and specifies the origin of the content. 9n this case it says$ 6ate of termination, which is the name of the column of the 0uery we are wor+ing with. So the content of this bo* come from this column. -ere is where we want to introduce our formula. 8e donHt need to change the data field type Ithe first bo*5 because it already allows for a formula. 8e =ust need to replace the content of the data field Isecond bo*5 with our formula. 2ou can now place your cursor there, erase the content and type the formula we have created. O7 you could clic+ on the ellipsis and call for the Function 8i;ard and let the wi;ard ta+e care of the synta* and spelling and set the formula for you. #his wi;ard is really cool. First, itHs a library of all available functions, e*plaining what they do and giving their formal definitions. #hen, it allows you to build your formula =ust by point and clic+, ma+ing sure you include all the proper parameters and ta+ing care of synta* and spelling for you. 8hat more can you as+ forG A body rubG Eiven that we +now the form our formula must ta+e, letHs compose it with the wi;ard to learn to wor+ with it. Star by clic+ing on the button with those three little dots... #he Function wi;ard interface pops-up showing two te*t bo*es, one vertical to the left and one hori;ontal to the bottom. #o the right and above there is an area that will change depending on the options that you select. #he bo* to the left shows two tabs$ Functions and Structure. "hances are that the Functions tab is selected at the moment. 9f not, select it now. #o the top in this tab there is a drop down list with the name "ategory. #he wi;ard organi;es all available built-in functions in categories so that they are easier to find. 2ou can clic+ on the button with the arrow to pee+ on the options. Notice that there is an option called >/ast <sed?, which suggests that the wi;ard ta+es notes of our actions and helps us repeat them with ease. 2ou can see that the options include mathematical and logic functions, date and time manipulation and even user defined formulas. -owever, because at this moment we are not familiar with them, ma+e sure that the option >All? is selected. #his way, all functions will appear in the lower section labeled Function.
(F&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#he lower bo* has the tag >Formula?. At this moment it should show an e0uality Ior assignment5 sign >P? and the name of the field in use$ >6ate of termination?. On top of this bo* you will see the function currently selected in the Function bo* defined and with a short e*planation of what it does. "hances are that the A S function is selected Ihighlighted5 to the left and e*plained now. 2ou can read that this function accepts one parameter Ia number5 and the e*planation that this function returns the absolute value of the number. ,lace your cursor over the function bo* to the left and scroll until you find the function 9F. Note that the functions are organi;ed alphabetically. 8hen you find it, right-clic+ on it once to select it. Note how the e*planation now provides the definition of the function Isimilar to the one we gave earlier5 and a short e*planation. 6ouble right-clic+ on it to select it. Several things happen now$ #he category bo* changes to /ogic and the number of available functions shrin+s. #he Formula bo* now includes the te*t >9FI5? and there is a blin+ing cursor between the parentheses. 9f the name of the field was highlighted before then it has been replaced by the new te*t. 9f not then it remains at the tail of our insert. -owever, the most ama;ing transformation happened in the e*planation area because we now have three te*t bo*es flan+ed by buttons. #hese bo*es correspond to the three parameters that this function uses$ the test, the true value and the false value. Notice that the word >#est? is the only one without a bold typeface to suggest that it is not a mandatory parameter. #he buttons to the left seem to have a calligraphic HF*H, meaning functions. #he buttons to the right show a table with a green arrow that points to one of it cells. #he first button allows you to select and insert a function. #he second button allows you to select and insert the name of a field. #he test in our formula as+s us to evaluate if the field >6ate of termination? is empty or not. 8e will be using the 9S /ANL function for this. "onse0uently, clic+ on the F* button for the #est te*t bo*. 6oing so ta+es you bac+ to the >All? category listing. Scroll down until you find the function we are loo+ing for and double clic+ on it. At this moment the function info pops up and a te*t bo* for selecting the value appears. #his time clic+ on the button to the left IField utton5. Now, the Add Field dialog bo* appears, with all the fields present in our 0uery. /oo+ for the >6ate of #ermination? field and either select it and clic+ on the 9nsert button or double clic+ on it. Now the Formula bo* displays the name of the selected field. Note that the s0uare brac+ets, that precisely indicate that this is a field name, are automatically included. #o continue you now need to set the cursor in the formula bo* after the first closing parenthesis. #his way, the wi;ard brings us bac+ to the 9F page so we can populate the two remaining bo*es. Note that our compound test, that includes a function and the name of a field, correctly appears in the #est bo*. 9n the second bo* we must indicate the value that the function must return if the test results true. 9n this case we want the string HOpen "aseH. 8e will not find this value among
(F4

AS)

#<#O79A/

either the functions or field names. 8hat we do is type it. ecause this is a te*t string value, we must enclose it within double 0uotes. #ype this directly to the bo* now. Notice that when you clic+ on the second bo* to insert the string a semicolon is added automatically in the formula by the wi;ard in order to separate the first and second parameters. Now, for the third bo*, clic+ on the button that calls the Add Field bo*. Again a semicolon is added to separate parameters while the dialog bo* waits for your selection. For the second time, select and insert the >6ate of #ermination? field name. 9f you chec+ now, the formula in the Formula bo* is identical to the formula we had presented earlier, =ust that this time it too+ very little typing from us. 9f by any chance the field name that was present before we built our formula is still trailing, erase it now. At this moment you could clic+ on the Structure tab and get a glimpse of what it offers$ basically, you get a more graphical and structured rendition of the functions and field names that your formula uses. Nice! Finally, clic+ on OL to insert our formula in the >6ata field? bo* of the 6ata tab for the corresponding te*t bo*. 2ou can see it there now but you might need to clic+ on the arrow button if you need to read it whole. O+ay, enough dilation. /etHs chec+ the effect right way. "lic+ on the 7un .uery button and insert the name and surname of an entry in your database that does not have termination data. #he report should come out stating >Open "ase?. -ey! 9snHt this greatG! #est this to your hearts content. 8ith the help and ease offered by the function wi;ard itHs very easy to compose and insert functions that enhance the value of the information in our reports. Now do the same with the field in the detail section that records the date when certain medication was terminated. <se the string >Still Active? to give the report more variety. 8e will use this in our final e*ample. Esing !unctions. Now that we have some e*perience using formulas we are going to ta+e this a step further and use some functions that come preloaded with the S7 . #here are several circumstances when a report would re0uire that some information in the report be processed and be presented as part of the report. For e*ample we could want to add the totals in a series of numbers Ie.g.$ sales in a region or per salesperson5, find the highest number ISalesperson with most number of sales5 or the lowest number in a column I6epartment with fewest number of complaints5. S7 offers these e*act functions for us to include in our reports. Of course, you +now by now that you can easily produce S./ 0ueries with this type of information and even other more comple* ones. ut you also +now that combining aggregate and regular functions might re0uire more than one data set and therefore, more than one logical page Ithat is, multiple reports5. 2our e*ploration of the function
(FB

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

wi;ard should have shown you that many of those functions can be replicated by the S7 without the problem of multiple data sets. )ven better, the process of finding the sum, min or ma* of a column of numbers has been further simplified. #his is what we are going to test now. One of the goals of the database for the psychotherapy clinic is to learn about the money in and the money out of their operations and several of our forms re0uire that we sum the money received and the money that must be payed. 8e are going to do a version of the "linicHs Summary of ,ayments report. 8e might simplify this report somewhat =ust so that we can focus on the process of designing a form that uses the sum function. /ater on you should attempt to replicate the form as described in part 99. 9 will now briefly go through the steps for designing a report as detailed earlier$ #his report will list all patients that made a payment within a time frame, the date and the amount of the payment. #he report will as+ for the time window and then list alphabetically all patients that made a payment in that time slice, the amount they payed and the timestamp of payment. 8e also want the sum of the ,atientHs total after displaying the detail. 8e will also want the report to display the total amount received in that period from all patients previously listed, information that we will place at the end of the report. So we will have subtotals Iby patient5 and an grand total Iall payments together5. #he data needed comes from the ,atient table and the ,ayments table. #he S./ code could loo+ li+e$
ELECT CONCAT(CONCAT("Patient"#" u+name"! 3! 3$! "Patient"#"&i+2t Name"$ A "Patient Name"! "Pa-ment"#"Date an. time of Pa-ment"! "Pa-ment"#"Amount" &ROM "Patient"! "Pa-ment" </ERE "Patient"#"ID Numbe+" 1 "Pa-ment"#"Patient ID" AND "Pa-ment"#"Re2ult" 1 3CREDIT3 AND "Pa-ment"#"Date an. time of Pa-ment" 01:BottomTime AND "Pa-ment"#"Date an. time of Pa-ment" =1:TopTime ORDER B* "Patient Name" A C%

Save this with a name you can easily identify. Notice that the 0uery will only select the payments that were successful I17esult1 P H"7)69#H5. 2ou could later produce a report with all the failed payment attempts I17esult1 P H6) 9#H5 and include the !emo field that e*plains what happened. #his 0uery will produce a table with only three fields$ ,atient Name, #imestamp of payment and the amount. !a+e sure that you have created the forms for payment(A or otherwise populated that ,ayment table so that you have actual data to play with. 9nclude data from at least two different months so you can test the time window function and also include both "7)69# and 6) 9# transactions so that you can chec+ the S./ code in its full splendor.
(A 2ou will need a form with patient name and surname and a sub-form for the rest. /et the wi;ard help you.

(FF

AS)

#<#O79A/

2ou might also have advanced that we are going to be doing grouping of data around patient name. Eroupings do have headers and footers. #he header will be a good place to insert the name of the patient. #he footer appears at the end of the section and therefore is the logical section to place the columnHs sum. #he total sum of all payments needs to go at the end of the report. #he only section that can be placed at the end of a report is the 7eport footer. #he page footer is not the place to use because this footer is repeated at the end of every page and therefore does not constitute the ending of a logical section but of a layout section Ithe end of the page5. On understanding these conventions it becomes obvious that we are going to need to include the 7eport header and footer and the Eroup footer, none of which is on by default. 8ith this in mind letHs start our wor+$ go to 7eport and call the S7 . Eo to the )ata tab, select .uery for the "ontent type and then select the name you gave to our 0uery. Now go to the )dit menu and clic+ on 9nsert 7eport -eader3Footer. Notice that the reportHs header and footer appear AF#)7 the ,age header and )FO7) the page Footer. #his is not a mista+e. #he page header will appear on the head of every page by default, including the section for the 7eport header. )ven if your 7eport header ta+es a full page of e*planation and other boilerplate te*t, the top of the page will have the ,age header. #he same thing goes for the page footer. Anyway, you +now that you can change this behavior in the :eneral tab for the report. -owever, donHt change the default for this e*ercise. 9n the ,age header write a title for the report. Something li+e >"linic ,ayment Summary?. 8e are using the page header for this because we want this title printed in all e*tra pages the report could generate. Ad=ust the margin of this section to something you feel as appropriate. !a+e sure the boundaries of the label are not preventing you from downsi;ing this section as much as you want. 9 do not really need to use the 7eport -eader Ibut 9 do need the 7eport Footer5 for this e*ercise. Anyway, 9Hm going to place here a caption that reads$ >For payments made between a and ...? and will insert there the KottomTime and TopTime variables Iwhich the Add Field dialog bo* +indly displays for us5. ecause 9 am using the 7eport -eader, this info will only appear in the first page of the final report. /etHs do this. 8e are going to use two labels$ One for the part of the te*t until the first ellipsis ans the other for the >... and ...? bit. "lic+ on label and write the first part. #hen insert KottomTime, erase the tag and place the bo* ne*t to your te*t. 9t is very convenient if you place both against the upper margin because we are going to reduce the si;e of the 7eport -eaderHs section. Now insert a label that =ust reads >and? and finally insert the TopTime Ialso discarding the label5. Now drag the bottom limit of this section up, leaving only a small margin before the ne*t section. 6onHt worry if gray area starts showing underneath. Now we are going to wor+ on the 6etail. 8e already identified our need to use groups and organi;e them around the name. "all for the Sorting and Erouping dialog bo* and
(FC

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

clic+ on the bo* with a down arrowhead under Field3)*pression. Now select the ,atient Name field. At this moment the Eroup -eader pops up. 9f you read under properties, the third option states$ >Eroup Footer$ Not present?. "hange that to >,resent?. Now the group footer pops up. At this moment you have the detail section surrounded by the group header on the top and the group footer at the bottom. Kust li+e in previous e*amples, we will place information that identifies the group in the group header. 9n this case we will write the name of the patient here. 9n the detail area we will place the timestamp and the amount payed. 9n the group footer we will place the sum of the amounts payed by the particular patient. Notice that the detail will be repeated for every amount payed by the patient in the time frame and the whole group will be repeated for every patient that was recorded ma+ing a payment within the time frame. Select the Eroup -eader and use the Add Field bo* to insert the patientHs name there. !y sense of order doesnHt need the tag so 9 am going to erase it. 9 will change the font properties for the te*t bo* to bold typeface though. #his should be enough to frame the beginning of the group. 9 also recommend that you flush the bo* to the left margin. Now you can insert a label one row further down and to the right of the ,atientHs name te*t bo*. #his is going to be li+e the header of a table that will list the date and amount of payments. #o conform a bit closer to our original report draft you can give it the te*t$ >,ayment received on$?. #o the right of this label add a second one with the te*t >Amount?. #o ma+e them loo+ li+e headers change their typefaces to bold. Now you can drag the bottom margin up. 9f you have deselected the te*t bo* you should see the sectionHs property dialog Iselect on it or the bluish area to the left to ma+e it active5. 2ou can see the -eight property change as you drag the bottom margin. 9 left mine at '.F'?. See what you li+e. Now select the detail and insert the >6ate and time of ,ayment? field. )rase the tag and place the te*t bo* under the first label you created. Now insert the amount field, erase the label and place the te*t bo* under the >Amount? label. Notice that while the labels are in the group header, the te*t bo*es for the actual values are located in the detail area. Now drag the bottom margin until your sense of aesthetic is pleased I9 got to '.&&?5. ,lacing margins in pleasant ways might ta+e some practice. Now comes the fun part$ Select the group footer and place a te*t bo* there aligned with >Amount?, ma+ing a column with it and the other te*t bo* we placed in the detail section. -ere is where we will display the sum of all the amounts in the group. Now go to its )ata tab. #he 6ata Field #ype reads Field or Formula. "hange it to Function. Now for 6ata Field select Amount. At this moment the third bo*, which reads Function, becomes activated. "lic+ on it and select Accumulation. #his combination will produce the sum of the values in Amount. ut we donHt want all of the amounts. Only the ones for this group. 6onHt despair. ase identified this 0uite 0uic+ly upon noticing that we are placing this te*t bo* in the group footer. So the last bo*, descriptively named Scope, automatically displays$ >Eroup$ ,atient Name?, which is e*actly the scope that we want. #he other option for scope is 7eport, which we will be using shortly.
(F@

AS)

#<#O79A/

#o finish the Eroup footer we are going to add some te*t that helps frame the info here. From the Add Field bo* insert ,atient Name Iagain, 9 +now5 and ma+e sure it falls to the left of the accumulated amount te*t bo*. Now change the the te*t in the label from >,atient Name? to >#otal payments for$? and ad=ust the width of the bo* and the distance with the te*t bo* so that it loo+s li+e a sentence >#otal payments for such and such$?. #o separate a group from another Iin this case, a patient bloc+ from the ne*t one5 /eave more white between the lower limits of the label and te*t bo*es and the lower margin of this section. ecause 9 am using the Arial front, si;e (&pt. and the bo*es are flushed against the top margin, a height of '.4'? wor+s for me. #his is only a reference and you can do what feels better to you. Now select the 7eport Footer. 7emember$ this section appears only once, at the end of the report. -ere we are going to place the total sum of all payments received. Start by placing some labels and the time frame variables so that the caption in the report footer reads something li+e$ >"linicHs total income for period between KottomTime and Top# Time$?. 9f you are not sure how to do this follow the instructions concerning the 7eport -eader in this e*ercise. Now 9nsert a te*t bo* to the right of the previous caption. Select the )ata tab. On the 6ata field type select Function. On the 6ata field select Amount and on the Function option select Accumulation. Now the report will automatically select >7eport? for the Scope of the function. #his is a beautiful report. !a+e sure to save it now Iyou never +now5 and run it$ First you are as+ed for a time frame. Start by providing the first day of the earliest month you inserted in your data and the last day of the latest month. #his way all the successful I>7esult?PH"7)69#H5 payments that you entered will be included. Now ase produces your report. 9t could be the case that some bo*es are too short to display all data, or too longJ or that section margins need to be further ad=usted or that you need to twea+ the alignment of te*t in the bo*es. S7 gives you all the fle*ibility that you need to fi* this. ut for now focus on the totals by patient and the grand total calculated by your report. 7eali;e that we donHt need to do any more programming to re0uest income information for any period of time that we have recorded in our databaseJ and that our time windows can be of any length and precise to a second. "onfirm this$ run the report again, now giving different time windows. Notice that you can omit time Ias opposed to date5 parameters to ma+e your input 0uic+er. O+, enough. 2ou can dry the tears in your eyes now. 2ou should practice your new s+ills and produce a report that displays the highest payment by patient and the highest payment overall Iuse the ma* function5 and then one that displays the lowest payment by patient and overall lowest payment. #hese functions where placed automatically by ase. 8e didnHt even have to worry about writing the formulas needed for these calculations. -owever, it would be very informative for us to see how the e*perts have created the formulas that wor+ with these functions. /etHs e*amine under the hood and see how this marvel happened so we can replicate it with other functions. #o do this we need to become familiar with the 7eport Navigator.
(FA

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

The &eport

avigator.

#he 7eport Navigator provides a summary of all the elements you have placed in your report$ /abels, te*t bo*es and functions by section Iheader, footer, detail, etc.5, gives you 0uic+ access to their ,roperty 6ialog bo*es and activates any element in the report if you clic+ on its name in the Navigator. #his is not unli+e the Form Navigator we have studied earlier. 2ou call this window by clic+ing on the button ne*t to the ones that call for the Add Field and the Sorting and Erouping bo*es$ itHs the one that loo+s li+e a form with a compass over it. 9f you call this window now you can see that it displays some +ind of tree structure with a root in 7eport and, dependent of it, the elements$ Functions, ,age -eader, 7eport -eader, Eroups, 6etail, ,age Footer and 7eport Footer. #his pretty much describes the content of the sections in our report. 2ou can also see a small bo* to the left of these elements with a plus sign. 9f you clic+ on it then the contents of the sections become visible. !eanwhile, the little bo* now displays a minus sign instead. 9f you clic+ on it, you hide the contents. For e*ample, if you clic+ on the ,age -eader, the 7eport Navigator shows that the only content there is a label, displaying also the content we gave to it. 9f you clic+ on this section, the label in the report becomes active and the properties that belong to it are displayed in the ,roperties dialog bo*. #his is an easy way to find any element in a report. )*pand all the bo*es to see a complete description of the contents of our report. Ad=ust the margins of the 7eport Navigator window if necessary. )verything we placed in the report is described here e*cept for one element that might loo+ 0uite novel to you$ Functions. And there are two$One =ust under the 7eport root and other associated with Eroup. #his is not so strange because we do have two functions$ One that calculates the sum of money amount by patient and another that gives us the grand total. 9f you thin+ that the function that calculates the partial results must be the one associated with Eroup, you are right. #he function is defined at the head of the Eroup by ,atient Name although its used at the footer. ecause itHs defined at the very beginning of the group section, it will consider data that is only local to the group and we could use it anywhere Iin our case, we use it at the footer5 but only in the group section. 9t also means that this function is local to the group and we might not be able to use it outside of the group. 8ith the previous in mind then itHs easy to understand that the function defined at the very beginning of the report, which is used at the 7eport Footer, could be used globally, that is, anywhere, in the reportJ and that it will consider data available to all the report. -ence its ability to calculate the total sum of the amount field. So now we +now that in the future, when we want to include a function that can be used anywhere in the report or that uses data from the entire report, we want to define it at the beginning of the report. 8hen we want functions that ma+e calculations local to a group, we will define it within the group section.
(FD

AS)

#<#O79A/

Now note that the functions have been given names$ #he global function is called$ Accu# mulation Amount <eport. #he local function has been called AccumulationAmount atient (ame. ase has assigned the names of the functions by =oining the name of the function option, the field it bases its calculation on and the scope of its domain. #he relevant thing is that functions are given names although we donHt need to follow the same convention. 9f you e*pand the Eroup Footer section you will see that the 7eport Navigator describes the following contents Iand not necessarily in a left-to-right and up-to-down order but organi;ed by the order in which they were created5$ #here is a /abel that holds the te*t$ >#otal payments for$? #hen there is a te*t bo* with the field corresponding to ,atient Name and finally a Formatted te*t bo* Ithe one we placed manually5 associated to the function name$ AccumulationAmount atient (ame. Now, note that this function is placed within brac+et parentheses. y ma+ing this association Iwhich ase made automatically this time for us5 we manage that a bo* display the result of a function. 9f you now select one of the functions in this report by clic+ing on the name of the function in the report navigator, right ne*t to the F* symbol, you will see the ,roperties 6ialog o* of the function. 6o this now. 2ou can see that a function has only a :eneral tab and only five bo*es with properties$ Name, Formula, 9nitial :alue, 6eep #raversing and ,re-evaluation. 8e are mostly going to wor+ with the first three bo*es$ Name, Formula and 9nitial :alue. #he name allows you to identify your formula which allows you to later use it with a formatted field and even with other formulas. #he second bo*, Formula, tells ase what calculations to perform e*actly. 2ou can see a button with an ellipsis. "ertainly, it calls for the Function wi;ard. #he documentation states that this field accepts and understands formulas as defined by the OpenFormula standard. #he initial value bo* can hold a field, another formula or a constant, depending on what we want to achieve. 8e will see some e*amples of this(D. /etHs start with the formula for AccumulationAmount atient (ame. 9n the 7eport Navigator e*pand the F* bo* below Eroups and ,atient Name and then clic+ on Accumula# tionAmount atient (ame. Now chec+ the Name, Formula and 9nitial :alue bo*es in the :eneral tab of the ,roperties dialog bo*. #hey should loo+ li+e this$
Name: AccumulationAmountPatient Name Formula: [Amount] + [ AccumulationAmountPatient Name] Initial Value: [Amount]

#he first thing we can notice is that this formula uses an addition sign I>T?5. 9n effect, formulas allow us to use mathematical operators li+e$ >T? Iaddition5, >Q> Isubtraction5, >]? Imultiplication5, >3? Idivision5 and parentheses for grouping >I> and >5?. #he second thing is that this formula has been given a I0uite long5 name but later is treated as a field, that is, its value is referenced by using the name withing s0uare brac+ets >Y> and >Z?. #his is a very important feature. 9t basically means that the function itself becomes something li+e a variable, a name that +eeps a value.
(D Kust for the record, if you need the formula evaluated before the report is run then you must set ,re-evaluation to

2es.

(C'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

/etHs see how this wor+s$ the function definition starts by allocating a name to identify the variable Ifirst bo*5. #hen is states that it will start by assigning to it the first value found in the field Icolumn5 >Amount? Ithird bo*5. Finally it states that every new amount will be added to the previous value of the function and stored in the function Ithe Formula, or second, bo*5. ecause this function has been declared inside the ,atient Name Eroup, it will reset every time the ,atient Name field changes. Eo to the 7eport Navigator and clic+ on the AccumulationAmount<eport function and see if you can understand itHs definition and the way it has been set. Following this insight, 9 could try the following definition for a function$
Name: numberOfItems Formula: [numberOfItems] + 1 Initial Value: 1

#his proposes to create a function called HnumberOf9temsH, that will start receiving the value of one and will increase by one every time a new field is evaluated. #his allows me to +eep a count of the number of records in a field for the scope of a group or a complete report, depending on my selection of the scope of this function Iwhich is done in the last bo*5. #his is e*actly what the "ount function does, which you can find in the 6ata Field #ype bo* of the )ata tab of any #e*t o*. ut formulas donHt need to limit themselves to mathematical operators. #hey can in fact use any of the functions available to the S7 . #he !in and !a* formulas show this clearly$
Name: Min Formula: IF [Fiel!Value]<[Min]"[Fiel!Value]"[Min]# Initial Value: [Fiel!Value] Name: Ma$ Formula: IF [Fiel!Value]>[Ma$]"[Fiel!Value]"[Ma$]# Initial Value: [Fiel!Value]

2ou can see that the definitions for the !in and !a* functions use the 9F function. /etHs interpret the !a* function$ Assign to @1a*A the number stored in the first @"ield+alueA evaluated. 2ompare the ne*t value for @"ield+alueA to the number stored in @1a*A. &f the number is bigger, store it in 1a*, replacing the old value. &f not, keep the old value. 8ith this information we should be perfectly able to venture in the creation of our own functions. /etHs try this ne*t.

(C(

AS)

#<#O79A/

Custom made functions.


Now that we understand how to use the 7eport Navigator and where and how functions are defined, we are going to start from scratch and create a custom function that calculates the average payment by patient and the overall average of payments. #his way we can use the same 0uery we created for the previous e*ercise. Also, the general layout of the form that we need is basically the same to the one we =ust createdJ only the function definitions will be different. Anyway, my recommendation is that you donHt =ust try to reuse this one$ uild the report from scratch and practice what you have learned. #a+e your time. 9 will sit here and wait for you. As you +now by now, the S7 allows us to create our own functions Icalled <ser 6efined Functions5 at two levels$ the grouping level and the report level. 9n this e*ercise we are going to create a function that calculates the average payment by patient and the overall average payment for a defined period of time. ecause we are using the elements created in our previous e*ercise, most of the functionality re0uired by this report has been e*plained already Ithe S./ code that re0uests the time period and filters the information, the grouping of the information by patient, the organi;ation of the report in report and grouping sections, etc.5. Now we will =ust focus on creating the functions and ma+ing sure that they are used by the report. 8e +now that we need two user-created functions$ One to calculate the average amount payed by each patient and another to calculate the overall average. #he first one needs to be placed at the grouping level and the other one needs to be placed at the report level. #his should be a fun e*ercise because we canHt use the A:)7AE) formula that appears in the Formula 8i;ard here. -ow comeG 9f you analy;e its definition you will read that this built-in function returns the average of a sample and that allows for the input of up to 4' elements that can be either column names -present in your table or S./ code basis for the report- or other formulas. -owever, this function does not allow you to calculate the average of values inside one column but rather uses values across several columns, usually in the same row. 9n general, all functions wor+ with values in one row, letHs say, hori;ontallyJ and not vertically with values in one column. 9f your S./ code or the table you are using as basis for the report has, say, a column for first 0uarter total sales and a second column for second 0uarter total sales and so on Iup to thirty columns5 then the function will happily return their averages, row by row. 8ait a minute! you could e*claim$ 8ere we not calculating the sum of values in a column Iand the biggest or smallest value in a column5 =ust in the last sectionG 2es, we were. #han+s to the fact that the name of a function wor+s li+e a variable that stores a value, we were storing there the accumulation of a column and the bigger or smaller number in a comparison. <#, we were doing this row by row$ 5e land in a new rowL Then add the value to the number we are keeping or compare the values and keep the larger one, etc. . 9n the case of the accumulation, this is made possible because the sum of a number to two numbers previously added is e0ual to the sum of the three numbers, that is$
(aTb$ T " 1 a T (bT"$ 1 a T b T "
(C&

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

-owever, this is not true for averages$ #he average of three numbers is not e0ual to the average between one of the numbers and the average of the other two$
A6)(a!b!"$ U A6)( A6)(a!b$! "$

For e*ample, the average of B, F and C is F. ut the average of B and F is B.F and the average of B.F and C is F.&F. Oops! 9s this the end of the worldG Not really. 8e have the goal to build our own functions and this e*ercise demands =ust that. /etHs start by understanding what we need$ 8e want to calculate the average of a set of numerical values. -ow do we do thisG 8e add the values and we divide this result by the number of values in our set. 8e will not +now before hand how many values come in our set. #hen, letHs count the values as we add them. #hese two functions rely on addition, which can be done row by row with no problem. #his way we +now that we will need three functions in total$ one to calculate the sum of the numerical values, one the calculate the number of values in the set and one to calculate the division of these results. #o ma+e things even more pleasant for us we donHt even need to produce the first two functions$ we can use the Accumulation function we analy;ed in the previous section to calculate our sum and we can use the "ount function to determine the number of numerical values. 8e =ust need to put them in place and then create a function that calculates their ratio. #his is what we are going to do now. 8e are going to start with the Eroup average. 9n order to illustrate as clearly as possible what we are doing, we will ta+e some intermediate steps you might want to replicate when you attempt to do the report average. /etHs start by adding a "ount. ecause we have not done this before, 9 want to show you how it wor+s. /etHs start by adding a small te*t bo* to the right of the te*t bo* that displays the >6ate and time of ,ayment? field in the detail section of this report. #hen access the )ata tab of this small new bo*. 9n the 6ata Field #ype select "ounter. At this moment ase deactivates the following two bo*es in the )ata tab and correctly sets the scope to Eroup$ ,atient Name. #hatHs all it ta+es as ase has ta+en care of the rest for us. 9f you run this 0uery now you will see that each payment per patient has an ordinal number that starts with one for each new patient name. #he Eroup footer should have three elements$ a label that frames the info and should say >Average payment for?, a te*t bo* where the patient name field will be displayed and a te*t bo* where we will display this average. 9 want you to add a fourth element$ another te*t bo* this time to the right of the last one. 8e will display our sum here. After creating the bo* go to its )ata tab and select the Function option for the 6ata Field #ype. #hen in 6ata Field select >Amount? and select Accumulation for the Function. 2es, we have done this before. 9n any event, if you run the 0uery now you will see a sum of the amounts payed by each patient.

(C4

AS)

#<#O79A/

At this moment we have the number of payments and the total sum of payment made by each patient. #hese are the numbers we need to calculate the average. 8e didnHt really need the bo*es for the "ount and the Sum ut 9 wanted to show these elements in action at least once. 9t also simplifies our wor+$ 9f you call the 7eport Navigator you will see that these functions have been properly and automatically placed by ase at the Eroup level, sparing me the need to type them myself. Now we need to create the function that will use our partial results. Eo to the 7eport Navigator and find the function branch for the Eroup level ,atient Name. Select it by right-clic+ing on it. #hen left-clic+ it, calling the conte*tual menu. Find and clic+ the option >New Function?. Now a new function with the name >Function? appears under the two functions created automatically by ase. Select it, calling its ,roperties dialog bo*. /etHs first change the name of the function with something more descriptive. 9 will do >fn,aymentAvg?. #he prefi* identifies this as a function. #he rest of the name reminds me that this function calculates the payment average. ut you can try any name, li+e )dna or !aribel, and with or without prefi*es. Notice the 7eport Navigator updating the name as soon as you shift focus from the bo*. Now we will introduce our formula. 8e want the sum of payments divided by the number of payments. #he function that holds the sum of payments is$ AccumulationAmount# atient (ame and the function that holds the count is$ 2ounter atient (ame. #he formula should loo+ li+e this$
[AccumulationAmountPatient Name]%[&ounterPatient Name]#

#ype this and we are ready. Notice that we donHt need an initial value so we are leaving that field empty. /etHs leave ,re-evaluation set to >2es?. Now we need this formula displayed. Select the te*t bo* in the group footer that you had prepared for this. Eo to the )ata tab and select ><ser 6efined Function? for the 6ata Field #ype. ase responds by deactivating the 6ata field and Scope selections. 8hen you clic+ on Function you will find all of the functions available for this report Ithat should be three if you started this e*ercise from scratch5. Find and clic+ our function. 9f you now run this report you will see the average of payments done by each patient displayed in the group footer section. 6epending on how you have formatted this bo* you could see an integer number Iwith no decimal places5 or a decimal number. 2ou can further specify the format displayed by this bo* in its :eneral tab. 2ou can now eliminate the bo*es that display the count or the sum of the amounts. 8e used them only as guides and to have ase insert the needed functions for us. Now it will be your turn to calculate and display the full average of payments in this report. Kust remember to define your functions at the report level Iat the top in the 7eport Navigator5 although you will be using them in the reportHs footer.
(CB

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

9 am sure that all the possibilities opened by the use of functions and formulas might be whetting your appetite$ #he ability to gather and process information in your report to produce further information not immediately evident and then dynamically adapt the output to the results is really tempting. ut wait, there is still more.

Conditional formatting.
/etHs imagine that we need to highlight a possible value in one field. 8e could ma+e it stand out by changing the color of the font, the typeface or some other element of the formatting but ON/2 if it happens to be a certain value or within a range of values. 8hat we need here is the ability to do conditional formatting. For e*ample, letHs go bac+ to the e*ample for our "linical Summary$ 9t could be very important to highlight any active medication because the therapist might need to chec+ on that. So we would li+e the report to write the >Still Active? string with some enhancement, say, using the color red and italics. #o achieve this go bac+ to your report and select the te*t bo* that displays the >!ed end date? field Ithe te*t bo* to the right of the label ><ntil$?5. Now go to the menu and clic+ on Format and then on "onditional ,rinting... #he "onditional ,rinting dialog bo* pops-up. 2ou can see the name >"ondition (? and down of it two rows of controls. #he first one sets a condition and the second row specifies how must the te*t appear if the condition is met. #he name >"ondition (? suggest that more conditions and resulting formatting styles can be added. For this you can clic+ on the button with a plus sign down and to the right. y default, the field value is compared with a range of values by offering the operator > etween? and two bo*es for parameters. )ach of these bo*es have buttons with the ellipsis. 9f you clic+ on these you will call the Function wi;ard. So you can build very sophisticated conditions for the conditional printing. -owever, our goal is to highlight when we get e*actly the string >Still Active?. /etHs start by clic+ing on the button with a down arrowhead in the second bo*, the one that states the operator, and find and select the >)0ual to? operator. Notice that because this operator needs only one parameter, the condition row ad=usts accordingly. 9n the #hird bo* =ust type the string that we are loo+ing to match$ >Still Active?. 7emember that for the S7 , we must enclose strings within double 0uotes. #his way the first row should read$ "ield +alue is ;'ual to @9till ActiveA. Now letHs establish the way we want the formatting$ "lic+ on the button for italics and see the sample te*t change accordingly. #he fifth button form the left calls for the color

(CF

AS)

#<#O79A/

menu. Select the color red and see again the sample te*t reflect this. Notice that the si* buttons allow you to change virtually any aspect of the rendering of te*t. Finally press the OL button and run the 0uery. ,ic+ a patient that has current and terminated medication records. 8ow! 8hat bout this!! 8ith this dialog bo* you could easily set that, for e*ample, values below ;ero come out in red, values between one and &' are printed in orange and numbers over &' are rendered in blue. 8hat about thatG Or you could ma+e that patients that have been in therapy for more than a year to the date the report is made appear highlightedJ or you could compare values from different fields... in short, the possibilities are endless.

A word of caution:
8ith all its fle*ibility and powerful functions, the S7 is not without bugs. #o my understanding, this is problematic at least at two levels$ First because by not wor+ing the way itHs supposed to it ma+es it difficult to accomplish what one wants. ut second, it complicates the learning curve a lot$ 9f 9 am not achieving the end result that 9 want, is it because 9 made a mista+e or is it a software bugG 9f we +new beforehand the effects of the bug in our programming we would probably not call them bugs but issues and =ust wor+ around them. ut we donHt always +now in advance whatHs happening. !y adviceG 9f things are not going the way you thought they should then be patient. #ry again. Start anew. "hec+ the forumHs post Ichances are that someone already confronted the bug, posted a 0uestion and received an answer5. And, yes, report bugs.

(CC

Chapter
,aintenance of a Database.

11

#hroughout the useful life of your database there are things that you might want to do to +eep it current, reliable and safe. #his includes modifying data structure, updating your forms, defragmenting your database and creating bac+ups. ,odif$ing data structure. 2ou might remember all the time we spent carefully shaping our tables and their connections. 9t is not a good thing if we find ourselves trying to modify this with a database that we are actually using because the potential for doing some irreparable damage is 0uite big. 8e could lose some important data and we could even lose some critical data for the internal operation of the database itself Ili+e primary +ey numbers, for e*ample5. ut business practices do change and the effort to start a new design, and later populate it with data, could be 0uite big compared to the effort of =ust adapting the database to the new practice. 8here does the boundary lie will depend on your ability, available time and the degree of change in data structure re0uired by the new business practice. For e*ample, letH say that the director of the clinic decides to include new offerings aside from therapy for adult individuals li+e family therapy, couples therapy and child and adolescent therapy. #hey will cost differently and the therapist will be payed differently. Now it ma+es sense to record the +ind of therapy being provided so that we can charge and pay accordingly. 9f we study the <!/ diagram for our database we will easily discover that the best place to include this would be in the 1Assignment1 table. 8e need to include a new column, that we could call 1!odality1, where we can store this new piece of information. #he instruction for doing this is the A/#)7 #A /). 2ou can find a complete description of what this instruction does in the documentation for -S./ at$ http$33www.hs0ldb.org3doc3guide3ch'D.htmlOalterRtable-section #here are many things you can modify with this instruction, including$ Adding columns or constraints, dropping columns or constraints, renaming tables, altering columns and even changing the auto numbering of primary +eys. !a+e sure to read the section so that you can understand the synta* by comparing the definition given there with the cases e*amined here. For our e*ample we will need to call the S./ command bo* at #oolsXS./... and type and e*ecute$

AS)

#<#O79A/

ALTER TABLE "A22i,nment" ADD COLUMN "Mo.alit-" 6ARC/AR (78$%

Now we have a new column of a varchar data type in the specified table. Of course, this column is completely empty. Other e*amples of this S./ instruction include$
ALTER TABLE "A22i,nment" DROP COLUMN "Mo.alit-"%

#his instruction would eliminate the column 1!odality1 and all data in it would be lost.
ALTER TABLE "A22i,nment" ALTER COLUMN "Mo.alit-" RENAME "The+apT-pe"%

#his instruction changes the name of the column 1!odality1 to 1#herapy type1 in the Assignment table.
ALTER TABLE "A22i,nment" ALTER COLUMN "A22i,nment ID" RE TART <IT/ K7%

#his instruction resets the counter for the primary +ey auto numbering in 1Assignment 961 to 4& Eo and chec+ the documentation to get a feeling of other things that you can do. ,odif$ing forms. 2ou might want to modify your forms to ma+e them easier to use or as a conse0uence of changing data structure. /etHs see this in the conte*t of our previous e*ample. Now that we have our new column we need to start recording the type of therapy that the patients are being assigned to. #he modalities are$ Adult individual, child and adolescent, couples therapy and family therapy. 8e +now that we want to insert this data in a way to minimi;e data entry error because the generation of reports that charge or pay money are going to be based on precise counts of the types of therapy. 8ith long names li+e these, the potential for error increases. 9 am sure that you are already thin+ing about radio buttons for this and you are right. 2ou are going to need to modify your Assignment 6ata )ntry Form and include these four new modalities using radio buttons so that the user only needs to point and clic+ the desired option. 2ou already +now how to do this. ut what happens if the director of the clinic +eeps changing the offer of therapeutic modalities, loo+ing for products with the necessary public appealG /etHs say that he includes support groups for obsessive-compulsive disorders, grief and mourning and se* addiction. Now your form is getting really crowded with radio buttons. /ater he decides to drop child and adolescent therapy because he has no 0ualified therapists at the moment and also se* addiction because no one has registered in it in the four wee+s that it has been available. #wo days later he comes with the re0uest to include a drug addiction pro(CA

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

gram and AA meetings. #here you are changing your form, adding and dropping radio buttons with no end in sight. 6onHt despair, 9 have a little tric+ to offer you. /etHs thin+ for a moment what is it that we are trying to achieve$ 8e want to insert strings of te*t in a varchar column in a way that is simple and minimi;es entry errors li+e misspellings. Our first inclination is to use radio buttons but with a big number of options the form becomes crowded 0uite 0uic+ly. 8e are also e*perimenting with several and new options, adding and changing them, so we want a mechanism that would simplify maintenance. #o achieve this we are going to use a /ist o*. 2es, 9 +now that /ist o*es and their drop-down feature are used for displaying names and then storing the corresponding primary +eys while radio buttons =ust pass a string. ut we can change this behavior. Also, /ists o*es feed the options from a table, ma+ing maintenance easier. Our first step will be to create an e*tra table to hold the different therapy types. #his will be a simple table with a primary +ey and a :archar column we will call 1#ype1. 2ou can include a description column as well. 8e do not need any other element in this table. 2ou should +now by now how to compose the S./ code for this$
CREATE TABLE "The+ap- t-pe2" ( "ID" INTE)ER )ENERATED B* DE&AULT A PRIMAR* 'E*! "T-pe" 6ARC/AR(78$! "De2"+iption" 6ARC/AR(:;;$ $% IDENTIT* ( TART <IT/ O$ NOT NULL

2ou can go to the #ables section, open this table and populate the 1#ype1 column with the options re0uired by the director. I<se$ Adult individual, "hild3Adolescent, Family #herapy and "ouples #herapy5. #his way we have data to populate the drop-down list&'. Now weHll edit the form where we ma+e the assignments, which is lin+ed to the >Assignment? table. 9nsert a /ist bo*. 9f the /ist bo* wi;ard appears then select the new table, 1#herapy types1, as source in the first step. 9n the second step chose 1#ype1 to populate the drop down list. 9n the third step, under 1Field from the :alue #able1, which is the receiving field, chose 1!odality1 Icolumn we created earlier and should appear now5 and for 1Field from the /ist #able1, which is the source field, chose 1#ype1. 2ou are ready to go. Notice how we made sure that both 1!odality1 and 1#ypes1 are of the same data type. Now, it could happen that the wi;ard does not appear because ase has no way to +now what tables you are trying to lin+. No problem if this happens because we can as easily use the ,roperties dialog bo* of the /ist bo*. "all for it and go to the )ata tab. 9n the

&' #he >6escription? column allows you to record any important information about the different types, although is not really used in this e*ample.

(CD

AS)

#<#O79A/

16ata field1, which specifies the receiving column, pic+ 1!odality1. 9n 1#ype of list contents1 chose S./. For 1/ist content1 insert the following code$
ELECT "T-pe"! "T-pe" &ROM "The+ap- T-pe2"%

and for 1 ound field1 select (. Note that the procedure is almost identical to the one reviewed at the end of chapter A for manually creating list bo*Hs lin+s. #he big difference is in the S./ code where, instead of selecting the column with the names we need and the corresponding primary +ey, we selected the names twice$ #he first call for >#ype? populates the drop down list and the second call provides the content to be passed to the >!odality? column. 9f you chec+ the relationships I#oolsX7elationships5 you will see that our new table does not even appear with the rest of the tables. #his is because we have not included a constraint that establishes a relationship via a foreign +ey li+e the other tables do and, so, the tables are not lin+ed in this sense. ut right now the /ist bo* wor+s li+e a super radio button$ it offers mutually e*clusive options and passes the selected string. )ach time the 6irector comes with a new therapy modality, all you need to do is to include it in the >#herapy types? table and it will appear in the 6rop-down list. 9f the list is getting too crowded, you can even delete from the table the options that are no longer being offered. -ow is that for easy maintenance! Defragmenting $our Database: At times you could discover that your ase application re0uires a rather big amount of memory although it holds comparatively a small number of records. 9Hve read several e*planations for this$ First, that the application appropriates an amount of memory in anticipation of the number of records it could need to hold. Second that, although our data appears to us in graciously ordered tables, the truth is that itHs stored at different times and not necessarily in order. Alongside the piece of data we care for, -S./ is storing several inde*es that relate the data to a particular table and a particular column, bloating the amount of data we need to +eep. /astly, that when you delete records these are not really e*punged from the database but really =ust disconnected from the inde*es of the database, lying there until the memory they use is overwritten. All this e*tra data means bigger file si;es. Kust li+e with a hard dis+, if we can reorgani;e our data then we will be able to discard those inde*es and ma+e our files smaller, faster and less prone to brea+downs. 8e do this by defragmenting our database file. All you need to do is open the S./ window I#oolsX S./...5 and type and e*ecute$
C/EC'POINT DE&RA)

#his will ta+e care of all the e*tra unneeded information in the file. 6onHt be startled$ #his instruction will first close the database, reorgani;e data and then re-open the database.
(@'

F7O! N)8

9) #O A6:O"A#) 9N A ON), #8O... #-7))!

#here is another instruction that behaves similarly$ S-<#6O8N "O!,A"#, but does not re-start your database after reorgani;ing and minimi;ing data. 7ead more about them in "hapter D of the -S./ documentation at www.hs0ldb.org 0ackups: #errible things can happen to a computer$ :iral infections, hard dis+ drive brea+downs, computer crashes that damage dis+ sectors and a long etcetera. !ost of these things donHt even have to do with ase although ase can also crash. Eood thing that OpenOffice.org comes with a good recovery wi;ard that could minimi;e the data lost. -owever, there is always potential for data loss. #he smart thing to do, of course, is to +eep bac+ups. All you need to do is ma+e copies of your ase database files and +eep them in other places of storage li+e secondary hard dis+s, flash memory drives or optical media I"6s 6:6s5. 2ou =ust have to select the ].odb file of interest, copy it and paste it in the secondary media of storage. 8ith this solution you save all at once$ 6ata structure, data, forms, 0ueries and reports. Of course, any bac+up will be good only to the moment it is created. -ow often should you create them depends on how often you modify forms or reports or how often you update or modify data.

(@(

AS)

#<#O79A/

(@&

Chapter
.ome final words:

12

9 really li+e ase wor+ing with -S./. 8hen 9 started writing this tutorial -mostly to learn how to use them- 9 didnHt +now much about databases. #oday 9 can see that you can use them in a wide range of applications, not only +eeping customer data and recording rendition of services -which are already fine areas of application- but also in scientific research, administrative wor+ and even, if you thin+ about it creatively, for writing literary fiction or creating games. 9 remember reading a suggestion on using ase with the S7 for writing very focused cover letters and resumes with the ease of point and clic+. ase can wor+ as a front end for many other database management systems, not only -S./. ut -S./ is nice because it integrates very well with ase. #his means that they will wor+ together with not much discord, ta+ing advantage of the ease with which ase can set up things and the reliability with which -S./ stores and processes data. #he programmers at OpenOffice.org tested many options before deciding on the integration of ase and -S./ into an embedded application. Furthermore, if you chec+ the -S./ web site Iwww.hs0ldb.org5 you will read that their programmers are very proud of its speed, the small amount of memory the program itself re0uires, the reliability with which it handles data and other advanced functionalities. ut if you read the ooforum.org you will find lots of s+epticism about ase wor+ing with the embedded -S./ engine. #hey would definitively not recommend this solution to store critical data and would shy away from the idea of having your business depending on it. #his might come as a disappointing and dis0uieting revelation to you, who has =ust finished a 0uite long =ourney understanding ase and learning how to ta+e advantage of it. 8hy do they say thisG 9n simple words$ 6ata corruption. #he thing is that by having ase wor+ with -S./ in embedded mode, A// of your information is stored in ON) file Ithe ].odb ase file5. 2our forms and reports are stored in this file but also your data structure and your data, all conveniently ;ipped for storage. And it so happens that there is a chance of ase inadvertently transforming some element of this data and thus potentially ma+ing it impossible to read and write the file appropriately. #he change could be trivial but it can have a devastating effect on your ability to access and use your information. 9f this happens to you and you are courageous enough, you could try un;ipping the file and e*ploring the scripts that are read to build your application every time you open it. 9f you spot the corruption and you can fi* it, you might be able to recuperate your data and even the database&(. <nfortunately, this might not always be possible

&( Find info at www.oooforum.org on how to do this. Kust to learn more, you should un;ip and e*plore a spare odb file. efore un;ipping you must change the .odb e*tension to .;ip so it can be recogni;ed as a ;ipped file.

AS)

#<#O79A/

So the fact remains$ #his corruption can occur. #herefore the embedded option is not completely reliable. 8hat do we do nowG ecause the problem is related to having all your data in one file, the recommendation is to have the data and data structure in a separate file to the rest of your application Iforms, reports, etc.5. #his way, any corruption or crash created by ase will not affect the tables and their stored information. 9f the corruption in a ase file pushes it beyond recovery, you can =ust open a new ase file and as+ to connect to your tables. ,roblem solved. All the stability and reliability promised by the database engine becomes yours to en=oy again. #his is not difficult to achieve. 9t basically consists of downloading an -S./ file Iwith a .=ar e*tension5 and storing it somewhere in your computer as resident and then have ase connect to it. 9f you want to, you can even chose a different database system altogether. For e*ample, at the time of the writing of this te*t, -& has become a very attractive alternative as it offers encrypted tables and other per+s. -S./ &.* also offers attractive features Iincluding encrypted data5. oth these options integrate very well with ase. Furthermore, you can find at the ooforum.org an overview of the pros, cons and features of ase wor+ing with several other relational database management systems. 9 will not cover how to connect ase with an e*ternal database because the process will be different depending on which one you pic+ and they are all 0uite well documented at the ooforum.org, which should become the continuation of this tutorial to you. And what happened with all the techni0ues that we had learned hereG #hey remain valid. 2ou can wor+ with ase =ust the same -so we havenHt lost our time! #he only difference is in the way you open your application Iby as+ing to connect to it5. After that, you +eep wor+ing with ase the way it has been proposed in this tutorial Iinsert a sigh of relief here5. 9f you chose another database management system, you might need to adapt to the naming conventions and slight changes in S./ synta* that the new system uses, but this should be a snap to you. Also notice that there could be varying degrees of integration, with -S./ and -& offering the best level. As 9 said, 9 started writing this tutorial because 9 wanted to learn how to use databases -and ase particularly- applied to my needs, understanding enough about the sub=ect to help me remain fle*ible with the options offered and using them in the best way possible. 9 trust that you have read so far because you had similar motivations. 9 did reach my goal. 9 am not an e*pert but do go around e*plaining my friends how a database could help them with their problem and, so far, have been able to devise solutions for the Irather simple, 9 admit5 problems 9 have encountered. 9 hope that this tutorial has provided you with the same help in designing database applications that fit your needs and has given you a foundation from which to continue e*ploring ase.

(@B

Вам также может понравиться