Using Remote Views in Visual FoxPro

Robert Green, Microsoft Corporation
July 11, 1997

Purpose of this Document

This document is designed as part of a series of demo script documents to assist customers who are evaluating Microsoft® Visual FoxPro 5.0™. It can be used by an individual developer learning new features in Visual FoxPro 5.0; or as the basis for a demo shown to other developers and software tools evaluators. This demo script requires Visual FoxPro 5.0 to be installed. Questions about this demo script should be directed via email to foxmktg@microsoft.com.

Introduction

Visual FoxPro provides developers the tools to create powerful client-server applications. A Visual FoxPro-based client-server application combines the power and user interface of Visual FoxPro with the speed, massive data storage and built-in security of an Open Database Connectivity (ODBC)-based data source or server. This gives Visual FoxPro developers the ability to create graphical client-server applications that provide maximum speed, security, and power.

Views

Visual FoxPro makes it very easy to build database applications by using views. A view is an SQL Select statement that retrieves data from one or more tables and stores the data in a cursor. By default, the data in the cursor is read-only but it is a simple matter to make the data updateable. Views can be created in code with the CREATE SQL VIEW command or created visually with the View Designer.

Once a view has been created, you can work with it in the same way you would work with a Visual FoxPro table. When you USE a view, the SQL Select that defines it is executed and the results are stored in a cursor. You can then manipulate the cursor in familiar ways. For instance, you can BROWSE the cursor, SKIP from record to record, REPLACE data, and DELETE rows.

Because views can be treated in the same manner as tables, they can be used in forms and reports. When a form is based on a view, the view is populated as the form loads, and you can bind controls on the form to fields in the view. This is no different than basing a form on a local Visual FoxPro table.

Local Views and Remote Views

A local view is a view that uses one or more Visual FoxPro tables within the current database. As an example, the following code creates a local view based on the customer table. When the view is used, the Select statement runs and retrieves all rows from the table.

CREATE SQL VIEW vwCustomerLocal ;
    AS SELECT * FROM customer 

Remote views use ODBC to talk to remote data. An ODBC data source represents a database and the information you need to access that database. For example, a SQL Server data source consists of the SQL Server database, the server on which it resides, and the network used to access that server.

A connection contains information about how to access a specific ODBC data source and is stored in a Visual FoxPro database. When you create a remote view you can base it on a connection. When you activate the remote view, the view’s connection becomes the pipeline to the remote data source. You can also set properties on the connection to optimize the communication between Visual FoxPro and the back-end.

As an example, the following code creates a connection using an ODBC data source named TastradeSQL. The code then creates a remote view based on the connection. When the view is used, the Select statement is sent to the data source and the results are returned to Visual FoxPro and are stored in the view’s cursor.

CREATE CONNECTION cnTastrade DATASOURCE "TastradeSQL" USERID "sa"

CREATE SQL VIEW vwCustomerRemote CONNECTION cnTastrade ;
    AS SELECT * FROM customer 

Parameterized Views

Parameterized views are one of the most important factors in building a fast, efficient client-server application because they minimize the amount of data pulled down from the server. The parameter is included in the Select statement’s WHERE clause and limits the result set to only those rows that meet a criteria.

As an example, an order view might use the order number as the parameter and only return a single row with information for a given order. Or it might use the customer number as the parameter and return one row for each order placed by a given customer.

The following code changes the remote view used above into a parameterized remote view. Instead of returning the entire customer table, the view will now return only the information for one customer at a time. When the view is opened, the value in the memory variable cCustID is placed into the WHERE clause of the Select statement, which is then sent to the back-end for processing. Only the data for the customer with the specified ID is sent back to Visual FoxPro.

CREATE SQL VIEW vwCustomerRemote CONNECTION cnTastrade ;
    AS SELECT * FROM customer ;
WHERE customer.customer_id = ?cCustID

Views and Buffering

Views, both local and remote, can take advantage of buffering, and therefore protect data in a multi-user environment. A buffer is a temporary holding area in memory where information can be stored. Visual FoxPro has two types of buffering: record and table. To access, modify, and write a single record at a time, use record buffering. To buffer the updates to several records, use table buffering.

When buffering is in effect, changes are made to the buffered data, not the original data. The TABLEUPDATE() function is used to save the data in the buffer to the actual data. If the data can not be updated, perhaps due to a validation rule or an update conflict with another user, TABLEUPDATE() will return .F. To abandon changes made in the buffer, use the TABLEREVERT() function.

Using buffering with remote views enables users to perform batch processing. This means that data can be moved from the back-end server into Visual FoxPro and manipulated locally. When additions and/or modifications to the data have been made, TABLEUPDATE() is issued and Visual FoxPro sends the updated information back to the server. This greatly reduces the network traffic in client-server environments.

When working in a multi-user environment, it is possible for several users to attempt to make changes to the records on the remote server simultaneously. Visual FoxPro will detect whether the information has been changed by another user. You can write code to handle these types of conflicts in whatever manner you choose which provides you with tremendous flexibility.

Developing and Prototyping with Local Views

In contrast to remote views, which use back-end server data via ODBC, local views use Visual FoxPro tables. In all other respects, local views work in the same manner as remote views. They can be used in forms and reports, take advantage of buffering, and can be parameterized.

Using parameterized local views provides several benefits. You can build a prototype of your client-server application using local views. To do this you would build the application using parameterized local views that use Visual FoxPro data. This enables you to develop and test the application without needing to talk to the back-end server. You can then replace the local views with the appropriate remote views to develop, test, and deploy the application using the back-end data.

If you develop using local views you can build all of your applications in the same manner, whether they are multi-user desktop based or client-server. Since there is no paradigm shift involved in building client-server applications, both your learning curve and your development time are significantly reduced.

The ability to easily move between local and remote data also provides your applications with a built-in a migration path to using back-end data. An application can start out using local Visual FoxPro data and then later switch to using remote data.

Demo: Using Remote Views in Visual FoxPro

The purpose of this document is to illustrate the power and simplicity of using remote views in Visual FoxPro to create client-server applications. A simple data entry form is created that allows the viewing and editing of SQL Server data. This demo script requires access to the SQL Server Pubs sample database.

Create an ODBC Data Source

Use the ODBC Data Source Administrator to create a SQL Server data source that connects to the Pubs sample database. The data source should be named Pubs.

Create a Database and a Connection to SQL Server

In Visual FoxPro create a new project by entering Create Project csdemo in the Command window.

Create a new database by highlighting Databases in the Project Manager and choosing New. Name the new database csdemo. Close the Database Designer window once it appears.

Create a new connection in the database by expanding the database in the Project Manager, highlighting Connections,and choosing New. In the Connection Designer window, choose the Pubs data source from the Data Source list. Enter a valid userid and password to connect to SQL Server. Choose Verify Connection to test that you can actually connect to SQL Server. Close the Connection Designer and save the connection, naming it cnPubs.

Create a Parameterized Remote View

Create a remote view by highlighting Remote Views in the Project Manager and choosing New. In the Select Connection or Data Source dialog, highlight the cnPubs connection and choose OK. Visual FoxPro will then connect to SQL Server and present, in the Open dialog, a list of tables and views in the Pubs database. This enables you to easily see which tables and views are available in the SQL Server database. Select the authors table and choose Add. Then choose Close.

The View Designer is used to create views which consist of SQL Select statements that return cursors. The Fields tab of the View Designer is used to specify the fields to include in the view. Choose Add All to retrieve all of the fields from the authors table. The Filter tab is used to limit the numbers of rows that appear in the view. To make the view parameterized choose Authors.au_id from the Field Name list and type ?cAuID in the Example textbox.

In the Update Criteria tab check Send SQL updates to have Visual FoxPro send updates to authors back to SQL Server. Close the view and save it as vwAuthor.

Test the remote view by browsing it in the Project Manager. Highlight the view and choose Browse. Because the view is parameterized you will need to supply a value for the author’s id. Enter ‘172-32-1176’ in the View Parameter dialog. You should see the author record for Johnson White in the Browse window.

Note: You must enter the quotes because the author id is a character field.

You can also test the view by typing Use vwAuthor in the Command window and browsing.

Type Use In vwAuthor in the Command window to close the view and disconnect from SQL Server.

You have now created a parameterized remote view that returns the information for one author at a time. The remote view uses a named connection, which is based on an ODBC data source. Next you will create a form that uses this remote view.

Create a Form

You will now create a form to view and edit author information. Highlight Forms in the Project Manager and choose New. The first step in creating this form is to add the remote view to the form’s data environment, which consists of all the tables, views, and relationships that are to be opened when you run or modify the form. The data environment is saved with the form or report and can be modified in the Data Environment Designer.

Right click on the new form and choose Data Environment. In the Add Table or View dialog choose Views. Select the vwAuthor view and choose Add, followed by Close. In the Data Environment window, highlight the word Fields in the vwAuthor remote view and then drag that onto the form. This will add controls for each field in the view.

Note: Before adding the controls to the form, Visual FoxPro will open the view so you will need to supply an author ID in the View Parameter dialog.

Change the cursor’s BufferModeOverride property to 3 - Optimistic row buffering. This will turn on row buffering for the remote view and allow you to make changes locally in the buffer and then send the changes to the back end. With optimistic buffering, records are locked only when the changes are made, rather than when the edits begin.

If this were a traditional Visual FoxPro application, you might have the author form appear with the first author displayed. The user could then scroll from record to record via navigation buttons for Next, Prior, etc. In a client/server application you want to take a different approach. You would not bring all of the records down to the client for the user to scroll through. Rather, you would want to bring down one author at a time and give the user a way to specify which author to look at.

The author form in this demo will load with no data displayed. The user can then enter the id of an author and, upon exiting the author id field, the author’s information will be retrieved from SQL Server and displayed in the form.

To accomplish this, change the NoDataOnLoad property of the view’s cursor to .T. When the form loads, there will be no data in the view and the textboxes will be empty. Close the Data Environment.

Select the author id textbox and in the Properties window change its ControlSource property to (None). Next put the following code in the textbox’s Valid method. This code sets the view’s parameter to the value entered in the textbox. The view’s Select statement is resent to the server and a new author’s information is returned and is now in the view’s cursor. The form is then refreshed with the new information.

cAuID = This.Value
= REQUERY('vwAuthor')
ThisForm.Refresh

Run the form, saving it with the name csDemo. Notice that no data appears. Enter 172-32-1176 (without the quotes this time) in the author id textbox and tab off. The form should then display the information for Johnson White. Enter 213-46-8915 in the author id textbox and tab off. The form should then display the information for Marjorie Green.

You have now created a very simple read-only client/server application! You have used a remote view and a form to retrieve one author at a time. Next you will add the capability to save data and delete authors.

Enable Saving of Author Information

Go back into design view and add a command button to the form. Set the Caption to Save, the Name to cmdSave, and put the following code in the command button’s Click method. This will attempt to save the information in the form back to SQL Server. Visual FoxPro will be informed by SQL Server if the update was successful.

IF NOT TABLEUPDATE()
    MESSAGEBOX("Update failed")
    TABLEREVERT()
ELSE
    MESSAGEBOX("Update succeeded")
ENDIF

Run the form and enter 172-32-1176 in the author id textbox and tab off. Change the author’s address and choose Save. Enter 213-46-8915 in the author id textbox and tab off. This will display the author’s information. Now re-enter 172-32-1176 in the author id textbox and tab off. The first author’s updated data should be displayed on the form.

Although this form is simple, it is quite interesting. When you enter the author id, Visual FoxPro sends a SQL Select statement to the back-end, which then sends back the information for the requested author. This data resides in a buffered cursor, which is a local copy of that data. You can make changes to the buffer and when the Save button is pressed, Visual FoxPro sends a SQL Update statement to the back-end to save the data. The back-end then informs Visual FoxPro whether the update succeeded.

Enable Deleting of Authors

Go back into design view and add a second Command button to the form. Change the Caption to Delete, the Name to cmdDelete, and add the following code in the Command button’s Click method. This will cause Visual FoxPro to pass to SQL Server a request to delete the current author. Visual FoxPro will be informed by SQL Server if the deletion was successful.

DELETE
IF NOT TABLEUPDATE()
    MESSAGEBOX("Delete failed")
    TABLEREVERT()
ELSE
    MESSAGEBOX("Delete succeeded")
ENDIF

Run the form. Enter 172-32-1176 in the author id textbox and tab off. Try to delete the author. The delete fails because in the SQL Server Pubs database there is a relationship defined between authors and titles, and you can not delete an author if they have written a book.

When the Delete button is pressed, Visual FoxPro sends a SQL Delete statement to the back-end to delete the author. The back-end then informs Visual FoxPro whether the deletion succeeded, which in this case is not the case. Next you will enhance the form to give additional information on why an update or delete failed.

Add Better Error Checking to the Form

The previous code successfully prevented you from deleting the author, but it didn’t tell you why the delete failed. To fix this, go back into design view and change the Delete button’s Click method code to the following. This code will now display the error message that is returned by SQL Server.

DELETE
IF NOT TABLEUPDATE()
    * Retrieve and display the ODBC error.
    AERROR(aSQLError)
    MESSAGEBOX(aSQLError[3])
    * Discard the changes in the buffer.
    TABLEREVERT()
ELSE
    MESSAGEBOX("Delete succeeded")
ENDIF

The AERROR() function is used to retrieve error information. It takes as an argument the name of an array to create. If the error originates from the ODBC data source the third column in the array contains the error message returned from that data source.

Run the form and enter 172-32-1176 in the author id textbox and tab off. Try to delete the author. Again the delete fails, but this time you see the error message sent by SQL Server.

Note: The error message displayed is in the language of the back-end. In an actual application you would translate it into something the user could understand.

Add Multi-user Capabilities to the Form

A client/server application is inherently multi-user. The data resides in SQL Server (or other back end) and many different clients can connect to it. You will now add to this form the ability to detect update conflicts.

Go back into design view and set the form’s DataSession property to 2 - Private Data Session. This will allow you to run multiple instances of the form and simulate a multi-user situation.

Next, change the Save button’s Click method code to the following. This will attempt to update the author’s record and not only display the SQL Server error message if the update fails, but also rerun the view’s query and display the updated author information.

IF NOT TABLEUPDATE()
    * Retrieve and display the ODBC error.
    AERROR(aSQLError)
    IF aSQLError[1] = 1526
        * If an ODBC error the message is in column 3.
        MESSAGEBOX(aSQLError[3])
    ELSE
        * If a VFP error the message is in column 2.
        MESSAGEBOX(aSQLError[2])
    ENDIF
    * Discard the changes in the buffer.
    TABLEREVERT()
    * Set the view's parameter to this author's id.
    cAuID = ThisForm.txtAu_ID.Value
    * Refresh the data in the view cursor. 
    Requery('vwAuthor')
    * Display the updated author information.
    ThisForm.Refresh
ELSE
    MESSAGEBOX("Update succeeded")
ENDIF

The AERROR() function creates an array. The first column in the area contains the error number. If the error originated in the ODBC data source then the value in that column will be 1526 and the error message will be in the third column in the array. If the error originates in Visual FoxPro then the error message will be in the second column in the array.

Close and save the form. Enter Do Form csdemo in the Command window twice to run two different versions of the form.

In both forms enter 172-32-1176 in the author id textbox and tab off. In the first form change the author’s address and press the Save button. The update should succeed. In the second form change the author’s address to something else and press the Save button. The update will fail due to the conflict and when the form refreshes you can see the updated address data as it appears on the server.

You have now created a client-server application that retrieves one row of data at a time and allows the user to update and delete authors. The user is informed whether data modifications succeed or fail.

Summary

Visual FoxPro is an excellent solution for client-server development. Through ODBC, users can create connections to back-end data and can then create remote views based on these connections. Remote views are SQL Select statements that return data into cursors, which can then be made updateable. They can be used in forms and in reports. You can use the same Visual FoxPro commands and functions with views and tables; therefore you do not need to learn an entirely new language to create a client-server application. Views in Visual FoxPro enable developers to prototype locally using the Visual FoxPro engine, and then move the application seamlessly to a true client-server environment.

Frequently-Asked Questions

How can I learn more about using remote views with Visual FoxPro 5.0?

A good place to start is the whitepaper entitled, Integrating SQL Server with Visual FoxPro . Also, see Chapter 8, "Creating Views," in the Developer's Guide, part of the documentation that came with your copy of Visual FoxPro 5.0.

Can Visual FoxPro 5.0 use any back-end data?

You can create remote views that work with any ODBC data source. There are over 170 ODBC drivers available today.

Can I migrate my existing Visual FoxPro applications to use SQL Server or Oracle data?

The Upsizing Tools built into Visual FoxPro enable users to create solutions in Visual FoxPro and “upsize” them to run on Microsoft SQL Server or Oracle back ends. The Upsizing Wizards completely automate the process of upsizing data from Visual FoxPro to Microsoft SQL Server or Oracle. The wizards preserve the database structure, including data, indexes and defaults. They also automatically convert the Visual FoxPro validation rules to Microsoft SQL Server or Oracle equivalents. In addition, all of the relationships and referential integrity are maintained after upsizing.

Can I obtain an evaluation copy of Visual FoxPro 5.0?

In the United States and Canada, Visual FoxPro 5.0, and all Microsoft products, are available with a 30-day money back guarantee from software resellers. Therefore, if you purchase the product on a trial basis, and decide not to keep it, simply return it for a full refund.


© 1997 Microsoft Corporation. All rights reserved.