| Mastering .NET Application Development with Oracle
Using .NET Stored Procedures in Oracle
A step-by-step guide to developing, deploying, and debugging your .NET Stored Procedures in Oracle Database 10g Release 2
Published November 2005 If you are a .NET developer, one of the most exciting features of Oracle Database 10g Release 2 for Windows is the ability to implement stored procedures using the .NET language of your choice, via Oracle Database Extensions for NET. In this installment of Mastering .NET Application Development with Oracle, you will learn a step-by-step approach for taking advantage of .NET stored procedures in your applications. You will learn how .NET stored procedures are supported, how to install and configure the Oracle Database to enable support for .NET stored procedures, how to develop and deploy .NET stored procedures, and, finally, how to debug .NET stored procedures. Supporting Architecture PL/SQL stored procedures and functions run in the same process as the Oracle Database and are stored inside of Oracle. A .NET stored procedure, on the other hand, runs in an external process and the .NET code is compiled into a ".NET assembly," which is a dynamic link library (DLL) file stored in the file system (usually on the same machine as the database). The .NET assembly is loaded into and executed inside of a "CLR host" external process named extproc.exe, which is spawned by the Windows service named <OracleHomeName>ClrAgnt. When a .NET stored procedure call is made, Oracle communicates with this external process, passing in the arguments and retrieving the results. This communication is handled by the Oracle multithreaded agent architecture. To the end user, a .NET stored procedure call appears to be no different than any other type of stored procedure call. In fact, a .NET stored procedure can be called from any environment where you could call a PL/SQL or Java stored procedure. Installation and configuration: If you are using Oracle Database 10g Express Edition, .NET stored procedures are automatically installed and configured—no additional configuration is required. In the Standard and Enterprise Editions, however, .NET stored procedures are not installed and configured by default. Here are basic instructions to get everything working for those installs:
SQL> desc countries Name Null? Type -------------- -------- ------------ COUNTRY_ID NOT NULL CHAR(2) COUNTRY_NAME VARCHAR2(40) REGION_ID NUMBERTo create the stored procedure, you use a new project type in Visual Studio .NET 2003, the "Oracle Project":
using System;
using System.Data;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
namespace MyStoredProcedure
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class Class1
{
public static string GetCountryName(string CountryID)
{
// used to return the country name
string CountryName = "";
// Get a connection to the db
// context connection is used in a stored procedure
OracleConnection con = new OracleConnection();
con.ConnectionString = "context connection=true";
con.Open();
// Create command and parameter objects
OracleCommand cmd = con.CreateCommand();
cmd.CommandText = "select country_name from countries where country_id = :1";
cmd.Parameters.Add(":1", OracleDbType.Varchar2, CountryID, ParameterDirection.Input);
// get a data reader
OracleDataReader rdr = cmd.ExecuteReader();
// get the country name from the data reader
if(rdr.Read())
{
CountryName = rdr.GetString(0);
}
// clean up objects
rdr.Close();
cmd.Dispose();
// Return the country name
return CountryName;
}
}
}
Again, other than the special connection string, this code is identical to that you would include in a client application. The context
connection=true is how you indicate that the code uses the connection of the process that called it and you may only specify context
connection=true within a stored procedure. The
OracleConnection has a new property called
IsAvailable that you can use to determine if your code is executing in the context of a stored procedure. If the
IsAvailable property returns
true, the code is executing in the context of a stored procedure. This property returns
false otherwise. You can easily use this property to build a connection string based on whether your code is executing in a stored procedure or in a stand-alone application. This allows for you code to be reused with very little effort.
Before you deploy your stored procedure, you must first build the project. Since you will debug your procedure after deploying it, make sure you perform a debug build of the project. After building the project, you deploy it to the database using a deployment wizard. At this time, you must use a SYSDBA connection to the database in order to deploy the stored procedure. If you do not have a SYSDBA connection available in the Data Connection node within the Oracle Developer Tools for Visual Studio .NET, the wizard will allow you to create one.
To deploy the stored procedure, select
Build→ Deploy Solution from the Visual Studio .NET 2003 menu bar. This will start the deployment wizard:
C:\>dir c:\oracle\10.2\database\bin\clr
Volume in drive C is Local Disk
Volume Serial Number is 94FF-538C
Directory of c:\oracle\10.2\database\bin\clr
09/10/2005 07:18 PM <DIR> .
09/10/2005 07:18 PM <DIR> ..
09/10/2005 07:18 PM 16,384 MyStoredProcedure.dll
1 File(s) 16,384 bytes
2 Dir(s) 26,689,114,112 bytes free
To verify that the procedure has been correctly deployed and functions correctly, you use SQL*Plus:
SQL*Plus: Release 10.2.0.1.0 - Production on Sat Sep 10 19:21:47 2005
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> connect hr
Enter password:
Connected.
SQL> select GetCountryName('FR') from dual;
GETCOUNTRYNAME('FR')
---------------------------------------------------------------------
France
1 row selected.
You can also execute the procedure using the Oracle Developer Tools for Visual Studio .NET. To do this, expand the HR connection, expand the Functions node, select the GETCOUNTRYNAME function, right click, and select
Run:
C:\>dir c:\oracle\10.2\database\bin\clr
Volume in drive C is Local Disk
Volume Serial Number is 94FF-538C
Directory of c:\oracle\10.2\database\bin\clr
09/10/2005 07:32 PM <DIR> .
09/10/2005 07:32 PM <DIR> ..
09/10/2005 07:18 PM 16,384 MyStoredProcedure.dll
09/10/2005 06:44 PM 11,776 MyStoredProcedure.pdb
2 File(s) 28,160 bytes
2 Dir(s) 26,681,720,832 bytes free
The directory now contains both the DLL and the .pdb file.
Because the DLL file is loaded by the extproc.exe process, you must attach to that process in Visual Studio .NET 2003 in order to debug it. Since you executed the stored procedure in the previous step, the extproc.exe process should be running. However, if you have not executed the procedure, the process will not be running. For this reason, you should execute the procedure either through SQL*Plus or the Oracle Developer Tools for Visual Studio .NET prior to attempting to debug the code.
To debug the procedure, set a breakpoint in the source code as illustrated here:
SQL> select GetCountryName('FR') from dual;
Note: Do not use the Oracle Explorer "Run" menu item to fire off the .NET procedure if the breakpoint for that procedure is set inside that same instance of Visual Studio. This will hang Visual Studio due to deadlock.
This call will invoke the procedure and SQL*Plus will appear to hang. However, the procedure should be stopped at the breakpoint in Visual Studio .NET 2003:
SQL> select GetCountryName('FR') from dual
*
ERROR at line 1:
ORA-28576: lost RPC connection to external procedure agent
ORA-06512: at SYS.DBMS_CLR, line 234
ORA-06512: at HR.GETCOUNTRYNAME, line 7
If you encounter this error, re-executing the call to the stored procedure typically restarts the extproc.exe process. Other troubleshooting tips include closing and reconnecting the connection of the caller as well as killing the extproc.exe and restarting the CLR service (to force extproc.exe to get re-spawned).
Conclusion
In this introductory look at .NET stored procedure support in Oracle Database 10g Release 2 for Windows, you have learned how .NET stored procedures are supported, how to configure the Oracle networking components, how to develop and deploy a .NET stored procedure, and how to debug a deployed procedure. You now should be ready to begin to develop and deploy .NET stored procedures in your environment.
Mark A. Williams [ mawilliams@cheshamdbs.com] is the author of the ODP.NET column in Oracle Magazine, an Oracle ACE, an Oracle Certified Professional DBA, and the author of Pro .NET Oracle Programming (Apress, 2004). Williams focuses on solutions for Oracle on Windows and contributes to the Oracle Data Provider for .NET forums on the Oracle Technology Network. |
