ヘッダーをスキップ
Oracle® Data Provider for .NET開発者ガイド
12c リリース1(12.1)
B72971-07
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

.NETストアド・プロシージャにおけるODP.NETに関する制限事項

この項では、Oracle Data Provider for .NETを.NETストアド・プロシージャ内で使用する際に適用される重要な概念について説明します。


注意:

ODP.NET管理対象ドライバは、.NETストアド・プロシージャをサポートしていません。

暗黙的なデータベース接続

.NETストアド・プロシージャでは、暗黙的なデータベース接続を使用してOracleデータにアクセスできます。暗黙的なデータベース接続が.NETストアド・プロシージャのコール元によりすでに確立されているため、ユーザー接続を確立するかわりに、この暗黙的なデータベース接続を使用する必要があります。これにより、リソースの使用量が最小化されます。

暗黙的なデータベース接続を表すOracleConnectionオブジェクトを.NETストアド・プロシージャで取得するには、OracleConnectionオブジェクトのConnectionStringプロパティを"context connection=true"に設定し、Openメソッドを起動します。"context connection=true"は、Statement Cache Size属性以外の接続文字列属性と一緒に使用することはできません。

暗黙的なデータベース接続の可用性は、実行時にOracleConnection.IsAvailable静的プロパティを使用して確認できます。このプロパティでは、Oracle Data Provider for .NETが.NETストアド・プロシージャで使用されている場合は常にtrueを戻します。それ以外の場合は、falseが戻されます。


注意:

データベース・リンクは、.NETストアド・プロシージャではサポートされません。

.NETストアド・プロシージャを起動して使用できる暗黙的なデータベース接続は1つのみです。暗黙的なデータベース接続に加えてさらに接続を確立するには、明示的な接続を作成する必要があります。暗黙的なデータベース接続を表すOracleConnectionに対してCloseメソッドが起動されると、接続は実際にはクローズされません。したがって、同一の、または別のOracleConnectionオブジェクトに対してOpenメソッドを起動して、暗黙的なデータベース接続を表す接続を取得することができます。

暗黙的なデータベース接続を取得できるのは、最初に.NETストアド・プロシージャを起動した、ネイティブのOracleスレッドでOpenメソッドを起動するときのみです。ただし、ネイティブのOracleスレッドから生成されたスレッドでは、ネイティブのOracleスレッドにより取得された暗黙的なデータベース接続を使用できます。

トランザクションのサポート

暗黙的なデータベース接続では、.NETストアド・プロシージャを実行すると、現在のトランザクションが自動的に継承されます。コンテキスト接続では、明示的なトランザクションは.NETストアド・プロシージャ内で開始、コミット、またはロールバックできませんが、クライアント接続では、明示的なトランザクションは.NETストアド・プロシージャ内で開始、コミット、またはロールバックできます。

たとえば、コンテキスト接続の場合、OracleConnection.BeginTransactionを.NETストアド・プロシージャ内で使用できませんが、クライアント接続の場合は使用できます。.NETストアド・プロシージャは分散トランザクションをサポートしません。分散トランザクションのクライアント接続に参加して.NETストアド・プロシージャまたはファンクションをコールした場合、エラーが発生します。

トランザクションの一部にする必要があるデータベース上で、.NETストアド・プロシージャまたは関数の操作を実行する場合、このトランザクションは、.NETストアド・プロシージャを呼び出す前に開始する必要があります。必要なコミットまたはロールバックは、.NETストアド・プロシージャや関数から戻された後に実行する必要があります。

次の例は、クライアント・アプリケーションと従業員のレコードをEMP表に挿入するInsertRecordSPという.NETストアド・プロシージャで構成されています。

例(.NETストアド・プロシージャ)

using System;
using System.Data;
using Oracle.DataAccess.Client;
// This class represents an Oracle .NET stored procedure that inserts
// an employee record into an EMP table of SCOTT schema.
public class InsertRecordSP
{
    // This procedure will insert a row into the emp database
    // For simplicity we are using only two parameters, the rest are hard coded
    public static void InsertRecord( int EmpNo, string EmpName )
    {
        if(OracleConnection.IsAvailable == true )
        {
            OracleConnection conn = new OracleConnection(
                "context connection=true");
            conn.Open();
            // Create new command object from connection context
            OracleCommand Cmd = conn.CreateCommand();
            Cmd.CommandText = "INSERT INTO EMP( EMPNO, ENAME, JOB," +
                "MGR, HIREDATE, SAL, COMM, DEPTNO ) " +
                "VALUES ( :1, :2, 'ANALYST', 7566, " +
                "'06-DEC-04', 5000, 0, 20 )";
            Cmd.Parameters.Add( ":1", OracleDbType.Int32,
                EmpNo, ParameterDirection.Input );
            Cmd.Parameters.Add( ":2", OracleDbType.Varchar2,
                EmpName, ParameterDirection.Input );
            Cmd.ExecuteNonQuery();
        }
    }
}

例(クライアント・アプリケーション)

この例では、従業員番号7950のBernsteinという新しい従業員をEMP表に入力します。

// C#
// This sample demonstrates how to start the transaction with ODP.NET client 
// application and execute an Oracle .NET stored procedure that performs
// a DML operation. Since .NET stored procedure inherits the current
// transaction from the implicit database connection,  DML operation 
// in .NET stored procedure will not be in auto-committed mode.
// Therefore, it is up to the client application to do a COMMIT or ROLLBACK
// after returning from .NET stored procedure
using System;
using System.Data;
using Oracle.DataAccess.Client;
// In this class we are starting a transaction on the client side and
// executing a .NET stored procedure, which inserts a record into EMP
// table and then verifies record count before and after COMMIT statement
class TransactionSample
{
    static void Main(string[] args)
    {
        OracleConnection Conn = null;
        OracleTransaction Txn = null;
        OracleCommand Cmd = null;
        try
        {
            Console.WriteLine( "Sample: Open DB connection in non auto-committed " 
               + "mode," +
                "DML operation performed by .NET stored " +
                "procedure doesn't have an effect before COMMIT " +
                "is called." );
            // Create and Open oracle connection
            Conn = new OracleConnection();
            Conn.ConnectionString = "User Id=scott;Password=tiger;" +
                "Data Source=oracle;";
            Conn.Open();
            // Start transaction
            Txn = Conn.BeginTransaction( IsolationLevel.ReadCommitted );
            // Create command object
            Cmd = new OracleCommand();
            Cmd.Connection = Conn;
            Cmd.CommandType = CommandType.StoredProcedure;
            Cmd.CommandText = "InsertRecord"; // .NET Stored procedure
            // Parameter settings
            OracleParameter EmpNoPrm = Cmd.Parameters.Add(
                "empno", OracleDbType.Int32 );
            EmpNoPrm.Direction = ParameterDirection.Input;
            EmpNoPrm.Value = 7950;
            OracleParameter EmpNamePrm = Cmd.Parameters.Add(
                "ename", OracleDbType.Varchar2, 10 );
            EmpNamePrm.Direction = ParameterDirection.Input;
            EmpNamePrm.Value = "Bernstein";
            // Execute .NET stored procedure
            Cmd.ExecuteNonQuery();
            Console.WriteLine( "Number of record(s) before COMMIT {0}",
                RecordCount() );
            Txn.Commit();
            Console.WriteLine( "Number of record(s) after COMMIT {0}",
                RecordCount() );
        }
        catch( OracleException OE )
        {
            Console.WriteLine( OE.Message );
        }
        finally
        {
            // Cleanup objects
            if( null != Txn )
                Txn.Dispose();
            if( null != Cmd )
                Cmd.Dispose();
            if( null != Conn && Conn.State == ConnectionState.Open )
                Conn.Close();
        }
    }
    static int RecordCount()
    {
        int EmpCount = 0;
        OracleConnection Conn = null;
        OracleCommand Cmd = null;
        try
        {
            Conn = new OracleConnection( "User Id=scott;Password=tiger;" +
                "Data Source=oracle;" );
            Conn.Open();
            Cmd = new OracleCommand( "SELECT COUNT(*) FROM EMP", Conn );
            Object o = Cmd.ExecuteScalar();
            EmpCount = Convert.ToInt32(o.ToString());
        }
        catch( OracleException OE )
        {
            Console.WriteLine( OE.Message );
        }
        finally
        {
            if( null != Cmd )
                Cmd.Dispose();
        }
        return EmpCount;
       }
      }

未サポートのSQLコマンド

.NETストアド・プロシージャでは、COMMITROLLBACKおよびSAVEPOINTなどのトランザクション制御コマンドはサポートされていません。

CREATEALTERなどのデータ定義コマンドは暗黙的なデータベース接続ではサポートされていませんが、.NETストアド・プロシージャにおける明示的なユーザー接続ではサポートされています。

Oracleユーザー定義タイプ(UDT)のサポート

UDTはコンテキスト接続内ではサポートされませんが、クライアント接続ではサポートされます。UDTは.NETストアド・プロシージャのパラメータとしてサポートされていません。