Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Programming with Java 1 Chapter 13 Storing Information, Object Serialization, and JDBC © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 2 Objectives • Understand the purpose of streaming classes. • Use the System class for input and output to standard devices. • Save an object to a file. • Retrieve an object from a file. • Retrieve information from a database using the JDBC API. • Write SQL Select statements to create a ResultSet. • Use SQL action queries to update an existing database. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 3 Streams • The most basic of input/output with Java is done with streams. • The stream can flow from the program to the screen, from a keyboard to the program, to/from a disk file, other storage media, to a printer, or even to a network or the Web. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 4 Input Stream and Output Stream © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 5 Output to the Screen • • • • • You can send an output stream to the "standard output device" or read an input stream from the "standard input device." The standard input device is normally the keyboard and the standard output device is your monitor. Java's System class contains utilities for reading from the standard input device and writing to the standard output device. Two methods to send text to the screen; println method-automatically adds a carriage return, and print method--does not add a carriage return. Java, like C and C++, has three standard IO (input/output) objects: in, out, and err. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 6 Saving an Object in File • A common term in programming is persistence. • How can you make data persist, or still be available, from one run of the program to the next? • If you want to save data from one program execution to the next, you must have some way to store the data. • Java has been able to store bytes of information and the contents of individual variables into a disk file. • Using this technique, the programmer is responsible for writing all data into a disk file and reading it again for the next program execution. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 7 Applet vs. Applications • Although you can perform disk reading and writing from some versions of the applet viewer, you cannot access disk files from an applet running in a browser. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 8 Object Serialization • From JDK 1.1, Java added a powerful tool for persisting an entire object as a single unit. • Using object serialization, you can use an output stream for writing objects. • When you store an object, you need to keep the contents of the variables but not the methods. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 9 Object Serialization Continued • You can create a file that stores the contents of the class variables for multiple instances of a class. • The program that later inputs the information from the file can read the values for the class variables into an instance of the class, or multiple instances, one for each object stored in the file. • If your object contains a reference to another object you also must store the data of the referenced object. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 10 Creating a Serializable Class • You must import java.io.* and implement the interface Serializable. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 11 Steps of Writing an Object • Create a FileOutputStream object. • Create an ObjectOutputStream object. • Obtain the data from the text fields (after the user enters them). • Create an event for storing the data for one object. • After all objects have been stored, close the ObjectOutputStream object. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 12 FileOutputStream Object • The FileOutputStream class establishes a link from the program to an actual disk file. • If the file does not already exist, this class creates the file. • Declare the output object at the class level - FileOutputStream outputEmployee; • Instantiate the object and assign the file name in a method inside the application - outputEmployee = new FileOutputStream("Employee.txt");. • You must place this statement in a try/catch block, catching Exception. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 13 The ObjectOutputStream Object • • • • You can use the FileOutputStream object for any type of output stream. To save an object using the stream, you must also set up an ObjectOutputStream class. You declare the object as a class variable, and then assign the ObjectOutputStream object in a class method. The argument for the ObjectOutputStream constructor is the name of a FileOutputStream object. //Declare the object output stream ObjectOutputStream objSaveEmployee; //Instantiate the object stream and associate it to the file stream objSaveEmployee = new ObjectOutputStream(outputEmployee); © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 14 Event for Storing Data • The writeObject method of the ObjectOutputStream class saves the contents of the named object. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 15 Entering Information © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 16 Reading an Object • The steps for reading an object are Create a FileInputStream object. Create an ObjectInputStream object. Obtain the data for one object from the file. Create an event to display the object's data in text fields. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 17 The FileInputStream andObjectInput Stream Objects • The FileInputStream object associates the project with a file. • And the ObjectInputStream enables you to read the entire object with one read command. • Declare the FileInputStream and ObjectInputStream objects as class variables. • Then instantiate the objects in a class method. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 18 Event for Displaying Data • You can create an Employee object and read the information from the disk file. • Read the information using the readObject method of the ObjectInputStream; you must cast the result into an Employee object. • Then you can use the Employee object's get methods to display the data to the screen. • You can check for the end of file by catching an EOFException. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 19 DataBase Connection with the JDBC API • The JDBC API is a set of classes available in JDK 1.1 or higher, in the java.sql package. • The classes and methods allow Java applets and applications to interface with data that is stored in many formats including relational, hierarchical, and network databases. • JDK 1.2 (Java 2) greatly improved database handling, providing many additional features, such as scrollable recordsets. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 20 DataBase Connection with the JDBC API Continued • • • Many issues can complicate accessing databases in Java. If you are using an applet, security is an issue. You can easily access a database on the local machine, but to access a database on a server, you must properly set up security and sign the applet (see Chapter 15). For optimal database performance on the Web, you must download and install drivers that are specific to the database format. The JDBC classes handle communication between your Java program and a database driver. Java 2 comes with JDBC, but not the manufacturer-specific database drivers. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 21 DataBase Connection with the JDBC API Continued • The only driver that does come with Java is the JDBC-ODBC Bridge, which we will use in this chapter. • The JDBC-ODBC Bridge takes advantage of Open DataBase Connectivity (ODBC), which is Microsoft's implementation of universal data access for diverse database formats. • Nearly all database formats provide ODBC drivers. • If an ODBC driver is available to access a database format, files in that format can also be accessed from Java. • The following sections introduce you to JDBC and SQL (structured query language). © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 22 Setting up DSN • A Data Source Name (DSN) creates a link between a physical data file and a name that you use in a program. • Before using JDBC in a Windows environment, you must create a DSN, which registers your database file on the computer. • You use the ODBC icon on the control panel to register databases. • Follow the six steps in the book to register your database file. • You set up the DSN only once for a database file in a given location. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 23 Loading the JDBC-ODBC Bridge Driver • • • In your code, you must connect to the driver using the Class.forName method. Connect to Sun's JDBC-ODBC Bridge driver using this statement. Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); If you are using Microsoft's J++ or Internet Explorer, you cannot load Sun's driver, but must load Microsoft's version of the Bridge instead: Class.forName("com.ms.jdbc.odbc.JdbcOdbcDriver"); © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 24 Loading the JDBC-ODBC Bridge Driver Continued • If you need to be able to load either driver, you can use try/catch blocks and attempt to load one driver. • If that fails, load the other one. If both fail, a ClassNotFound exception occurs. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 25 Connecting to the Database • Your next step is to connect to the database using the name that you registered as a DSN. • This name is included in a string literal. • For example, if we registered the DSN as MerryPeas the string becomes “jdbc:odbc:MerryPeas“. • Use this string with the DriverManager.getConnection method and assign to a Connection object. • Notice that the connection is placed inside of an exception testing for an SQLException. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 26 Creating a ResultSet • A ResultSet object contains a collection of records from the database. • To create a ResultSet, you must declare a Statement object and call the Connection object's createStatement method. • Then you can use the Statement object to create a query Statement cmdEmployees; ResultSet rsEmployees; • You can create a SQL query. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 27 Creating a ResultSet Continued • The following example selects all fields and all records in the Employees table of the MerryPeas database. • The SQL string is : Select * from Employees; © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 28 Creating a ResultSet Continued • Use this string as an argument for the executeQuery method of the Statement object. try { //Connect to the database conEmployees = DriverManager.getConnection("jdbc:odbc:MerryPeas"); //Create a ResultSet Statement cmdEmployees = conEmployees.createStatement(); ResultSet rsEmployees = cmdEmployees.executeQuery( "Select * from Employees"); } catch(SQLException error) { System.err.println("Error:" + error.toString()); } © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 29 Creating a ResultSet Continued • You can create an SQL statement to create a ResultSet that matches a given condition. • You can allow the user to enter the desired name and substitute the literal name with a string variable. • Let’s look at some examples: ResultSet rsEmployees = cmdEmployees.executeQuery( "Select * from Employees Where [Last Name] = 'Rigner'"); ResultSet rsEmployees = cmdEmployees.executeQuery( "Select * from Employees Where [Last Name] = '" + strLastName + "'"); • You can create a PreparedStatement outside of Java and call it from the Java code. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 30 Employees table in MerryPeas Database © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 31 Retrieving a Record • When you first open a ResultSet, the current-record pointer is located just prior to the first record. • You call the ResultSet's next method, which has a dual purpose. • The next method moves the current-record pointer (also called the cursor) to the first record and returns boolean true or false. • A true means that the next record exists and a false means that no more records exist in the ResultSet (the operation was successful or unsuccessful). © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 32 Retrieving a Record Continued • You must have a current record before you can access the data fields in a record. • This code moves to the first (next) record and adds the contents of the Last Name field to a List component called lstNames. • The getString method retrieves the data for the specified string field. • Make sure to enclose the next method in a try/catch block. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 33 Looping through a ResultSet • You can step through all records in a ResultSet using a loop. • The boolean condition (rsResultSet.next()) tests true as long as records remain in the ResultSet, and tests false when no more records remain. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 34 Accessing the Data Fields • Access the data in database fields by using the appropriate method for the data type. • Use getString for string fields; use getFloat or getInt for float or int fields. • You must give the correct field name, including spacing. For example : lblFirstName.setText(rsEmployees.getString("First Name")); lblSSN.setText(rsEmployees.getString("SSN")); lblPhone.setText(rsEmployees.getString("Phone Number")); © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 35 Accessing the Data Fields Continued • If you declare a ResultSet object at the class level, you cannot access the ResultSet in any method other than the one in which it was created. • You must actually pass the ResultSet to any other method that needs to reference the data. • Failure to do this results in a null pointer error. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 36 Closing the Connection • Make sure that the database connection is closed at the termination of the program. • Place the statements in the stop method of an applet. • If you are writing an application, place the code in your exit routine. • You can avoid an exception for attempting to close a connection that doesn't exist by testing for null. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 37 SQL • Java's JDBC uses Structured Query Language (SQL) to create a ResultSet. • SQL is an industry-standard language that you can use to access data in nearly every relational database format. • Although the basic SQL statements are standardized, some vendors include extensions that are non-standard. • You will see several ways to use an SQL statement in code to create a ResultSet or to directly update a database. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 38 Types of SQL Statements • SQL Select statements select data from a database and return that data to the program. • You can specify which fields from which table or tables, and select only certain records based on criteria. • You can also write SQL statements that perform actions on the database rather than just select data. • The actions that you can perform include inserting records, deleting and updating records, as well as modifying the structure of a database, such as adding tables and fields. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 39 Writing SQL Select Statements • Multiple-word field names must be enclosed in square brackets or accent grave marks. • The optional Distinct drops out duplicates so that no two records are alike. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 40 The SQL Select Statement— General Form SELECT [Distinct] Field(s) FROM Table(s) [IN Database] [WHERE Criteria] [GROUP BY Field(s)] [HAVING GroupCriteria] [ORDER BY Field(s)]; © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 41 The SQL Select Statement— Examples SELECT [Last Name], [First Name], Phone FROM Patient ORDER BY [Last Name], [First Name]; SELECT DISTINCT `Last Name` FROM Patient ORDER BY `Last Name`; SELECT * FROM Patient WHERE [Last Name] = "'" + txtSearch.getText() + "';" SELECT * FROM Patient, Insurance WHERE Patient.[Insurance Company Code] = InsuranceCompany.Code; © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 42 Writing SQL Select Statements Continued • Note that the last example joins the Patient and Insurance tables so that the actual name of the company, not just the Code, is included in the results. • This easy method for joining tables creates a ResultSet that is nonupdateable and does not include any patients without a matching entry in the InsuranceCompany table, including those with no insurance. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 43 Writing SQL Select Statements Continued • To make a joined ResultSet updateable and complete, you must use the Join clause of the SQL Select statement. • The closing semi-colon (;) is specified in the SQL standards. Many versions of SQL do not require the semi-colon, but some do. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 44 SQL Queries • A few simple queries: • Example :SELECT [Last Name], [First Name] FROM Employee; • The ResultSet created from this SQL statement will include only the Last Name and First Name fields from the Employee table. • Example: SELECT * FROM Employee; • This ResultSet will include all fields (* = all fields) from the Employee table. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 45 SQL Queries Continued • Example: SELECT Employee.[Last Name], Employee.[First Name], InsuranceCompany.Name FROM Employee, InsuranceCompany WHERE Employee.[Insurance Company Code] = InsuranceCompany.Code; • This ResultSet will include three fields: Last Name and First Name from the Employee table and the Name field from the InsuranceCompany table. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 46 SQL Queries Continued • It joins the two tables, in order to retrieve the company name that matches the Insurance Company Code field from the Employee table. • For field names that contain a space, you must enclose the name with either square brackets or the accent grave symbol (`). © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 47 Where Clause • You can use a Where clause to join tables. "WHERE Employee.[Insurance Company Code] = InsuranceCompany.Code" • You can also use a Where clause to select only those records that meet specific criteria. "WHERE Employee.[Insurance Company Code] = ‘ABC‘ " "WHERE Employee.[Insurance Company Code] = '" + strSelectedCompany + "'" © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 48 Where Clause Continued • Note the single quotes and double quotes. • You can include multiple conditions in a Where clause. "WHERE Employee.[Insurance Company Code] = InsuranceCompany.Code " + "AND Employee.[Insurance Company Code] = '" + strSelectedCompany + "'" © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 49 Comparing Database Fields to Java Fields • The syntax of the criteria in a Where clause depends on the location of the data. • You must specify database fields differently from program variables. • And string fields must be compared only to string data; numeric fields compared only to numeric data. • Otherwise your program will fail. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 50 Comparing Database Fields to Java Fields Continued • Look at the following examples: //Compare a string field to a string variable "WHERE [Last Name] = '" + strName + "'" //Compare a string field to a string from a text component "WHERE [Last Name] Like '" + txtSearchName.getText() + "'" //Compare a string field to a string constant "WHERE [Last Name] = 'Jones'" © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 51 Comparing Database Fields to Java Fields Continued //Compare a numeric field to a numeric variable "WHERE [Duration] = " + intSearchMinutes //Compare a numeric field to a property "WHERE [Duration] = " + Float.valueOf(txtNumber.getText()).floatValue() //Compare a numeric field to a numeric constant "WHERE [Duration] = 15" © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 52 The Order by Clause • It is incredibly easy to sort your ResultSet in SQL—just use the Order By clause. • You can order by one or more fields, in ascending or descending sequence. • If you don't specify the direction, ascending is assumed. "ORDER BY [Last Name], [First Name]" "ORDER BY InsuranceCompany.Name ASC" "ORDER BY DateDue DESC" © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 53 Updating a Database • You can also update a database from a Java program. • You use the Statement object's executeUpdate method, which works with SQL statements. • Many different errors can occur while updating a database. • If you get a "null pointer exception," it is likely that the update or query has failed. • With an update this could be a result of many different factors— a mandatory or key field left blank, duplicate records, incorrect data type, or not a valid format. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 54 SQL Updates • You can use your validation techniques from Chapter 6 to avoid some of the problems; others problems may not be easy to find. • You will see a different way to program, using methods to directly update a database. • You will write SQL action queries, such as Insert, Delete, and Update, and execute the actions using the executeUpdate method of the Statement object. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 55 SQL Updates • Action queries operate directly on the database, not on any open ResultSet. • To execute an SQL action query on a database, you must have an open Connection. • The user can add new records, delete records, or edit (modify) existing records. • For the delete and edit options, the user first displays the desired record and then clicks the appropriate button. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 56 Adding a Record • Adding a record is a two-step process. • When the user clicks the Add button, you must clear the text fields for data entry and set the focus in the first text field. • After the user enters the data for the new record, he or she will click the OK (or Cancel) button. • To actually add a new record to the database, you use the SQL Insert statement. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 57 The SQL Insert Statement— General Format Insert Into TableName (Fieldlist) VALUES (ListOfValues); © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 58 The SQL Insert Statement— Examples Insert Into Employees ([Last Name], [First Name]) Values ('Berry', 'Terry'); strSQL = "Insert Into Employees ([Last Name], [First Name]) " + "VALUES ('"+ txtLastName.getText() + "', '" + txtFirstName.getText() + "');" © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 59 User Interface for the Update Program © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 60 The Add Method • In the Add method, you must clear the contents of the text fields so that the user can enter new values. • Also, it's a good idea to give the user only two choices once the Add operation starts: OK (which saves the new record) or Cancel (in case of a mind change). • We will use the Add button for a dual purpose. Once the Add is in progress, the button's caption changes to "OK". After the user clicks OK or Cancel, the caption of the Add button changes back to "Add" © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 61 The Save Method • The Save method, which is executed when the user clicks OK at the end of an Add, must perform validation. • If the data passes the validation, then the record is added. • Use the Statement object's executeUpdate method to execute the SQL Insert Into statement. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 62 Modifying an Existing Record • To allow users to modify an existing record, you need to display the record's current contents and allow them to make changes. • In the example, the user selects a Last Name from the list and the field contents display in the text fields. • Then the user should be able to change the contents of the fields and click the Save button. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 63 The SQL Update Statement— General Format Update TableName Set FieldName = FieldValue, FieldName = FieldValue, . . . Where Criteria; © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 64 The SQL Update Statement— Examples Update Employee Set [Last Name] = 'Bowser' Where [Employee Number] = 500; Update Visit Set Date = #1/1/2000# Where Date = #1/1/1900#; strSQL = "Update Employees " + "Set [Last Name] = '" + txtLastName.getText() + "', " + "[First Name] = '" + txtFirstName.getText() + "', " + "Where [SSN] = " + txtSSN.getText(); © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 65 The Edit Method • The Edit method executes when the user clicks the Save button after making changes to an existing record. • What if the user clicks the Save button before displaying the record first. • We need to first check if the record is displayed. • After validation, use the executeUpdate method of the Statement object, passing it an SQL Update statement. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 66 Deleting a Record • Deleting a record is similar to modifying an existing record. • The user must display the record to delete and then click the Delete button. • The Delete statement requires a Where clause that specifies which record(s) to delete. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 67 The Delete Method • When writing the routine for handling the delete, consider the tasks: Delete the record from the database. Delete the name from the list. Clear the record from the text fields. • To delete the record from the database, use the executeUpdate method of the Statement object to execute an SQL Delete Statement. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 68 Joins • One of the primary characteristics of relational databases is that data are stored in multiple tables that are related to each other by common fields. • Data can be stored once and used in many places by using the relationships between tables. • You will often want to select some fields from one table and other fields from another related table, maybe even fields from several related tables. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 69 Joins • Although you can join tables using the Where clause, the resulting ResultSet is not updateable. • If you want the user to be able to update the data, you must use a Join clause in the SQL Select statement. • Joins are of three types: inner join, left join, and right join. • The left join and right join are often called left outer join and right outer join. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 70 SQL Joins Join Type Selects Inner join Only records that have matching records in both tables. Left join All records from the first table and only the matching records from the second table. Right join All records from the second table and only the matching records from the first table. © 2002 The McGraw-Hill Companies, Inc. All rights reserved. Programming with Java 71 The Join Clause • To code a Join clause, name only the first table in the From clause (this becomes the left table). • Then specify the join type and the second table name; then write the relationship for the join using the On clause. • Example: Select [Last Name], [First Name], [Insurance Company Code], Name From Patient Left Join InsuranceCompany On Patient.[Insurance Company Code] = InsuranceCompany.Code; © 2002 The McGraw-Hill Companies, Inc. All rights reserved.