DEVELOPER: ODP.NETFollowing the Changes, Part TwoBy Mark A. Williams Use database change notification with ODP.NET and Oracle Database 10g Release 2. You can access data from Oracle databases in .NET applications in different ways, but for features and performance, Oracle Data Provider for .NET (ODP.NET) is your best choice. In the last issue ("Following the Changes, Part One," March/April 2006), I examined the new Database Change Notification feature introduced in Oracle Database 10g Release 2. In this issue, I examine in greater detail the classes that support change notification and show how to take advantage of additional ODP.NET features. First, a ReviewThe Database Change Notification feature enables the database to automatically notify your application when a change occurs. This change can be in one or more of the values in a result set, in the underlying schema objects, or in the state of the database itself. Using Database Change Notification is a three-step process: You register a query with the database, receive notification when a change occurs, and respond to the notification in your application. Any datatype can be included in the registered query, and all objects can be queried, with the exception of materialized views; fixed tables and views, such as V$ tables; and objects accessed through a database link. The ODP.NET notification framework—in conjunction with Database Change Notification—supports the following activities
The sample code download in the last issue demonstrates the Database Change Notification process and uses the default values for the ODP.NET objects that support change notification. Two important limitations are inherent in this sample code: Only a single change notification event is generated by the database per registration, and the application does not retrieve the actual changed data. In this issue, I extend this sample code to generate and receive multiple change notifications in a single registration and provide the information needed so you can retrieve the changed data. To retrieve the changed rows, you need to include a pseudocolumn—ROWID—in the registered query. The ROWID PseudocolumnThe pseudocolumn construct allows you to include a column name in a query for a column that is not part of a table definition. However, you use a pseudocolumn in a query exactly as you would a real table column. Various pseudocolumns are available in Oracle Database; they are documented in chapter 3 of the Oracle Database 10g Release 2 SQL Reference manual. A ROWID value represents the address of a particular database row. Selecting a ROWID as part of a query is trivial—you simply include the ROWID pseudocolumn in the query text. The ROWID pseudocolumn is of particular interest when your application uses Database Change Notification because it allows the application to retrieve only rows that have changed (rather than reissuing the original query on a change notification event to retrieve all the rows that make up a result set). To retrieve only the changed rows, include the ROWID pseudocolumn as part of the query you register with the database. Alternatively, set the AddRowid property of the OracleCommand object to true, and ODP.NET will automatically add the ROWID pseudocolumn to your registered query. Listing 1, also available with the complete code download for this article, contains the main class file from the sample code download and registers a Database Change Notification query: select rowid, first_name, last_name, salary from employees where employee_id = :1 Code Listing 1: Main class file
using System;
using System.Threading;
using System.Data;
using Oracle.DataAccess.Client;
namespace DatabaseChangeNotification02
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class ChangeNotificationSample
{
// connection object for the database
static OracleConnection con;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
// sql statement to create result set that we will watch for changes
// include the rowid to use to retrieve data that has changed
string sql = "select rowid, first_name, last_name, You can include ROWID in the query you register or set the OracleCommand object AddRowid property to true. In either case, the ROWID value is included as part of the notification data, which allows you to construct a new query to retrieve data based on that ROWID. The database passes the ROWID value to your application as part of the OracleNotificationEventArgs parameter, and this code passes this parameter to the change notification event handler:
public static void
OnDatabaseNotification(
object src,
OracleNotificationEventArgs args)
You can then access the ROWID through the Details property of the args parameter. The ROWID is represented as a String object in your .NET code. This code accesses the ROWID and assigns the value to an OracleParameter object named p_rowid: p_rowid.Value = args.Details.Rows[0]["rowid"] After you have retrieved the ROWID for a changed row, you construct a new query to get that row from the database. This code does just that: select rowid, first_name, last_name, salary from employees where rowid = :1 As you can see in this example, the query for retrieving the changed row differs from the original query in only one way: The ROWID, rather than the EMPLOYEE_ID, is used in the WHERE clause. Two Key ClassesThe OracleNotificationRequest and OracleNotificationEventArgs classes form the backbone of the Database Change Notification support in ODP.NET. Each of these classes is documented in ODP.NET and available in the Microsoft Visual Studio online integrated help. OracleNotificationRequest. One important property of the OracleNotificationRequest class is IsNotifiedOnce. This Boolean property has a default value of true and is used to inform the database about whether you wish to receive a notification for each change that occurs or only a single notification. When the property is set to true, the server's notification registration will be removed after the first change. When the property is set to false, the registration will persist, regardless of the number of changes. In the sample code, the property is set to false, allowing the notification registration to persist: cmd.Notification.IsNotifiedOnce = false;
OracleNotificationEventArgs. The Oracle NotificationEventArgs class exposes the data (and metadata) associated with a change event to your application. Several properties exposed by the OracleNotificationEventArgs class may be useful in your applications:
Sample Code and BeyondThe sample code download (revised from Part One) responds to multiple database change notifications (rather than a single notification) and retrieves the changed row from the database. I encourage you to download and experiment with it. For example, you can extend this code to retrieve multiple changed rows and loop through all the rows in the Details DataTable (accessed via the args parameter) and then build a query such as this: select rowid, first_name, last_name, salary from employees where rowid = :1 or rowid = :2 or rowid = :3 Set breakpoints in the code, and run the sample, using the debugger. Examine the properties of the objects. Use this code as a starting point for implementing Database Change Notification in your applications, and experience its benefits for yourself. Mark A. Williams (mawilliams@cheshamdbs.com) is an Oracle ACE, Oracle Certified Professional DBA, and the author of Pro .NET Oracle Programming (Apress, 2004). He focuses on solutions for Oracle on Windows and contributes to the Oracle Data Provider for .NET forums on the Oracle Technology Network. |
