プライマリ・コンテンツに移動

Oracle® Data Provider for .NET開発者ガイド ODAC 12.2c リリース1 (12.2.0.1) for Microsoft Windows E88311-03 |
| 目次 | 索引

前 | 次 |

# .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スレッドにより取得された暗黙的なデータベース接続を使用できます。

関連項目:

IsAvailable

## トランザクション・サポート

暗黙的なデータベース接続では、.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ストアド・プロシージャでは、`COMMIT`、`ROLLBACK`および`SAVEPOINT`などのトランザクション制御コマンドはサポートされていません。

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

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

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