ヘッダーをスキップ
Oracle Migration Workbench Microsoft SQL ServerおよびSybase Adaptive Serverからの移行のためのリファレンス・ガイド
リリース10.1.0.4 for Microsoft Windows 98/2000/NT/XP
B19342-01
  目次
目次
索引
索引

戻る
戻る
次へ
次へ
 

3 トリガーおよびストアド・プロシージャ

この章では、Microsoft SQL ServerとSybase Adaptive ServerおよびOracleの違いを説明します。 内容は次のとおりです。

トリガー

Microsoft SQL ServerおよびSybase Adaptive Serverのデータベース・トリガーはAFTERトリガーです。これは、特定の操作を実行した後にトリガーが起動されることを意味します。たとえば、INSERTトリガーは、データベースに行が挿入された後に起動されます。トリガーが正常に起動されない場合は、操作がロールバックされます。

Microsoft SQL ServerおよびSybase Adaptive Serverでは、INSERT、UPDATEおよびDELETEトリガーを使用できます。 通常、トリガーは変更中のデータのビフォア・イメージおよびアフター・イメージにアクセスする必要があります。 Microsoft SQL ServerおよびSybase Adaptive Serverでは、INSERTEDおよびDELETEDという2つの一時表を使用してこの処理が行われます。これらの2つの表はトリガーの実行中に存在します。これらの表と、トリガーが書き込まれる表は完全に同じ構造をしています。DELETED表にはINSERT/UPDATE/DELETE操作のために変更されている行のビフォア・イメージが保持され、INSERTED表にはこれらの行のアフター・イメージが保持されます。エラーが発生した場合は、トリガーでロールバック文を発行できます。

Microsoft SQL ServerおよびSybase Adaptive Serverのほぼすべてのトリガーのコードは、参照整合性が適用されます。 Microsoft SQL ServerおよびSybase Adaptive Serverのトリガーは、SQL文(INSERT、UPDATE、DELETEなど)を実行するたびに1回実行されます。SQL文の影響を受ける各行に対して特定のアクションが実行されるようにする場合は、INSERTEDおよびDELETED表を使用してそのアクションをコード化する必要があります。

Oracleでは、豊富なトリガーが提供されています。INSERT、UPDATE、DELETEなどのイベントに対して起動されるトリガーもあります。また、トリガー・アクションが実行される回数を指定することもできます。たとえば、トリガーを起動するイベント(多くの行を更新するUPDATEによって起動されるイベントなど)によって影響を受けるすべての行に対して1回、(影響を受ける文の数に関係なく)トリガーを起動する文に対して1回などと指定できます。

ROWトリガーは、トリガーを起動するイベントによって表が影響を受けるたびに起動されます。たとえば、UPDATE文で表の複数の行を更新する場合、ROWトリガーは、UPDATE文によって影響を受ける各行に対して1回起動されます。STATEMENTトリガーは、トリガーを起動する文によって影響を受ける表内の行の数に関係なく、トリガーを起動する文のかわりに1回起動されます。

Oracleのトリガーは、BEFOREトリガーまたはAFTERトリガーのいずれかとして定義できます。BEFOREトリガーは、トリガーを起動する文を完了できるかどうかをトリガー・アクションで判断する場合に使用されます。BEFOREトリガーを使用すると、トリガーを起動する文およびその最終的なロールバックが、例外が発生した場合に必要以上に実行されないようにすることができます。

Oracleには、これらを組み合せた次の4つのタイプのトリガーがあります。

ROWトリガーまたはSTATEMENTトリガーを作成して、Microsoft SQL ServerおよびSybase Adaptive Serverのトリガーと同じ機能を使用できるようにする必要がある場合があります。次に、その場合を示します。

次の例では、グループ関数AVGを使用して平均給与を計算します。

SELECT AVG(inserted.salary)
FROM inserted a, deleted b
WHERE a.id = b.id;

これをOracleに変換するには、更新されたすべての値をパッケージに挿入するAFTER ROWトリガー、およびパッケージから読取りを行い、平均を計算するAFTER STATEMENTを作成します。

Oracleのトリガーの例については、『Oracle9i アプリケーション開発者ガイド-基礎編』を参照してください。

ストアド・プロシージャ

Microsoft SQL ServerおよびSybase Adaptive Serverでは、トリガーおよびストアド・プロシージャがサーバーとともに格納されます。 Oracleでは、トリガーおよびストアド・サブプログラムがサーバーとともに格納されます。Oracleには、3種類の異なるストアド・サブプログラム(ファンクション、ストアド・プロシージャおよびパッケージ)があります。 これらすべてのオブジェクトの詳細は、『PL/SQLユーザーズ・ガイドおよびリファレンス』を参照してください。

ストアド・プロシージャを使用すると、サーバーとともに格納可能なアプリケーション・ロジックを有効にコード化できます。 ストアド・プロシージャは、Microsoft SQL Server、Sybase Adaptive ServerおよびOracleのすべてで利用できます。

これらのオブジェクトのコード化に使用する言語は、SQLに対するデータベース固有の手続き型拡張言語です。この言語は、OracleではPL/SQLで、Microsoft SQL ServerおよびSybase Adaptive ServerではTransact SQL(T-SQL)です。これらの言語は大幅に異なります。個々のSQL文およびプロシージャの構文(if-then-elseなど)は、両方のバージョンの手続き型SQLで類似しています。 この項では、両方のバージョンにおける次の項目の相違点を説明します。

また、この項では、変換時に問題が発生しないようにするために、Microsoft SQL ServerおよびSybase Adaptive Serverの通常のストアド・プロシージャの各種コンポーネントについて検討し、それらの設計方法を示します。 この項で説明する標準をコーディングに適用すると、ストアド・プロシージャをMicrosoft SQL ServerおよびSybase Adaptive ServerからOracleに変換できます。

個々のSQL文

個々のSQL文は、可能なかぎり、ANSI規格のSQLに準拠させる必要があります。ただし、使用が簡単、コーディングが単純、パフォーマンスが向上などの理由から、データベース固有のSQL構文を使用する必要がある場合があります。たとえば、次に示すMicrosoft SQL ServerおよびSybase Adaptive Serverの構文は、SQL Server固有で、手動操作なしではOracleに変換できません。

update <table_name>
set ...
from <table1>, <table_name>
where...

次に、このような文の変換に必要な手動操作の例を示します。

Microsoft SQL ServerおよびSybase Adaptive Server:

DELETE sales
FROM sales, titles
WHERE sales.title_id = titles.title_id
AND titles.type = 'business'

Oracle:

DELETE sales
FROM sales, titles
WHERE sales.title_id = titles.title_id
AND titles.type = 'business'

Microsoft SQL ServerおよびSybase Adaptive Server:

UPDATE titles
SET price = price + author_royalty
FROM titles, title_author
WHERE titles.title.id = title_author.title_id

Oracle:

UPDATE titles O
SET price = (   SELECT (O.price + I.author_royalty)
                          FROM title_author I
                        WHERE I.title_id = O.title_id)
WHERE EXISTS    (SELECT 1
                          FROM title_author
                          WHERE  title_author.title_id = O.title_id) ;

ANSI規格のすべてのSQL文は、自動変換ユーティリティを使用してデータベース間で変換できます。

論理トランザクション処理

Microsoft SQL ServerおよびSybase Adaptive Serverでは、トランザクションの定義は明示的です。これは、個々のSQL文がデフォルトでは論理トランザクションの一部ではないことを意味します。 SQL文は、ユーザーがBEGIN TRANSACTION(またはBEGIN TRAN)文を使用して明示的に開始したトランザクションが有効な場合、論理トランザクションに属します。 論理トランザクションは、対応するCOMMIT TRANSACTION(またはCOMMIT TRAN)あるいはROLLBACK TRANSACTION(またはROLLBACK TRAN)文で終了します。論理トランザクションの一部ではない各SQL文は、完了時にコミットされます。

Oracleでは、トランザクションは、ANSI規格に準拠しているため暗黙的です。暗黙的トランザクション・モデルでは、各SQL文が論理トランザクションの一部である必要があります。COMMITまたはROLLBACKコマンドを実行すると、新しい論理トランザクションが自動的に開始されます。また、これは、個々のSQL文からのデータの変更が実行後データベースにコミットされないことを意味します。この変更は、COMMIT文を実行した場合にのみデータベースにコミットされます。トランザクション・モデルの違いは、アプリケーション・プロシージャのコーディングに影響します。

トランザクション処理文

クライアント/サーバー・アプリケーションでは、トランザクション処理の構文をクライアント・プロシージャの一部にすることをお薦めします。論理トランザクションは、常に、クライアント・ユーザーが定義および制御する必要があります。この方針は、2フェーズ・コミット操作が必要な分散トランザクションにも適用されます。トランザクション処理文をクライアント・コードの一部にすることには、2つの目的があります。サーバー・コードの移植性を高めること、および分散トランザクションをサーバー・コードに依存しないようにすることです。BEGIN TRAN、ROLLBACK TRANおよびCOMMIT TRAN文は、ストアド・プロシージャでは使用しないようにしてください。Microsoft SQL ServerおよびSybase Adaptive Serverでは、トランザクションは明示的です。Oracleでは、トランザクションは暗黙的です。トランザクションがクライアントによって処理される場合は、サーバーに存在するアプリケーション・コードを、トランザクション・モデルに依存しないようにすることができます。

ストアド・プロシージャ内でのエラー処理

OracleのPL/SQLでは、次の文に進む前に各SQL文のエラーが確認されます。エラーが発生すると、すぐに制御が例外ハンドラに渡されます。これによって、すべてのSQL文の状態を確認する必要がなくなります。たとえば、SELECT文でデータベース内の行が検出されない場合は、例外が発生し、このエラーを処理するコードが実行されます。

Microsoft SQL ServerおよびSybase Adaptive Serverでは、SQL文を実行するたびにエラーは確認されません。前の文によって生成されたエラー状態に関係なく、制御が次の文に渡されます。そのため、SQL文を実行するたびに、ユーザー自身がエラーを確認する必要があります。確認しないと、誤った結果が戻される場合があります。

Oracleで、Microsoft SQL ServerおよびSybase Adaptive Serverの動作をシミュレートし、前のSQL文の実行状態に関係なく制御を次の文に渡すには、各SQL文を、同様に動作するPL/SQLブロックで囲む必要があります。このブロックによって、そのSQL文で発生する可能性があるすべての例外を処理する必要があります。このコーディング・スタイルは、Microsoft SQL ServerおよびSybase Adaptive Serverの動作をシミュレートする場合にのみ必要です。OracleのPL/SQLプロシージャに1つのみの例外ブロックを含め、そのブロックですべてのエラー状態を処理することをお薦めします。

Microsoft SQL ServerおよびSybase Adaptive Serverストアド・プロシージャで次のコードを実行するとします。

begin

        select @x = col1 from table1 where col2 = @y
        select @z = col3 from table2 where col4 = @x

end

このコード例では、最初のSELECT文が行を戻さない場合、値@xUNDEFINEDになります。 例外が発生せずに制御が次の文に渡されると、2番目の文では、最初の文によって値@x が設定されている必要があるため、不適切な結果が戻されます。 同様の状況で、最初の文が正常に実行されないと、OracleのPL/SQLではNO_DATA_FOUND例外が発生します。

RAISERROR文

Microsoft SQL ServerおよびSybase Adaptive ServerのRAISERROR文は、コール元のルーチンに戻されません。エラー・コードおよびエラー・メッセージがクライアントに渡され、ストアド・プロシージャは続行されます。 OracleのRAISE_APPLICATION_ERROR文は、コール元のルーチンに戻されます。 通常、RETURN文は、Microsoft SQL ServerおよびSybase Adaptive ServerではRAISERROR文の後に指定する必要があるため、OracleのRAISE_APPLICATION_ERROR文に変換できます。

エラー・メッセージのカスタマイズ

Microsoft SQL ServerおよびSybase Adaptive Serverでは、システム表を使用してエラー・メッセージをカスタマイズできます。システム・プロシージャを使用して、エラー・メッセージをシステムに追加できます。Oracleシステムに同等の機能がないため、エラー・メッセージは、Microsoft SQL ServerおよびSybase Adaptive Serverのシステム表には追加しないことをお薦めします。中央データベースにあるユーザー定義のエラー・メッセージ表をメンテナンスすることで、この操作を行う必要がなくなります。標準ルーチンは、エラー・メッセージを表に追加して必要に応じて取得できるように作成できます。この方法には、2つの目的があります。異なるタイプのデータベース・サーバー間でのシステムの移植性を高めること、および管理者がエラー・メッセージを集中制御できるようにすることです。

データ型

この項では、データ型に関する次の項目について説明します。

ローカル変数

T-SQLのローカル変数は、TEXTおよびIMAGE以外の任意のデータ型にできます。PL/SQLのローカル変数は、任意のデータ型にできます。次に例を示します。

  • BINARY_INTEGER

  • BOOLEAN

また、PL/SQLのローカル変数は、PL/SQLで使用可能な次の複合データ型のいずれかにできます。

  • RECORD

  • TABLE

サーバー・データ型

Microsoft SQL ServerおよびSybase Adaptive Serverのデータ型およびそれらに相当するOracleのデータ型のリストは、第2章の「データ型」を参照してください。

複合データ型

Microsoft SQL ServerおよびSybase Adaptive Serverには複合データ型はありません。

表3-1 Oracleの複合データ型

Oracle コメント

RECORD

変数をRECORD型と宣言できます。レコードには、一意に名前が付けられたフィールドがあります。型が異なり、論理的に関連するデータを論理ユニットとしてまとめて保存できます。

TABLE

PL/SQL表には1つの列および主キーを含めることができます。いずれも名前を付けることはできません。この列は、任意のスカラー・データ型に属します。 複合データ型


スキーマ・オブジェクト

この項では、Microsoft SQL ServerおよびSybase Adaptive Serverと Oracleの次のスキーマ・オブジェクトを比較します。

各スキーマ・オブジェクトの作成、削除、実行および変更(該当する場合)について個別の表で比較します。 次のセクションに分類して説明します。

一部の表では、変換による影響の重要な情報を含む推奨事項のセクションが後に続きます。

プロシージャ

この項では、プロシージャの次の操作について説明します。

作成

表3-2 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのプロシージャの作成方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle

構文:

CREATE PROCEDURE procedure [@formal_parameter formal_parameter_data type [OUTPUT]                     [= default_value] [,@formal_parameter formal_parameter_data type [OUTPUT][= default_value]] ...

AS BEGIN] procedural_statements [END]

構文:

CREATE [OR REPLACE] PROCEDURE [schema.]procedure [(]                        [formal_parameter [IN | OUT | IN OUT]         formal_parameter_data type] [DEFAULT default_value]  [,formal_parameter             [IN | OUT | IN OUT]formal_parameter_data type] [DEFAULT default_value]] ...   [)]                             IS | AS                    [local_variable data type;]... BEGIN                       PL/SQL statements | PL/SQL blocks      END;

説明:

CREATE PROCEDURE文は、名前付きのストアド・プロシージャをデータベースに作成します。

オプションで、プロシージャにOUTPUTとして渡されるパラメータを指定できます。 OUTPUT変数の値は、プロシージャの実行後、コール元のルーチンで使用できます。OUTPUTキーワードなしで指定されたパラメータは、入力パラメータとみなされます。

キーワードASは、プロシージャ本体の開始点を示します。

ストアド・プロシージャ本体を囲むBEGINおよびENDキーワードはオプションです。ファイル内のASの後に含まれているすべてのプロシージャ文は、BEGINおよびENDがブロックのマークに使用されていない場合、ストアド・プロシージャの一部とみなされます。

T-SQLプロシージャで使用可能な構文の詳細は、この章の「T-SQLおよびPL/SQLの言語要素」を参照してください。

説明:

OR REPLACEキーワードは、プロシージャがすでに存在している場合は、新しい定義で置き換えます。

PL/SQLプロシージャに渡されるパラメータは、IN(入力)、OUT(出力のみ)またはIN OUT(入出力)と指定できます。これらのキーワードを指定しない場合、このパラメータはINと想定されます。

キーワードISは、プロシージャの開始点を示します。ローカル変数は、キーワードISまたはASとキーワードBEGINの間で宣言します。

BEGINキーワードとENDキーワードは、プロシージャ本体を囲みます。

権限:

ストアド・プロシージャを作成するには、CREATE PROCEDUREシステム権限が必要です。

権限:

自分のスキーマにプロシージャを作成するには、CREATE PROCEDUREシステム権限が必要です。別のユーザーのスキーマにプロシージャを作成するには、CREATE ANY PROCEDUREシステム権限が必要です。


推奨事項:

T-SQLプロシージャとPL/SQLプロシージャの構造の機能的に同一の部分を識別することができます。したがって、ほぼすべての構文をMicrosoft SQL ServerおよびSybase Adaptive ServerからOracleへ自動的に変換できます。

OracleのCREATE PROCEDURE文にOR REPLACEキーワードを使用すると、効率的にプロシージャを再作成できます。Microsoft SQL ServerおよびSybase Adaptive Serverでは、プロシージャを明示的に削除した後で置き換える必要があります。

削除

表3-3 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのプロシージャの削除方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle

構文:

DROP PROCEDURE procedure

構文:

DROP PROCEDURE [schema.]procedure

説明:

プロシージャの定義がデータ・ディクショナリから削除されます。このプロシージャを参照するすべてのオブジェクトで、このプロシージャへの参照を削除する必要があります。

説明:

プロシージャが削除されると、削除されたプロシージャを参照するすべてのローカル・オブジェクトが無効になります。

権限:

プロシージャ所有者は、所有者自身のプロシージャを削除できます。DBOは、すべてのプロシージャを削除できます。

権限:

このコマンドを実行するには、プロシージャがユーザーのスキーマに存在するか、またはユーザーがDROP ANY PROCEDUREシステム権限を所有している必要があります。

:

DROP PROCEDURE myproc

:

DROP PROCEDURE sam.credit;

推奨事項:

前述の文は、変換処理には影響しません。この情報は、参照用にのみ提供されています。

実行

表3-4 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのプロシージャの実行方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle

構文:

EXEC [@return_value = ] procedure [[@formal_parameter = ] {@actual_parameter | constant_literal} [OUT]] [,[[@formal_parameter = ] {@actual_parameter | constant_literal} [OUT]]] ...

構文:

procedure
 [([{actual_parameter |
      constant_literal |
   formal_parameter =>
     {actual_parameter |
      constant_literal}
   }]
 [,{actual_parameter |
      constant_literal |
      formal_parameter =>
     {actual_parameter |
      constant_literal}
   }] ....
)]

説明:

Microsoft SQL ServerおよびSybase Adaptive Serverのストアド・プロシージャは、RETURN文を使用して、コール元のルーチンに整数値のみを戻すことができます。RETURN文を使用しない場合でも、ストアド・プロシージャはコール元のルーチンに戻り状態を戻します。 この値は、return_value変数で取得できます。

formal_parameterは、プロシージャの定義内のパラメータです。 actual_parameterは、実パラメータの値をそれぞれの仮パラメータに代入してプロシージャをコールするローカル・ブロックに定義されます。 実パラメータと仮パラメータの対応付けは、位置表記法または名前表記法のいずれかを使用して指定できます。

説明:

OracleのPL/SQLプロシージャは、OUTパラメータによってコール元のルーチンにデータを戻します。Oracleでは、別のタイプのスキーマ・オブジェクトであるファンクションが提供されています。ファンクションは、RETURN文を使用してコール元のルーチンにアトム型の値を戻すことができます。RETURN文は、任意のデータ型の値を戻すことができます。

formal_parameterは、プロシージャの定義内のパラメータです。 actual_parameterは、実パラメータの値をそれぞれの仮パラメータに代入してプロシージャをコールするローカル・ブロックに定義されます。 実パラメータと仮パラメータの対応付けは、位置表記法または名前表記法のいずれかを使用して指定できます。

位置表記法: 実パラメータは、プロシージャの定義内の仮パラメータと同じ順序でプロシージャに適用されます。

名前表記法: 実パラメータは、仮パラメータの名前を次のように使用して、プロシージャの定義内の仮パラメータの順序とは異なる順序でプロシージャに適用されます。

  @formal_parameter = @actual_parameter

定数リテラルは、次の位置に指定できます。

'@actual_parameter ' as:
@formal_parameter = 10

@formal_parameter = 10

キーワードOUTは、プロシージャでそのパラメータの値をコール元のルーチンにOUTPUTとして戻す必要がある場合に指定する必要があります。

位置表記法: 実パラメータは、プロシージャの定義内の仮パラメータと同じ順序でプロシージャに適用されます。

名前表記法: 実パラメータは、仮パラメータの名前を次のように使用して、プロシージャの定義内の仮パラメータの順序とは異なる順序でプロシージャに適用されます。

  formal_parameter => actual_parameter

定数リテラルは、次の位置に指定できます。

as:
   formal_parameter => 10

formal_parameterがプロシージャの定義内にOUTまたはIN OUTとして指定されている場合は、プロシージャの実行後、その値をコール元のルーチンで使用できます。

権限:

ユーザーは、ストアド・プロシージャに対するEXECUTE権限を所有している必要があります。ストアド・プロシージャ内で参照される、基礎となるオブジェクトにアクセスするための明示的な権限は必要ありません。

権限

ユーザーは、名前付きのプロシージャに対するEXECUTE権限を所有している必要があります。PL/SQLプロシージャ内で参照される、基礎となるオブジェクトにアクセスするための明示的な権限は必要ありません。

:

位置表記法:

  EXEC GetEmplName @EmpID
  EXEC @status = GetAllDeptCodes
  EXEC @status =  UpdateEmpSalary @EmpID,
   @EmpName
  EXEC UpdateEmpSalary 13000,'Joe Richards'

名前表記法:

  EXEC UpdateEmpSalary
@Employee = @EmpName,
   @Employee_Id = @EmpID

混合表記法:

 EXEC UpdateEmpSalary
@EmpName, @Employee_Id = @EmpID
 EXEC UpdateEmpSalary
@Employee = @EmpName, @EmpID

:

位置表記法:

 credit (accno, accname, amt, retstat);

名前表記法:

  credit (acc_no => accno, acc => accname, amount => amt,
      return_status => retstat)

混合表記法(位置表記法を名前表記法より先に指定する必要があります):

  credit (accno, accname, amount => amt, return_status => retstat)

変更

表3-5 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのプロシージャの変更方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle

構文:

システム・プロシージャSP_RECOMPILEは、名前付きのストアド・プロシージャを再コンパイルします。次に例を示します。

ALTER PROCEDURE <procedure name>
|RECOMPILE
|ENCRYPT
|RECOMPILE, ENCRYPT

構文:

ALTER PROCEDURE [schema.]procedure COMPILE

説明:

このコマンドを実行すると、プロシージャが再コンパイルされます。なんらかの理由で無効になっているプロシージャは、このコマンドを使用して明示的に再コンパイルする必要があります。

説明:

このコマンドを実行すると、プロシージャが再コンパイルされます。なんらかの理由で無効になっているプロシージャは、このコマンドを使用して明示的に再コンパイルする必要があります。明示的に再コンパイルすることによって、暗黙的に再コンパイルする必要がなくなるため、それに関連する実行時コンパイル・エラーおよびパフォーマンス上のオーバーヘッドの発生を防止できます。

権限:

このコマンドを発行できるのは、プロシージャの所有者です。

権限:

このコマンドを使用するには、プロシージャがユーザーのスキーマに存在するか、またはユーザーがALTER ANY PROCEDURE権限を所有している必要があります。

:

sp_recompile my_proc

:

ALTER PROCEDURE sam.credit COMPILE;

ファンクション

この項では、ファンクションの次の操作について説明します。

作成

表3-6 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのファンクションの作成方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle

構文:

Microsoft SQL ServerおよびSybase Adaptive Serverでは、ストアド・プロシージャでRETURN文を使用してコール元のルーチンに整数値を戻すことができるため、ストアド・プロシージャをOracleのファンクションに変換できます。ストアド・プロシージャは、RETURN文を使用しない場合でも、コール元のルーチンに状態値を戻します。戻される状態は、プロシージャが正常に実行され場合はZERO、なんらかの理由で正常に実行されなかった場合はNON-ZEROと同等になります。RETURN文は、整数値のみを戻すことができます。

構文:

CREATE [OR REPLACE] FUNCTION [user.]function [(parameter [OUT] data type[,(parameter [IN OUT] data type]...)]
RETURN data type {IS|AS} block

なし

説明:

OR REPLACEキーワードは、ファンクションがすでに存在している場合は、新しい定義で置き換えます。

PL/SQLファンクションに渡されるパラメータは、IN(入力)、OUT(出力)またはIN OUT(入出力)と指定できます。これらのキーワードを指定しない場合、このパラメータはINと想定されます。

RETURNデータ型は、ファンクションの戻り値のデータ型を指定します。データ型には、PL/SQLでサポートされている任意のデータ型を指定できます。 データ型の詳細は、「データ型」を参照してください。

なし

権限:

自分のスキーマにファンクションを作成するには、CREATE PROCEDUREシステム権限が必要です。別のユーザーのスキーマにファンクションを作成するには、CREATE ANY PROCEDUREシステム権限が必要です。

なし

例:

  CREATE FUNCTION get_bal
(acc_no IN NUMBER)
   RETURN  NUMBER
 IS
     acc_bal NUMBER(11,12);
  BEGIN
   SELECT balance
     INTO acc_bal
     FROM accounts
     WHERE account_id = acc_no;
   RETURN(acc_bal);
  END;

削除

表3-7 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのファンクションの削除方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle

なし

構文:

DROP FUNCTION [schema.]function

なし

説明:

ファンクションが削除されると、削除されたファンクションを参照するすべてのローカル・オブジェクトが無効になります。

なし

権限:

このコマンドを実行するには、ファンクションがユーザーのスキーマに存在するか、またはユーザーがDROP ANY PROCEDUREシステム権限を所有している必要があります。

なし

:

DROP FUNCTION sam.credit;

実行

表3-8 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのファンクションの実行方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle

なし

構文:

function [({actual_parameter | constant_literal}...)]

なし

説明:

ファンクションは、RETURN文を使用してコール元のルーチンにアトム型の値を戻すことができます。

ファンクションは、式の一部としてコールできます。これは、非常に優れた概念です。 Microsoft SQL ServerおよびSybase Adaptive Serverのすべての組込みファンクションは、PL/SQLを使用してコード化できます。これらのファンクションは、Oracleを使用して起動し、式内の他の組込みファンクション同様にコールできます。

なし

権限:

名前付きのファンクションを実行するには、そのファンクションに対するEXECUTE権限が必要です。PL/SQLファンクション内で参照される、基礎となるオブジェクトにアクセスするための明示的な権限は必要ありません。

なし

:

 1) IF sal_ok (new_sal, new_title) THEN
   ....
   END IF;

2) promotable:=
   sal_ok(new_sal, new_title) AND
   (rating>3);

ここで、sal_okはBOOLEAN値を戻すファンクションです。


変更

表3-9 OracleとMicrosoft SQL Server 7.0でのファンクションの変更方法の比較

Microsoft SQL Server Oracle

なし

構文:

ALTER FUNCTION [schema.]function COMPILE

なし

説明:

このコマンドを実行すると、ファンクションが再コンパイルされます。ファンクションは、ファンクション内から参照されるオブジェクトが削除または変更されると無効になります。なんらかの理由で無効になっているファンクションは、このコマンドを使用して明示的に再コンパイルする必要があります。明示的に再コンパイルすることによって、暗黙的に再コンパイルする必要がなくなるため、それに関連する実行時コンパイル・エラーおよびパフォーマンス上のオーバーヘッドの発生を防止できます。

なし

権限:

このコマンドを使用するには、ファンクションがユーザーのスキーマに存在するか、またはユーザーがALTER ANY PROCEDURE権限を所有している必要があります。

なし

例:

 ALTER FUNCTION sam.credit COMPILE

パッケージ

この項では、パッケージの次の操作について説明します。

作成

表3-10 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのパッケージの作成方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle

構文:

パッケージは、Microsoft SQL ServerおよびSybase Adaptive Serverではサポートされていません。

構文:

CREATE [OR REPLACE] PACKAGE [user.]package {IS | AS} {variable_declaration | cursor_specification | exception_declaration | record_declaration | plsql_table_declaration | procedure_specification | function_specification | [{variable_declaration | cursor_specification | exception_declaration | record_declaration | plsql_table_declaration | procedure_specification | function_specification}; ]...}        END [package]

なし

説明:

これは、パッケージの外部(公開部分)です。

CREATE PACKAGEは、プロシージャ、ファンクション、例外、変数、定数およびカーソルのグループとして構成できるPL/SQLパッケージの仕様部を設定します。

パッケージのファンクションおよびプロシージャは、変数、定数およびカーソルを介してデータを共有できます。

OR REPLACEキーワードは、パッケージがすでに存在している場合は、新しい定義で置き換えます。これを行うには、パッケージおよびパッケージ仕様部に依存するすべてのオブジェクトを再コンパイルする必要があります。

なし

権限:

自分のスキーマにパッケージを作成するには、CREATE PROCEDUREシステム権限が必要です。別のユーザーのスキーマにパッケージを作成するには、CREATE ANY PROCEDUREシステム権限が必要です。

なし

:

CREATE PACKAGE emp_actions AS
  -- specification
  TYPE EmpRecTyp IS RECORD (emp_id INTEGER, salary REAL);
  CURSOR desc_salary (emp_id NUMBER) RETURN EmpRecTyp;

  PROCEDURE hire_employee
   (ename CHAR,
    job CHAR,
     mgr NUMBER,
     sal NUMBER,
     comm NUMBER,
     deptno NUMBER);
  PROCEDURE fire-employee (emp_id NUMBER);
END emp_actions;

削除

表3-11 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのパッケージの削除方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle

構文:

パッケージは、Microsoft SQL ServerおよびSybase Adaptive Serverではサポートされていません。

構文:

DROP PACKAGE [BODY] [schema.]package

なし

説明:

BODYオプションを指定すると、パッケージ本体のみが削除されます。BODYを指定しない場合は、パッケージの本体と仕様部の両方が削除されます。パッケージの本体および仕様部を削除すると、パッケージ仕様部に依存するすべてのローカル・オブジェクトが無効になります。

schema.は、パッケージを含むスキーマです。schema.を指定しない場合は、パッケージが自分のスキーマに存在すると想定されます。

パッケージが削除されると、削除されたパッケージを参照するすべてのローカル・オブジェクトが無効になります。

なし

権限:

このコマンドを実行するには、パッケージがユーザーのスキーマに存在するか、またはユーザーがDROP ANY PROCEDUREシステム権限を所有している必要があります。

なし

:

DROP PACKAGE emp_actions;

変更

表3-12 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのパッケージの変更方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle

構文:

パッケージは、Microsoft SQL ServerおよびSybase Adaptive Serverではサポートされていません。

構文:

ALTER PACKAGE [user.]package COMPILE [PACKAGE | BODY]

なし

説明:

なんらかの理由で無効になっているパッケージは、このコマンドを使用して明示的に再コンパイルする必要があります。

このコマンドを実行すると、すべてのパッケージ・オブジェクトがまとめて再コンパイルされます。ALTER PROCEDUREまたはALTER FUNCTIONコマンドを使用して、パッケージの一部であるプロシージャまたはファンクションを個々に再コンパイルすることはできません。

PACKAGE(デフォルトのオプション)を指定すると、パッケージの本体および仕様部が再コンパイルされます。

BODYを指定すると、パッケージ本体のみが再コンパイルされます。

明示的に再コンパイルすることによって、暗黙的に再コンパイルする必要がなくなるため、それに関連する実行時コンパイル・エラーおよびパフォーマンス上のオーバーヘッドの発生を防止できます。

なし

権限:

このコマンドを使用するには、パッケージがユーザーのスキーマに存在するか、またはユーザーがALTER ANY PROCEDURE権限を所有している必要があります。

なし

:

ALTER PACKAGE emp_actions COMPILE PACKAGE

パッケージ本体

この項では、パッケージ本体の次の操作について説明します。

作成

表3-13 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのパッケージ本体の作成方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle

構文:

パッケージは、Microsoft SQL ServerおよびSybase Adaptive Serverではサポートされていません。

構文:

CREATE [OR REPLACE] PACKAGE BODY [schema.]package                               {IS | AS} pl/sql_package_body

なし

説明:

これは、パッケージの内部(非公開部分)です。

CREATE PACKAGEは、ストアド・パッケージの本体を作成します。

OR REPLACEは、パッケージ本体がすでに存在する場合、再作成します。パッケージ本体は、変更すると再コンパイルされます。

schema.は、パッケージを含むスキーマです。これを指定しない場合、パッケージは現行のスキーマに作成されます。

packageは、作成されるパッケージです。

pl/sql_package_bodyは、プログラム・オブジェクトを宣言および定義できるパッケージ本体です。 パッケージ本体への書込み方法の詳細は、『PL/SQLユーザーズ・ガイドおよびリファレンス』を参照してください。

なし

権限:

自分のスキーマにパッケージを作成するには、CREATE PROCEDURE権限が必要です。別のユーザーのスキーマにパッケージを作成するには、CREATE ANY PROCEDURE権限が必要です。

なし

例:

CREATE PACKAGE BODY emp_actions AS
-- body
   CURSOR desc_salary (emp_id NUMBER)
       RETURN EmpRecTyp IS
       SELECT empno, sal FROM emp
       ORDER BY sal DESC;
   PROCEDURE hire_employee
       (ename    CHAR,
        job      CHAR,
        mgr      NUMBER,
        sal      NUMBER,
        comm     NUMBER,
        deptno   NUMBER) IS
   BEGIN
       INSERT INTO emp VALUES
            (empno_seq.NEXTVAL, ename,
             job, mgr, SYSDATE, sal,
             comm, deptno);
   END hire_employee;

   PROCEDURE fire_employee
       (emp_id   NUMBER) IS
   BEGIN
        DELETE FROM emp
        WHERE empno = emp_id;
   END fire_employee;

END emp_actions;

削除

表3-14 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのパッケージ本体の削除方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle

構文:

パッケージは、Microsoft SQL ServerおよびSybase Adaptive Serverではサポートされていません。

構文:

DROP PACKAGE [BODY] [schema.]package

なし

説明:

BODYオプションを指定すると、パッケージ本体のみが削除されます。BODYを指定しない場合は、パッケージの本体と仕様部の両方が削除されます。パッケージの本体および仕様部を削除すると、パッケージ仕様部に依存するすべてのローカル・オブジェクトが無効になります。

schema.は、パッケージを含むスキーマです。schema.を指定しない場合は、パッケージが自分のスキーマに存在すると想定されます。

パッケージが削除されると、削除されたパッケージを参照するすべてのローカル・オブジェクトが無効になります。

なし

権限:

このコマンドを実行するには、パッケージがユーザーのスキーマに存在するか、またはユーザーがDROP ANY PROCEDUREシステム権限を所有している必要があります。

なし

:

DROP PACKAGE BODY emp_actions;

変更

表3-15 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのパッケージ本体の変更方法の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle

構文:

パッケージは、Microsoft SQL ServerおよびSybase Adaptive Serverではサポートされていません。

構文:

ALTER PACKAGE [user.]package COMPILE [PACKAGE | BODY]

なし

説明:

なんらかの理由で無効になっているパッケージは、このコマンドを使用して明示的に再コンパイルする必要があります。

このコマンドを実行すると、すべてのパッケージ・オブジェクトがまとめて再コンパイルされます。ALTER PROCEDUREまたはALTER FUNCTIONコマンドを使用して、パッケージの一部であるプロシージャまたはファンクションを個々に再コンパイルすることはできません。

PACKAGE(デフォルトのオプション)を指定すると、パッケージの本体および仕様部が再コンパイルされます。

BODYを指定すると、パッケージ本体のみが再コンパイルされます。

明示的に再コンパイルすることによって、暗黙的に再コンパイルする必要がなくなるため、それに関連する実行時コンパイル・エラーおよびパフォーマンス上のオーバーヘッドの発生を防止できます。

なし

権限:

このコマンドを使用するには、パッケージが自分のスキーマであるか、またはユーザーがALTER ANY PROCEDURE権限を所有している必要があります。

なし

:

ALTER PACKAGE emp_actions COMPILE BODY

T-SQLとPL/SQLの構文

この項では、Microsoft SQL ServerおよびSybase Adaptive Serverの構文と、それに相当し、Migration Workbenchで生成されるOracleの構文について説明します。次の構文の変換について説明します。

表には、Microsoft SQL ServerおよびSybase Adaptive Serverの構文と、それらに相当するOracleの構文を示します。また、変換に関する考慮点についてのコメントも示します。

Oracleの列に示すプロシージャは、Migration Workbenchによって直接出力されます。通常、Migration Workbenchは、次のいずれかの方法でMicrosoft SQL ServerおよびSybase Adaptive ServerのT-SQL構文を処理します。

CREATE PROCEDURE文

表3-16 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのCREATE PROCEDURE文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
AS
RETURN 0
CREATE OR REPLACE FUNCTION PROC1
RETURN INTEGER
AS
BEGIN
  RETURN 0;
END PROC1;

コメント

プロシージャ、ファンクションまたはパッケージがすでに存在している場合、REPLACEキーワードはそれらを置き換えるために追加されます。

パラメータの受渡し

表3-17 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのパラメータの受渡しの比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
@x int=-1,
@y money,
@z bit OUT,
@a char(20) = 'TEST'
AS
    RETURN 0
CREATE OR REPLACE FUNCTION PROC1(
  x IN NUMBER DEFAULT -1,
  y IN NUMBER DEFAULT NULL,
  z IN OUT NUMBER,
  a IN CHAR DEFAULT 'TEST')
  RETURN INTEGER
 AS
 BEGIN
   RETURN 0;
 END PROC1;

コメント

パラメータの受渡しは、Microsoft SQL ServerおよびSybase Adaptive ServerとOracleでほぼ同じです。デフォルトでは、特別に指定されていないかぎり、すべてのパラメータがINPUTパラメータです。

INPUTパラメータは、PL/SQLプロシージャ内からは変更できません。このため、INPUTパラメータは、値を割り当てることも、別のプロシージャにOUTパラメータとして渡すこともできません。Oracleでは、INパラメータにのみデフォルトの値を割り当てることができます。

Oracleでは、パラメータ名宣言内の@マークは削除されます。

Oracleでは、パラメータのデータ型定義に長さ/サイズは含まれません。

Microsoft SQL ServerおよびSybase Adaptive Serverのデータ型は、Oracleベースのデータ型に変換されます。たとえば、Oracleでは、Microsoft SQL ServerおよびSybase Adaptive Serverのすべての数値データ型はNUMBERに、すべての英数字データはVARCHAR2およびCHARに変換されます。

DECLARE文

表3-18 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのDECLARE文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
AS
DECLARE
        @x int,
        @y money,
        @z bit,
        @a char(20)
                RETURN 0
GO
CREATE OR REPLACE FUNCTION PROC1
RETURN INTEGER
AS
  x NUMBER(10,0);
  y NUMBER(19,4);
  z NUMBER(1,0);
  a CHAR(20);
BEGIN
  RETURN 0;
END PROC1;

コメント

ローカル変数を宣言する場合、Microsoft SQL ServerおよびSybase Adaptive ServerとOracleは同様のルールに従います。

変数宣言の有効範囲規則は、Migration Workbenchによって上書きされます。そのため、Oracleでは、すべてのローカル変数はパッケージ本体の最上位に定義されます。

IF文

表3-19 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのIF文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle

例1:

CREATE PROC proc1 @Flag int = 0
AS
BEGIN
DECLARE @x int
IF ( @Flag=0 )
 SELECT @x = -1
ELSE
 SELECT @x = 10
END

例1:

CREATE OR REPLACE PROCEDURE PROC1 (Flag IN NUMBER DEFAULT 0)AS
x NUMBER(10,0);
BEGIN
 BEGIN
  IF ( Flag = 0) THEN
    x := -1;
  ELSE
   x := 10;
  END IF;
 END;
END PROC1;

例2:

CREATE PROC proc1 @Flag char(2) = ''
AS
BEGIN
DECLARE @x int
IF ( @Flag='' )
 SELECT @x = -1
ELSE IF (@Flag = 'a')
 SELECT @x = 10
ELSE IF (@Flag = 'b')
 SELECT @x = 20
END

例2:

CREATE OR REPLACE PROCEDURE PROC1(Flag 	IN CHAR  DEFAULT '')
AS
x 	NUMBER(10,0);
BEGIN
 BEGIN
   IF  ( Flag IS NULL) THEN
     x := -1;
   ELSE
     IF ( Flag = 'a') THEN
       x := 10;
     ELSE
       IF ( Flag = 'b') THEN
         x := 20;
       END IF;
     END IF;
   END IF;
 END;
END PROC1;

例3:

CREATE PROC proc1
AS
BEGIN
DECLARE @x int
IF EXISTS ( SELECT * FROM table2 )
 SELECT @x = -1
END

例3:

CREATE OR REPLACE PROCEDURE PROC1
AS
x 	NUMBER(10,0);
BEGIN
  BEGIN
   BEGIN
     StoO_selcnt := 0;
     SELECT 1 INTO StoO_selcnt
     FROM DUAL
     WHERE EXISTS (SELECT *
                     FROM table2 );
   END;

   IF StoO_selcnt != 0 THEN
     x := -1;
   END IF;
  END;
END PROC1;

例4:

CREATE PROC proc1 @basesal money, @empid int
AS
BEGIN
IF (select sal from emp where   empid = @empid) < @basesal
     UPDATE emp
     SET sal_flag = -1
     WHERE empid = @empid
END

例4:

CREATE OR REPLACE PROCEDURE PROC1(
basesal 	IN NUMBER  DEFAULT NULL,
empid 	IN NUMBER  DEFAULT NULL)
AS
BEGIN
  BEGIN
    BEGIN
      StoO_selcnt := 0;
      SELECT 1 INTO StoO_selcnt
      FROM DUAL
      WHERE basesal > (SELECT sal
                      FROM emp
                      WHERE empid = empid );
    END;
    IF StoO_selcnt != 0 THEN
      UPDATE sa.emp
      SET sal_flag = -1
      WHERE empid = empid;
    END IF;
  END;
END PROC1;

コメント

例3と4では、StoO_selcntStoO_selcnt INTEGER;として宣言するか、Migration Workbenchのパーサー・オプションGenerate Maximal PL/SQLを有効にする必要があります。

Microsoft SQL ServerおよびSybase Adaptive ServerとOracleのIF文は、次の2つの場合を除いてほぼ同じです。

Microsoft SQL ServerおよびSybase Adaptive ServerのIf EXISTS(...)には、同等のPL/SQL構文がありません。 そのため、表3-19の例3に示すSELECT INTO WHERE EXISTS句とIF文に変換されます。

比較対象を指定したIF (SELECT... )には、同等のPL/SQL構文がありません。 そのため、表3-19の例4に示すSELECT INTO...WHERE...句に変換されます。

RETURN文

表3-20 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのRETURN文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
@x int
AS
IF @x = -1
        RETURN 25022
ELSE
        RETURN 25011
CREATE OR REPLACE FUNCTION PROC1(x IN NUMBER DEFAULT NULL)
 RETURN INTEGER
 AS
 BEGIN
     IF x = -1 THEN
       RETURN 25022;
     ELSE
       RETURN 25011;
     END IF;
 END PROC1;

コメント

RETURN文は、コール元のプログラムに単一の値を戻すために使用され、両方のデータベースで同様に動作します。 Microsoft SQL ServerおよびSybase Adaptive Serverでは数値データ型のみを戻すことができ、Oracleではサーバー・データ型またはPL/SQLデータ型のいずれかを戻すことができます。

PL/SQLプロシージャでは、RETURN文によって、データを戻さずにコール元のプログラムに制御のみを戻すことができます。このため、この値は、Microsoft SQL ServerおよびSybase Adaptive ServerのプロシージャがPL/SQLプロシージャに変換されるとコメント化されますが、PL/SQLファンクションに変換されるとコメント化されません。この処理は、Migration Workbenchによって自動的に行われます。

RAISERROR文

表3-21 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのRAISERROR文の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle
 CREATE PROC proc1
 AS
      RAISERROR 12345 "No Employees found"
CREATE OR REPLACE PROCEDURE PROC1
AS
BEGIN
  raise_application_error(-20999, 'No Employees found');
END PROC1;

コメント

Microsoft SQL ServerおよびSybase Adaptive Serverでは、RAISERRORを使用して、エラーが発生したことをクライアント・プログラムに通知します。この文はプロシージャの実行を終了しないため、次の文に制御が渡されます。

PL/SQLでは、RAISE_APPLICATION_ERROR文で同様の機能が提供されます。ただし、この文は、ストアド・サブプログラムの実行を終了し、コール元のプログラムに制御を戻します。この文は、RAISERROR文とRETURN文を組み合せた場合と同様に動作します。

EXECUTE文

表3-22 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのEXECUTE文の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle
 CREATE PROC proc1
 AS
EXEC SetExistFlag
EXEC SetExistFlag yes=@yes, @Status OUT
EXEC @Status = RecordExists
EXEC SetExistFlag @yes
CREATE OR REPLACE PROCEDURE PROC1
 AS
 BEGIN
  sa.SetExistFlag;
  sa.SetExistFlag(yes=>yes,Status);
  Status:=sa.RecordExists;
  sa.SetExistFlag(yes);
END PROC1;

コメント

EXECUTE文は、プロシージャ内から別のストアド・プロシージャを実行するために使用されます。PL/SQLでは、プロシージャは、PL/SQLブロック内からその名前でコールされます。

Migration Workbenchは、パラメータをコールする場合の表記法を位置表記法、名前表記法または混合表記法に変換します。パラメータをコールする場合の表記法については、この章の「スキーマ・オブジェクト」を参照してください。

WHILE文

表3-23 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのWHILE文の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle

例1:

CREATE PROC proc1
 @i int
 AS
         WHILE @i > 0

         BEGIN
          print 'Looping inside WHILE....'
          SELECT @i = @i + 1
         END

例1:

CREATE OR REPLACE PROCEDURE PROC1(i IN NUMBER DEFAULT NULL)
AS
BEGIN
   <<i_loop1>>
   WHILE i > 0 LOOP
   BEGIN
     DBMS_OUTPUT.PUT_LINE('Looping inside WHILE....') ;
     i := i + 1;
   END;
   END LOOP;
END PROC1;

例2:

CREATE PROC proc1
 @i int,
 @y int
 AS
         WHILE @i > 0
         BEGIN
          print 'Looping inside WHILE....'
          SELECT @i = @i + 1
         END

例2:

CREATE OR REPLACE PROCEDURE PROC1(
i 	IN NUMBER  DEFAULT NULL,
y 	IN NUMBER  DEFAULT NULL)
AS
BEGIN
 <<i_loop1>>
 WHILE  i > 0 LOOP
	BEGIN
	DBMS_OUTPUT.PUT_LINE('Looping inside  WHILE....') ;
      i := i + 1;
    END;
    END LOOP;
END PROC1;

例3:

CREATE PROC proc1
 AS
 DECLARE @sal money
 SELECT @sal = 0
 WHILE EXISTS(SELECT * FROM emp where sal < @sal )
 BEGIN
  SELECT @sal = @sal + 99

  DELETE emp
  WHERE sal < @sal
 END
 GO

例3:

CREATE OR REPLACE PROCEDURE PROC1
AS
  sal NUMBER(19,4);
BEGIN
  sal := 0;
  <<i_loop1>>
  WHILE 1 = 1 LOOP
  BEGIN
    BEGIN
      StoO_selcnt := 0;
      SELECT 1 INTO StoO_selcnt FROM DUAL
      WHERE ( EXISTS ( SELECT *
                         FROM emp
                        WHERE sal < sal ));
    END;
    IF StoO_selcnt != 1 THEN
       EXIT;
    END IF;
    sal := sal + 99;

    DELETE emp WHERE sal < sal;
  END;
  END LOOP;
END PROC1;

例4:

CREATE PROC proc1
 AS

 DECLARE @sal money

 WHILE (SELECT count (*) FROM emp ) > 0
 BEGIN
 SELECT @sal = max(sal) from emp
  WHERE stat = 1

   DELETE emp
  WHERE sal < @sal
 END
 GO

例4:

CREATE OR REPLACE PROCEDURE PROC1
AS
sal 	NUMBER(19,4);
BEGIN
  <<i_loop1>>
  WHILE 1 = 1 LOOP
  BEGIN
    BEGIN
      StoO_selcnt := 0;
      SELECT 1 INTO StoO_selcnt FROM DUAL
      WHERE ( 0 < ( SELECT count(*)
                      FROM emp ));
    END;
    IF StoO_selcnt != 1 THEN
      EXIT;
    END IF;

    SELECT MAX(sal)
      INTO sal
      FROM emp
     WHERE stat = 1;

    DELETE emp WHERE sal < sal;
   END;
   END LOOP;
END PROC1;

コメント

Migration Workbenchを使用して、ほぼすべてのWHILE構文を変換できます。ただし、Microsoft SQL ServerおよびSybase Adaptive ServerのWHILEループ内のCONTINUEには、PL/SQLに同等の構文はありません。この構文は、ラベルを指定したGOTO文を使用してシミュレートされます。 Migration Workbenchは、単一パスのパーサーであるため、すべてのWHILEループの先頭にラベル文を追加します(表3-23の例2を参照)。

GOTO文

表3-24 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのGOTO文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
 CREATE PROC proc1 @Status int
 AS
 DECLARE @j int
         IF @Status = -1
                 GOTO Error

         SELECT @j = -1
 Error:
         SELECT @j = -99
CREATE OR REPLACE PROCEDURE PROC1(
   Status IN NUMBER DEFAULT NULL)
 AS
   j NUMBER(10,0);
 BEGIN
   IF Status = -1 THEN
     GOTO Error;
   END IF;

   j := -1;

  <<Error>> NULL;

  j := -99;
END PROC1;

コメント

GOTO <label>文は自動的に変換されます。手動で変更する必要はありません。

@@Rowcountおよび@@Error変数

表3-25 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでの@@Rowcountおよび@@Error変数の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle
CREATE PROC proc1
 AS
   DECLARE @x int
   SELECT @x=count(*) FROM emp
    IF @@rowcount = 0
        print 'No rows found.'
         IF @@error = 0
         print 'No errors.'
CREATE OR REPLACE PROCEDURE PROC1
AS
StoO_selcnt  INTEGER;
StoO_error  INTEGER;
StoO_rowcnt  INTEGER;
StoO_crowcnt  INTEGER := 0;
StoO_fetchstatus	  INTEGER := 0;
StoO_errmsg  VARCHAR2(255);
StoO_sqlstatus	  INTEGER;
x   NUMBER(10,0);

BEGIN

 SELECT count(*)
   INTO x
   FROM emp;

 IF StoO_rowcnt = 0 THEN
   DBMS_OUTPUT.PUT_LINE('No rows found.') ;
 END IF;

 IF StoO_error = 0 THEN
   DBMS_OUTPUT.PUT_LINE('No errors.') ;
 END IF;

END PROC1;

コメント

パーサー・オプションGenerate Maximal PL/SQLは、この例のために追加されました。

@@rowcountは、StoO_rowcntに変換されます。この変数は、PL/SQLのカーソル属性SQL%ROWCOUNTからその値を取得します。

@@errorは、StoO_errorに変換されます。この変数には、SQLCODEファンクションによって戻された値が含まれます。SQLCODEによって戻された値は、例外ブロック内でのみ割り当てる必要があります。そうでない場合は、値0が戻されます。 これを行うには、SQL文の前後にローカル例外ブロックが必要です。この場合は手動で行う必要があります。他のグローバル変数は、警告メッセージを戻して変換されます。これらは、手動で変換する必要がある場合があります。

ASSIGNMENT文

表3-26 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのASSIGNMENT文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
AS
DECLARE @x int
   SELECT @x = -1
   SELECT @x=sum(salary) FROM employee
CREATE OR REPLACE PROCEDURE PROC1
 AS
 x NUMBER(10,0);
 BEGIN
   x := -1;
   SELECT SUM(salary)
     INTO x
     FROM employee;
END PROC1;

コメント

Microsoft SQL ServerおよびSybase Adaptive Serverでの割当ては、SELECT文を使用して行います(表3-26を参照)。

PL/SQLでは、次の方法で値を変数に割り当てます。

割当て文を使用して、変数または式の値をローカル変数に割り当てます。SELECT..INTO句を使用して、データベースから値を割り当てます。これを行うには、次の例に示すように、SQLによって1行のみが戻されるか、またはNULL値を変数に割り当てる必要があります。

        SELECT empno INTO empno
        FROM employee
        WHERE ename = 'JOE RICHARDS'

SELECT文

表3-27 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのSELECT文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle

例1

CREATE PROC proc1
AS
SELECT ename FROM employee

例1

CREATE OR REPLACE PROCEDURE PROC1(
   RC1 IN OUT Omwb_emulation.globalPkg.RCT1)
AS
BEGIN
   OPEN RC1 FOR
   SELECT ename
     FROM employee;
END PROC1;

例2

CREATE PROC proc1
AS
DECLARE @name char(20)
  SELECT @id = id
  FROM employee

  RETURN id

例2

CREATE OR REPLACE FUNCTION PROC1
RETURN INTEGER
AS
name 	CHAR(20);

BEGIN
  FOR rec IN ( SELECT id
                 FROM employee)
  LOOP
    id := rec.id ;
  END LOOP;

  RETURN id;
END PROC1;

コメント

それぞれのアーキテクチャの違いのため、Microsoft SQL Server 6.5のストアド・プロシージャは、Oracleとは異なる方法でクライアント・プログラムにデータを戻します。

Microsoft SQL Server 6.5とOracleでは、ストアド・プロシージャの出力パラメータを使用して、すべてのデータをクライアントに渡すことができます。 Microsoft SQL Server 6.5では、結果セットという別の方法を使用してサーバーからクライアントにデータを転送します。

GROUP BY句が指定されたSELECT文

表3-28 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのGROUP BY句が指定されたSELECT文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
AS
DECLARE @ename char(20)
DECLARE @salary int
SELECT @ename=ename, @salary=salary FROM emp
WHERE salary > 100000
GROUP BY deptno
CREATE OR REPLACE PROCEDURE PROC1
AS
  ename CHAR(20);
  salary NUMBER(10,0);
BEGIN
 FOR rec IN ( SELECT ename, salary
                FROM emp
               WHERE salary > 100000
               GROUP BY deptno)
 LOOP
   ename := rec.ename ;
   salary := rec.salary ;
 END LOOP;
END PROC1;

コメント

T-SQLでは、GROUP BY句で使用される列をSELECT構文のリストの一部にする必要がないGROUP BY文を使用できます。PL/SQLでは、このタイプのGROUP BY句は使用できません。

Migration Workbenchは、このタイプのSELECT文をPL/SQLに変換します。ただし、Oracleで同様に動作するPL/SQL文はエラーを戻します。

列別名

表3-29 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでの列別名の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
@Status int=0
AS
        SELECT x=sum(salary) FROM employee
CREATE OR REPLACE PROCEDURE PROC1(
   Status IN NUMBER DEFAULT 0,
   RC1 IN OUT Omwb_emulation.globalPkg.RCT1)
AS
BEGIN
  OPEN RC1 FOR
  SELECT SUM(salary) x
    FROM employee;
END PROC1;

コメント

Migration Workbenchを使用して、Microsoft SQL Server固有の列別名をOracle形式の列別名に変換できます。手動で変更する必要はありません。

FROMが指定されたUPDATE文

表3-30 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのFROMが指定されたUPDATE文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
AS
        UPDATE table1
        SET col1 = 1
        FROM table1, table2
        WHERE table1.id = table2.id
CREATE OR REPLACE PROCEDURE PROC1
AS
  UF1_rowid ROWID;
  UF1_oval1 table1.col1%TYPE;
  CURSOR UF1_cursor IS
    SELECT table1.ROWID, 1
      FROM table1, table2
     WHERE table1.id = table2.id
       FOR UPDATE OF table1.col1;
BEGIN

 OPEN UF1_cursor;
 LOOP
   FETCH UF1_cursor INTO UF1_rowid, UF1_oval1;
   EXIT WHEN UF1_cursor%NOTFOUND;

   UPDATE table1
      SET col1 = UF1_oval1
    WHERE ROWID = UF1_rowid;

   StoO_rowcnt := SQL%ROWCOUNT;
 END LOOP;

 CLOSE UF1_cursor;
END PROC1;

FROMが指定されたDELETE文

表3-31 OracleとMicrosoft SQL ServerおよびSybase Adaptive ServerでのFROMが指定されたDELETE文の比較

Microsoft SQL ServerおよびSybase Adaptive Server Oracle
CREATE PROC proc1
AS
        DELETE FROM table1
        FROM table1, table2
        WHERE table1.id = table2.id
CREATE OR REPLACE PROCEDURE PROC1
AS
BEGIN
  DELETE FROM table1
    WHERE ROWID IN
      (SELECT table1.ROWID
      FROM table1, table2
      WHERE table1.id = table2.id);
END PROC1;

一時表

表3-32 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでの一時表の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
AS
        SELECT col1, col2
        INTO #Tab
        FROM table1
        WHERE table1.id = 100
CREATE GLOBAL TEMPORARY TABLE TT_TAB
ON COMMIT PRESERVE ROWS AS
SELECT
col1, col2
FROM table1
WHERE 1 = 2 ;

CREATE OR REPLACE PROCEDURE PROC1
AS
BEGIN
  DELETE FROM TT_TAB;
  INSERT INTO TT_TAB
  SELECT col1, col2
    FROM table1
   WHERE table1.id = 100;
END PROC1;

コメント

一時表はOracleでサポートされています。Migration Workbenchでは、この機能を使用します。 また、SELECT..INTO..#TEMPTABはINSERT文に変換されます。

カーソル処理

表3-33 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのカーソル処理の結果セットの比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC cursor_demo
AS
DECLARE @empno   INT
DECLARE @ename   CHAR(100)
DECLARE @sal     FLOAT
DECLARE cursor_1 CURSOR
FOR SELECT empno, ename, sal FROM emp

OPEN cursor_1

FETCH cursor_1 INTO @empno, @ename, @sal

CLOSE cursor_1

DEALLOCATE CURSOR cursor_1
CREATE OR REPLACE PROCEDURE PROC1
 AS
  empno NUMBER(10,0);
  ename CHAR(100);
  sal FLOAT(53);
  CURSOR cursor_1 IS
  SELECT empno, ename, sal
  FROM emp;
BEGIN
 NULL;/*DECLARE CURSOR cursor_1 */
 OPEN cursor_1;

 FETCH cursor_1 INTO
 empno, ename, sal;

 IF cursor_1%NOTFOUND THEN
   StoO_sqlstatus := 2;
   StoO_fetchstatus := -1;
 ELSE
   StoO_sqlstatus := 0;
   StoO_fetchstatus := 0;
 END IF;

 CLOSE cursor_1;

 NULL;

END PROC1;

コメント

Microsoft SQL ServerおよびSybase Adaptive Serverでは、T-SQLにカーソルが導入されました。Microsoft SQL ServerおよびSybase Adaptive ServerからOracleへのカーソルの構文変換は簡単に行うことができます。


注意:

PL/SQLでは、カーソルの割当て解除は透過的に行われるため、実行する必要はありません。

トランザクション処理文

表3-34 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのトランザクション処理文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
CREATE PROC proc1
AS
        BEGIN TRAN tran1

        UPDATE table1
        SET id = id + 1
        WHERE name = 'Event'

        IF @@Rowcount != 1
        BEGIN
          ROLLBACK TRAN tran1
                RETURN 25700
        END

        COMMIT TRAN tran1
        RETURN 0
CREATE OR REPLACE FUNCTION BYROYALTY
RETURN INTEGER
AS
BEGIN
omwb_emulation.globalPkg.trancount:=omwb_emulation.globalPkg.trancount+1;
SAVEPOINT tran1;
UPDATE table1
SET id = id + 1
WHERE name = 'Event';
 IF StoO_rowcnt != 1 THEN
  BEGIN
  ROLLBACK TO SAVEPOINT tran1;
  RETURN 25700;
  END;
END IF;
 IF omwb_emulation.globalPkg.trancount = 1 THEN
  COMMIT WORK;
 END IF;
 IF omwb_emulation.globalPkg.trancount > 0 THEN
  omwb_emulation.globalPkg.trancount:=omwb_emulation.globalPkg.trancount-1;
 END IF;
RETURN 0;
END BYROYALTY;

コメント

Migration Workbenchは、Microsoft SQL ServerおよびSybase Adaptive Serverのトランザクション・コマンドをOracleで同様に動作するコマンドに変換する場合に、1対1のマッピングを行います。 Oracleでのトランザクションの処理方法の詳細は、この章の後半の「トランザクション処理方法」を参照してください。


注意:

Microsoft SQL ServerおよびSybase Adaptive ServerとOracleでトランザクション・モデルが異なる場合があるため、同じ機能が保持されることを確認してください。

T-SQLとPL/SQLの言語要素

T-SQLはMicrosoft SQL ServerおよびSybase Adaptive Serverの手続き型SQL言語で、PL/SQLはOracleの手続き型SQL言語です。この項では、次のT-SQLとPL/SQLの言語要素について説明します。

トランザクション処理方法

Microsoft SQL ServerおよびSybase Adaptive Server

Microsoft SQL ServerおよびSybase Adaptive Serverでは、ANSI規格の暗黙的トランザクション・モデルおよび明示的トランザクション・モデルという2つの異なるトランザクション・モデルが提供されています。

Microsoft SQL ServerおよびSybase Adaptive Serverでは、ANSI規格のトランザクションをサポートするオプションが提供されています。これらのオプションは、SETコマンドを使用して設定または設定解除できます。

次のSETコマンドを実行すると、暗黙的トランザクション・モデルが設定されます。

set chained on

次のSETコマンドを実行すると、分離レベルが必要なレベルに設定されます。

set transaction isolation level {1|3}

isolation level 1を指定すると、内容を保証しない読取りが行われなくなります。isolation level 2を指定すると、反復不能な読取りが行われなくなります。isolation level 3を指定すると、仮読取りが行われなくなります。ANSI規格では、isolation level 3を指定する必要があります。 Microsoft SQL ServerおよびSybase Adaptive Serverの場合、デフォルトはisolation level 1です。

Microsoft SQL ServerおよびSybase Adaptive Serverでは、isolation level 3を実装するために、トランザクションに関連するすべての表にHOLDLOCKが適用されます。Microsoft SQL ServerおよびSybase Adaptive Serverでは、ページ・レベル・ロックとともに、HOLDLOCKを使用してユーザーを長時間ブロックできます。これを行うとレスポンス時間が長くなります。

Microsoft SQL ServerおよびSybase Adaptive Serverのアプリケーションで、isolation level 3が指定されたANSI規格の連鎖(暗黙的)トランザクションを実装すると、Oracleでは(リピータブル・リードが保証される)ANSI規格の暗黙的トランザクション・モデルが実装されるため、このアプリケーションの移行が正常に行われます。

非ANSI規格のアプリケーションでは、Microsoft SQL ServerおよびSybase Adaptive Serverのトランザクションは明示的です。論理トランザクションは、BEGIN TRANSACTION文を使用して明示的に開始する必要があります。トランザクションは、COMMIT TRANSACTION文を使用してコミットするか、またはROLLBACK TRANSACTION文を使用してロールバックします。トランザクションには、名前を付けることができます。たとえば、次の文は、名前を付けてトランザクションを開始します。

account_tran.
BEGIN TRANSACTION account_tran

明示的トランザクション・モードでは、ネストしたトランザクションを使用できます。ただし、可能なのは構文上のネストです。トランザクションは、一番外側のBEGIN TRANSACTIONおよびCOMMIT TRANSACTION文によってのみ実際に作成およびコミットされます。内側のCOMMIT TRANSACTIONは実際にはコミットされないため、この構文はわかりにくい場合があります。

次に、ネストしたトランザクションの例を示します。

BEGIN TRANSACTION
        /* T/SQL  Statements */
        BEGIN TRANSACTION
        /* T/SQL  Statements */
                BEGIN TRANSACTION account_tran
                /* T/SQL  Statements */
                IF SUCCESS
                        COMMIT TRANSACTION account_tran
                ELSE
                        ROLLBACK TRANSACTION account_tran
                END IF
        /* T/SQL  Statements */
        IF SUCCESS
                COMMIT TRANSACTION
        ELSE
                ROLLBACK TRANSACTION
        END IF
        /* T/SQL  Statements */
COMMIT TRANSACTION

BEGIN TRANSACTIONおよびCOMMIT TRANSACTION文がネストされている場合は、一番外側の組によってトランザクションが作成およびコミットされ、内側の組ではネスト・レベルが追跡されるのみです。トランザクションは、一番外側のCOMMIT TRANSACTION文が実行されるまでコミットされません。通常、トランザクションのネストは、BEGIN TRANSACTION/COMMIT TRANSACTION文を含むストアド・プロシージャを使用して、トランザクション処理文を含む他のプロシージャをコールすると発生します。 グローバル変数@@trancountは、現行のユーザーに対して現在アクティブなトランザクションの数を追跡します。複数のトランザクションをオープンしている場合は、ROLLBACKを実行後、COMMITを実行する必要があります。

内側のCOMMIT TRANSACTION文は、名前の有無にかかわらず実行されません。名前が付いていない内側のROLLBACK TRANSACTION文は、一番外側のBEGIN TRANSACTION文にロールバックされ、現行のトランザクションを取り消します。名前が付いている内側のROLLBACK TRANSACTION文は、名前が付いている各トランザクションを取り消します。

Oracle

Oracleでは、ANSI規格の暗黙的トランザクション方法を使用できます。論理トランザクションは、COMMIT、ROLLBACKまたはデータベースへの接続を行った後の最初の実行SQL文で開始されます。トランザクションは、COMMIT、ROLLBACKまたはデータベースからの切断を行うと終了します。暗黙的COMMIT文は、各DDL文の実行前および実行後に発行されます。有効にできる論理トランザクションは1セッション当たり1つのみのため、暗黙的トランザクション・モデルを使用すると、手動でトランザクションをネストする必要がなくなります。ユーザーは、トランザクションにSAVEPOINTを設定し、一部のトランザクションをSAVEPOINTにロールバックできます。

次に例を示します。

UPDATE test_table SET col1='value_1';
SAVEPOINT first_sp;
UPDATE test_table SET col1='value_2';
ROLLBACK TO SAVEPOINT first_sp;
COMMIT;   /* col1 is 'value_1'*/

変換準備に関する推奨事項

論理トランザクションは、Microsoft SQL ServerおよびSybase Adaptive ServerとOracleでは異なる方法で処理されます。Microsoft SQL ServerおよびSybase Adaptive Serverでは、トランザクションはデフォルトで明示的です。Oracleでは、ANSI規格の暗黙的トランザクション方法が実装されます。これによって、T-SQLトランザクション処理文からPL/SQLトランザクション処理文に直接変換する必要がなくなります。

また、Microsoft SQL ServerおよびSybase Adaptive Serverでは、ストアド・プロシージャのトランザクションでネスト可能である必要がありますが、Oracleでは、トランザクションのネストはサポートされていません。

次の表では、Microsoft SQL ServerおよびSybase Adaptive ServerとOracleのトランザクション処理文を比較します。

表3-35 OracleとMicrosoft SQL ServerおよびSybase Adaptive Serverでのトランザクション処理文の比較

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
BEGIN TRAN

BEGIN TRAN tran_1
 SAVEPOINT tran_1
COMMIT TRAN

(ネスト・レベル=1が指定されたトランザクション用)

 COMMIT
COMMIT TRAN

(ネスト・レベル>1が指定されたトランザクション用)

COMMIT TRAN tran_1

(ネスト・レベル=1が指定されたトランザクション用)

  COMMIT
COMMIT TRAN tran_1

(ネスト・レベル>1が指定されたトランザクション用)

ROLLBACK TRAN
ROLLBACK
ROLLBACK TRAN tran_1
ROLLBACK TO SAVEPOINT tran_1

変換時、Migration Workbenchでは、現行のトランザクション処理文のネスト・レベルは判断できません。 変数@@trancountはランタイム環境変数です。

表3-38に、Oracleでのトランザクション処理文の変換方法に対して現在実装されているMicrosoft SQL ServerおよびSybase Adaptive Serverを示します。

表3-36 トランザクション処理文の変換方法

Microsoft SQL ServerおよびSybase Adaptive Server
Oracle
BEGIN TRAN
/*BEGIN TRAN  >>> statement ignored <<<*/
BEGIN TRAN tran_1
 SAVEPOINT tran_1;
COMMIT TRAN

(ネスト・レベル=1が指定されたトランザクション用)

 COMMIT WORK;
COMMIT TRAN

(ネスト・レベル>1が指定されたトランザクション用)

 COMMIT WORK;
COMMIT TRAN tran_1

(ネスト・レベル=1が指定されたトランザクション用)

 COMMIT WORK;
COMMIT TRAN tran_1

(ネスト・レベル>1が指定されたトランザクション用)

 COMMIT WORK;
ROLLBACK TRAN
 ROLLBACK WORK;
ROLLBACK TRAN tran_1
 ROLLBACK TO SAVEPOINT tran_1
SAVE TRAN tran_1
SAVEPOINT tran_1

2つのデータベースでトランザクションを処理する方法に違いがあるため、トランザクションの再編成を検討する必要がある場合があります。

トランザクション処理文がストアド・プロシージャのコードではなくクライアントのコードの一部となるように、クライアント/サーバー・アプリケーションを設計します。通常、論理トランザクションはユーザーが設計および制御する必要があるため、このように設計すると効果的です。

ストアド・プロシージャの変換の場合は、SAVEPOINTをプロシージャの先頭に設定し、SAVEPOINTにのみロールバックすることを検討してください。Microsoft SQL ServerおよびSybase Adaptive Serverでは、少なくとも外側のトランザクションがクライアント・アプリケーションで制御されるように変更します。

例外処理方法およびエラー処理方法

Microsoft SQL ServerおよびSybase Adaptive Server

Microsoft SQL ServerおよびSybase Adaptive Serverでは、前の文によって生成されたエラー状態に関係なく、制御が次の文に渡されるため、各SQL文の実行後にエラーを確認する必要があります。 クライアントのERROR_HANDLERルーチンは、サーバー・エラーが発生した場合、コールバック・ルーチンとして起動されます。エラー状態はこのコールバック・ルーチンで処理できます。

ストアド・プロシージャは、RAISERROR文を使用してエラー状態をクライアントに通知します。この文を使用しても、制御はコール元のルーチンに戻されません。

Microsoft SQL ServerおよびSybase Adaptive Serverでは、システム表を使用してエラー・メッセージをカスタマイズできます。システム・プロシージャを使用して、エラー・メッセージをこの表に追加できます。

Oracle

Oracleでは、次の文に進む前に、各SQL文でエラーが自動的に確認されます。エラーが発生すると、すぐに制御が例外ハンドラ(存在する場合)に渡されます。これによって、すべてのSQL文の状態を確認する必要がなくなります。たとえば、SELECT文でデータベース内の行が検出されない場合は、例外が発生します。ブロックの対応する例外ハンドラ部分には、このエラーを処理するコードが含まれている必要があります。 RAISE_APPLICATION_ERROR組込みプロシージャは、サーバー・エラー状態をクライアントに通知し、コール元のルーチンにすぐに戻します。

Oracleでは、暗黙的SAVEPOINTがプロシージャの先頭に指定されます。 RAISE_APPLICATION_ERROR組込みプロシージャによって、このSAVEPOINT、またはプロシージャ内の最後にコミットされたトランザクションにロールバックされます。制御は、コール元のルーチンに戻されます。

OracleのRAISE_APPLICATION_ERROR文によって、ユーザーはエラー・メッセージをカスタマイズできます。例外が発生した場合は、PL/SQLによって、SQLCODEがコール元に自動的に戻されます。SQLCODEは、処理されるまで継続して伝播します。

推奨事項:

OracleでMicrosoft SQL ServerおよびSybase Adaptive Serverの動作をシミュレートするには、各SQL文を、同様に動作するPL/SQLブロックで囲む必要があります。このブロックで、SQL文用に検出する必要がある例外を処理する必要があります。

Microsoft SQL ServerおよびSybase Adaptive Serverの動作のシミュレートに必要な特別なコードの詳細は、この章の「T-SQLとPL/SQLの構文」を参照してください。

Microsoft SQL ServerおよびSybase Adaptive Serverのストアド・プロシージャのRAISERROR文の直後にRETURN文を指定すると、これらの2つの文をOracleのRAISE_APPLICATION_ERROR文に変換できます。

ユーザー定義の表を使用してエラー・メッセージをカスタマイズできます。標準ルーチンを作成し、この表にエラー・メッセージを取得できます。この方法には、2つの目的があります。システムの移植性を高めること、および管理者がエラー・メッセージを集中制御できるようにすることです。

特別なグローバル変数

Microsoft SQL ServerおよびSybase Adaptive Server

次のグローバル変数は、変換処理で特に有効です。

@@error:

最後に実行したT-SQL文の実行状態を示すサーバー・エラー・コードです。 コード例については、「@@Rowcountおよび@@Error変数」を参照してください。

@@identity:

文によって最後に生成された識別値を戻します。ROLLBACKSまたは他のトランザクションのため、前の設定には戻りません。

@@rowcount:

最後に実行したT-SQL文によって影響を受ける行の数です。 コード例については、「@@Rowcountおよび@@Error変数」を参照してください。

@@servername:

Microsoft SQL ServerおよびSybase Adaptive Serverのローカル・サーバーの名前です。

@@sqlstatus:

最後のFETCH文の状態情報です。

@@tranchained:

T-SQLプロシージャの現行のトランザクション・モードです。 @@tranchainedによって1が戻される場合、TL/SQLプロシージャは連鎖状態か、暗黙的トランザクション・モードです。

@@trancount:

現行のユーザーのネストしたトランザクションのネスト・レベルを追跡します。

@@transtate:

トランザクションの現行の状態です。

Oracle

SQLCODE:

最後に実行したPL/SQL文の実行状態を示すサーバー・エラー・コードです。

SQL%ROWCOUNT:

PL/SQLプロシージャ内から実行した各SQL文に対応付けられた暗黙カーソルに追加された変数です。 この変数には、暗黙カーソルに追加されたSQL文を実行すると影響を受ける行の数が含まれます。

推奨事項:

Oracleには、@@error変数と完全に同等の機能(SQLCODEファンクション)があります。SQLCODEファンクションは、サーバー・エラー・コードを戻します。

OracleのSQL%ROWCOUNT変数は、機能的に@@rowcountと同等です。

PL/SQLでは、さらに多くの特別なグローバル変数を使用できます。ここでは、一部のグローバル変数のみについて説明します。T-SQLでも、さらに多くの特別なグローバル変数を使用できます。ここでは、変換処理で重要な役割を果たす一部のグローバル変数についてのみ説明します。

演算子

Microsoft SQL ServerおよびSybase Adaptive ServerとOracleの演算子については、第2章の「データ操作言語」を参照してください。

組込みファンクション

Microsoft SQL ServerおよびSybase Adaptive ServerとOracleの組込みファンクションについては、第2章の「データ操作言語」を参照してください。

Microsoft SQL ServerおよびSybase Adaptive Serverストアド・プロシージャ内のDDL構文

Microsoft SQL ServerおよびSybase Adaptive Serverでは、DDL構文をストアド・プロシージャの一部にできます。Oracleでは、DDL文を動的SQLの一部にできます。また、各DDL文の実行後にCOMMIT文が発行されます。

T-SQLのほぼすべてのDDL構文で、構文エラーが発生します。Migration Workbenchを使用してT-SQLプロシージャをPL/SQLに変換するには、DDL文をT-SQLソースから削除する必要があります。

Migration Workbenchでは、次のDDL文は無視されます。これらの文は、処理されない文であることを示すメッセージとともに出力に表示されます。

CREATE TABLE
DROP TABLE
CREATE VIEW
DROP VIEW
CREATE INDEX
DROP INDEX