download.microsoft.comdownload.microsoft.com/.../migrateoracletosqlserver2008.docx · web...

Click here to load reader

Upload: others

Post on 30-Jan-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Oracle から SQL Server 2008 への移行ガイド

SQL Server 技術資料

執筆者: Vladimir Kisil (DB Best Technologies)、Valery Fomenko (DB Best Technologies)、Yuri Rusakov (DB Best Technologies)

テクニカル レビュー担当者: Dmitry Balin (DB Best Technologies)

公開日: 2009 年 8 月

適用対象: SQL Server 2008 および SQL Server 2008 R2

概要: このホワイト ペーパーでは、Oracle 7.3 以降のデータベースを SQL Server 2008 に移行するときの課題について検討し、この 2 つのプラットフォームでのデータベース オブジェクト、SQL Dialect、および手続き型コードの実装の違いを明らかにします。また、SQL Server Migration Assistant (SSMA) 2008 for Oracle での移行プロセス全体について、データベース オブジェクトと PL/SQL コードの変換に重点を置いて詳しく説明します。

制作: DB Best Technologies LLC

P.O. Box 7461, Bellevue, WA 98008

電話番号: (408) 202-4567

電子メール: [email protected]

Web: www.dbbest.com

著作権

このドキュメントは暫定版であり、このソフトウェアの最終的な製品版の発売前に大幅に変更されることがあります。

このドキュメントに記載されている情報は、このドキュメントの発行日における Microsoft の見解を示すものです。変化する市場状況に対応する必要があるため、このドキュメントは、記載された内容の実現に関する Microsoft の確約とは見なされないものとします。また、発行以降に発表される情報の正確性に関して、Microsoft はいかなる保証もいたしません。

このホワイト ペーパーに記載された内容は情報提供のみを目的としており、明示、黙示、または法律上の規定にかかわらず、これらの情報について Microsoft はいかなる責任も負わないものとします。

このソフトウェアおよびマニュアルは、本製品の使用許諾契約書の下でのみ使用することができます。このソフトウェアおよびマニュアルのいかなる部分も、米国 Microsoft Corporation の書面による許諾を受けることなく、その目的を問わず、どのような形態であっても、複製または譲渡することは禁じられています。ここでいう形態とは、複写や記録など、電子的な、または物理的なすべての手段を含みます。

Microsoft は、このマニュアルに記載されている内容に関し、特許、特許申請、商標、著作権、またはその他の無体財産権を有する場合があります。別途 Microsoft のライセンス契約上に明示の規定がない限り、このドキュメントはこれらの特許、商標、著作権、またはその他の無体財産権に関する権利をお客様に許諾するものではありません。

特に記載していない場合、このソフトウェアおよびマニュアルで使用している会社、組織、製品、ドメイン名、電子メール アドレス、ロゴ、人物、場所、出来事などの名称は架空のもので、実在する商品名、団体名、個人名などとは一切関係ありません。

© 2009 Microsoft Corporation. All rights reserved.

Microsoft および SQL Server は、米国 Microsoft Corporation の米国およびその他の国における登録商標です。

記載されている会社名、製品名には、各社の商標のものもあります。

目次

概要6

Oracle から SQL Server 2008 への移行の概要7

移行の主なステップ7

データベース オブジェクトの変換8

SQL 言語の違い9

PL/SQL の変換10

SSMA for Oracle のデータ移行アーキテクチャ11

SSMA の実装11

ソリューションのレイヤ11

クライアント アプリケーション12

ストアド プロシージャのインターフェイス12

データベース レイヤ12

移行実行可能ファイル13

メッセージ処理13

結果の検証13

Oracle のデータ型の移行14

数値型15

文字型16

日付と時刻17

ブール型17

ラージ オブジェクト型17

XML 型18

ROWID 型18

Oracle の空間データの移行19

Oracle のシステム オブジェクトのエミュレート21

Oracle のシステム ビューの変換21

Oracle のシステム関数の変換28

Oracle のシステム パッケージの変換39

入れ子になった PL/SQL サブプログラムの変換58

インライン置換58

Transact-SQL のサブプログラムを使用したエミュレーション63

Oracle ユーザー定義関数の移行67

変換アルゴリズム67

関数にパラメータの既定値とパラメータのさまざまな表記法がある場合の関数呼び出しの変換74

Oracle のトリガの移行76

変換のパターン78

Oracle パッケージのエミュレート98

プロシージャと関数の変換98

オーバーロードされたプロシージャの変換99

パッケージ変数の変換100

パッケージ カーソルの変換100

初期化セクションの変換101

パッケージ変換のコード例103

Oracle シーケンスのエミュレート105

SSMA for Oracle V4.0 でのシーケンスの作成と削除の方法105

SSMA for Oracle V4.0 での NEXTVAL と CURRVAL のシミュレーション107

変換の例108

階層化されたクエリの移行112

Oracle の例外のエミュレート116

例外の発生116

例外の処理118

SSMA 例外の移行119

Oracle カーソルの移行122

構文122

カーソルの宣言123

カーソルを開く126

データのフェッチ126

CURRENT OF 句132

カーソルを閉じる132

SSMA for Oracle V4.0 の変換の例133

SQL Server 2008 での Oracle トランザクションのシミュレーション137

トランザクション管理モデルの選択137

自動コミット トランザクション137

暗黙的トランザクション137

明示的トランザクション138

同時実行モデルの選択138

トランザクションの動作を Oracle と同じようにする139

Oracle の自律型トランザクションのシミュレーション140

自律型プロシージャおよびパッケージ プロシージャのシミュレーション141

自律型関数およびパッケージ関数のシミュレーション142

自律型トリガのシミュレーション143

コード例144

Oracle のレコードおよびコレクションの移行145

コレクションの実装145

レコードの実装155

XML を使用したレコードおよびコレクションの実装157

XML レコードのエミュレーション用のサンプル関数160

CLR UDT を使用したレコードおよびコレクションのエミュレート161

まとめ169

DB Best Technologies について169

概要

Oracle データベースから Microsoft® SQL Server® 2008 に移行すると、多くの場合、コストの削減、より機能豊富な環境など、さまざまなメリットがもたらされます。無償で提供されている Microsoft SQL Server Migration Assistant (SSMA) for Oracle を使用すると、この移行を迅速に行うことができます。SSMA for Oracle V4.0 は、Oracle のデータベース オブジェクト (ストアド プロシージャを含む) を SQL Server のデータベース オブジェクトに変換し、それらを SQL Server に読み込み、Oracle のデータを SQL Server に移行して、移行したコードとデータを検証します。

このホワイト ペーパーでは、Oracle データベースを SQL Server 2008 に移行するときの課題について検討し、この 2 つのプラットフォームでのデータベース オブジェクト、SQL Dialect、および手続き型コードの実装の違いを明らかにします。

Oracle から SQL Server 2008 への移行の概要

ここでは、SSMA for Oracle での移行プロセス全体について、データベース オブジェクトと PL/SQL コードの変換に重点を置いて説明します。

移行の主なステップ

移行の最初のステップでは、ターゲット SQL Server データベースの物理構造を決定します。最も単純なケースでは、Oracle のテーブルスペースを SQL Server のファイル グループにマップできますが、ファイル グループ内のファイルと、ファイルに格納されている情報は異なるのが一般的であるため、通常は不可能です。

次のステップでは、Oracle のスキーマをターゲットにマップする方法を選択します。SQL Server では、スキーマは必ずしも特定のユーザーやログインに関連付けられていません。また、1 つのサーバーに複数のデータベースが含まれます。

スキーマのマッピングは、通常、次のいずれかの方法で行われます。

· SSMA の既定の動作では、すべての Oracle スキーマが個別の SQL Server データベースになり、各データベースのターゲット SQL Server スキーマが dbo (データベース所有者の定義済みの名前) に設定されます。Oracle スキーマ間の参照がほとんどない場合はこの方法を使用します。

· もう 1 つの方法では、すべての Oracle スキーマを 1 つの SQL Server データベースにマップします。この場合は、1 つの Oracle スキーマが、同じ名前の 1 つの SQL Server スキーマになります。この方法を使用するには、SSMA の既定の設定を変更する必要があります。さまざまなソース スキーマが互いに深く関連付けられている場合は、この方法を使用します。

SSMA では、スキーマ マッピングの方法を選択すると、データベース オブジェクトの変換とデータベース オブジェクトへの参照の変換の両方で、常にその方法が適用されます。

最適なスキーマ マッピングを選択できたら、ターゲット SQL Server データベースと、そのデータベースに必要なスキーマの作成を開始します。SQL Server と Oracle のセキュリティ機構はまったく異なるため、SSMA ではセキュリティ項目の移行は自動化されていません。あらゆる可能性を考慮に入れて、ユーザーが自分で判断できるようになっています。

SSMA による典型的な移行では、まずソース Oracle サーバーに接続し、SQL Server を実行しているターゲット サーバーを選択して、[スキーマの変換] を実行します。SSMA のワークスペースにターゲット オブジェクトが作成されたら、[データベースに読み込む] を使用して保存します。最後に、[データの移行] を実行します。これにより、データが必要に応じて変換され、ソース テーブルからターゲット テーブルに転送されます。データ移行プロセスは、SQL Server を実行しているサーバーで実行されます。この機能の内部実装については、「SSMA for Oracle のデータ移行アーキテクチャ」を参照してください。

データベース オブジェクトの変換

Oracle のデータベース オブジェクトに直接対応する要素が SQL Server にあるとは限りません。SSMA では、多くの場合、正確なエミュレーションのために追加のオブジェクトが作成されます。変換の原則を以下に示します。

· Oracle のテーブルは、それぞれ SQL Server のテーブルに変換されます。その際、テーブルに対して定義されているすべてのインデックス、制約、およびトリガも変換されます。ターゲット テーブルの構造は、型マッピングの定義を使用して決定されます。データ型の変換については、「Oracle のデータ型の移行」を参照してください。

· Oracle のビューは、SQL Server のビューに変換されます。ただし、具体化されたビューは例外で、通常のテーブルになります。SSMA では、よく使用される Oracle システム ビューがエミュレートされます。システム ビューの変換の詳細については、「Oracle のシステム オブジェクトのエミュレート」を参照してください。

· Oracle のストアド プロシージャは、SQL Server のストアド プロシージャに変換されます。Oracle のプロシージャでは、"入れ子になったサブプログラム" を使用して、メイン プロシージャの中で別のプロシージャや関数を宣言してローカルで呼び出すことができます。現在のバージョンの SSMA では、入れ子になったサブプログラムはサポートされていません。手動で変換する方法については、「入れ子になった PL/SQL サブプログラムの変換」を参照してください。

· Oracle のユーザー定義関数は、変換後に SQL Server の要件が満たされる場合は SQL Server の関数に変換されます。満たされない場合は、関数とストアド プロシージャの 2 つのオブジェクトが作成されます。この追加のプロシージャに元の関数のすべてのロジックが含まれており、別のプロセスで呼び出されます。詳細については、「Oracle ユーザー定義関数の移行」を参照してください。SSMA では、Oracle の標準関数のほとんどがエミュレートされます。すべての一覧については、「Oracle のシステム オブジェクトのエミュレート」を参照してください。

· Oracle の DML トリガは、SQL Server のトリガに変換されます。ただし、トリガ機能が異なるため、トリガの数や種類が変更される可能性があります。トリガの変換については、「Oracle のトリガの移行」を参照してください。

· Oracle には、パッケージなど、SQL Server に直接対応するものがないオブジェクトもあります。SSMA では、パッケージ化されたプロシージャや関数が個別のターゲット サブルーチンに変換され、スタンドアロンのプロシージャや関数の規則が適用されます。パッケージ化された変数、カーソル、型の変換など、パッケージの変換に関連するその他の問題については、「Oracle パッケージのエミュレート」を参照してください。また、SSMA では、いくつかのよく使用される Oracle システム パッケージをエミュレートすることができます。詳細については、「Oracle のシステム オブジェクトのエミュレート」を参照してください。

· SQL Server には、Oracle のシーケンスに直接対応するものはありません。SSMA では、2 つの方法のいずれかを使用してシーケンスを変換できます。1 つ目の方法では、シーケンスを SQL Server の ID 列に変換します。これは最も望ましい解決策ですが、Oracle のシーケンス オブジェクトはテーブルに関連付けられていないため、使用されているシーケンスが ID 列の機能に適合しない場合もあります。その場合は、2 つ目の方法として、追加のテーブルでシーケンスをエミュレートします。この方法は、1 つ目の方法ほど効果的ではありませんが、Oracle との互換性を確保するうえではより有効です。詳細については、「Oracle シーケンスのエミュレート」を参照してください。

· Oracle のプライベート シノニムは、ターゲット データベースに格納された SQL Server のシノニムに変換されます。パブリック シノニムは、sysdb データベースに定義されているシノニムに変換されます。

SQL 言語の違い

Oracle と SQL Server では、SQL 言語の異なるダイアレクトが使用されていますが、SSMA では、そのために生じるほとんどの問題を解決できます。たとえば、階層化されたクエリに対しては、Oracle では CONNECT BY ステートメントが使用されますが、SQL Server では共通テーブル式が使用されます。共通テーブル式の構文は Oracle の形式に似ておらず、ツリー トラバーサルの順序も異なります。SSMA による階層化されたクエリの変換については、「階層化されたクエリの移行」を参照してください。

また、Oracle の別の非標準機能である、(+) 修飾子を使用した特殊な外部結合構文は、SSMA で ANSI 形式に変換されます。

ROWID や ROWNUM などの Oracle の疑似列は、特に問題になります。ROWNUM は、結果セットのサイズを制限するためだけに使用されている場合は、SELECT ステートメントの TOP キーワードを使用してエミュレートされます。SELECT リスト内で使用されている場合は、ROW_NUMBER( ) 関数が使用されます。ROWID の問題は、ROWID という名前のオプションの列によって解決できます。この列には、SQL Server の一意識別子が格納されます。

SSMA では、動的 SQL ステートメントは変換されません。動的 SQL ステートメントでは、実行時まで実際のステートメントが不明であるため、ほとんどの場合、変換時には再現できないからです。この問題の回避策として、SSMA に表示される Oracle のメタベース ツリーには、アドホック SQL ステートメントを作成したり変換したりできる "ステートメント" という名前の特殊なノードが含まれています。動的 SQL コマンドの最終的な形を手動で再現できる場合は、この [ステートメント] ノード内のオブジェクトとして変換できます。

PL/SQL の変換

Oracle の PL/SQL 言語の構文と、SQL Server の手続き型言語である Transact-SQL の構文は、大きく異なります。そのため、ストアド プロシージャ、関数、トリガなどの PL/SQL コードの変換が 1 つの課題になります。しかし、SSMA では、これらの変換に関連するほとんどの問題を解決できます。また、PL/SQL の変数に対して特殊なデータ型マッピングを設定することもできます。

PL/SQL の変換の規則には、代入、IF、LOOP などのステートメントの変換のように単純なものもあれば、もっと複雑なものもあります。たとえば、「Oracle の例外のエミュレート」で説明する Oracle の例外の変換は、そうした難しいケースの 1 つです。そこで説明されている解決策に従うと、Oracle の動作をできる限り正確にエミュレートできますが、コードを見直して Oracle のエラー コードへの依存を取り除いたり、NO_DATA_FOUND のような条件の処理を単純化したりする必要がある場合もあります。

Oracle のカーソル機能は、SQL Server のカーソル機能とまったく同じではありません。SSMA によるこの違いの処理については、「Oracle カーソルの移行」を参照してください。

Oracle のトランザクション (特に自律型トランザクション) も、変換時に問題になります。トランザクションの実装をニーズに合った最適なものにするためには、多くの場合、SSMA によって生成されたコードを見直す必要があります。そのための手順については、「SQL Server 2008 での Oracle トランザクションのシミュレーション」と「Oracle の自律型トランザクションのシミュレーション」を参照してください。

最後の問題として、PL/SQL には、Transact-SQL では対応する型がない型が数多くあります。たとえば、レコードやコレクションがそうです。SSMA では、PL/SQL のレコードやコレクションが使用されているほとんどのケースを処理できます。また、PL/SQL のコレクションを手動でエミュレートする方法もいくつかあります。それらの方法については、「Oracle のレコードおよびコレクションの移行」を参照してください。

SSMA for Oracle のデータ移行アーキテクチャ

ここでは、SSMA for Oracle V4.0 のコンポーネントと、データ移行時のコンポーネント間のやり取りについて説明します。これらのコンポーネントは別々のコンピュータで実行され、Microsoft SQL Server 2008 のデータベース オブジェクトを使用して通信します。このアーキテクチャにより、移行のパフォーマンスと柔軟性を最大限に高めることができます。このしくみを理解することは、SSMA のデータ移行の環境を設定したり、移行プロセスを制御、監視、最適化したりするうえで役に立ちます。

SSMA の実装

SSMA for Oracle V4.0 の実装は、.NET Framework 2.0 で定義されている SqlBulkCopy クラスに基づいています。SqlBulkCopy の機能は、bcp ユーティリティに似ています。このユーティリティを使用すると、大量のデータをすばやく効率的に転送できます。ソース データベースへのアクセスは、Oracle クライアント ソフトウェアの Oracle Call Interface (OCI) を使用する .NET Framework Data Provider for Oracle によって確立されます。.NET Framework Data Provider for OLE DB を使用することもできますが、その場合は、Oracle OLE DB プロバイダがインストールされている必要があります。

SSMA for Oracle のデータ移行の設計のポイントを以下に示します。

· データ転送プロセスは、SQL Server で実行する必要があります。これにより、Oracle クライアントのインストール数を制限し、ネットワーク トラフィックを削減できます。

· クライアント アプリケーションは、SQL Server のストアド プロシージャを使用してプロセスを制御します。そのため、サーバーとの通信チャネルを新たに追加する必要はありません。既存のサーバー接続を再利用してプロセスを制御できます。

· SSMA ユーザーは、移行のために選択したすべてのテーブルを 1 つの実行コマンドで転送できます。

· ユーザーは、データ フローの進行状況を監視して、いつでも中止することができます。

ソリューションのレイヤ

データ移行プロセスに関与するレイヤは以下の 4 つです。

· クライアント アプリケーション (SSMA 実行可能ファイル)

· すべてのサーバー アクションのインターフェイスとして機能するストアド プロシージャ

· 次の 2 つのテーブルから成るデータベース レイヤ

· パッケージ情報テーブル

· 状態テーブル

· SQL Server ジョブの一部として起動し、データ転送を実行してその状態を反映するサーバー実行可能ファイル

クライアント アプリケーション

SSMA では、移行するソース テーブルをユーザーが自由に選択できます。一括コピー操作のバッチ サイズもユーザーが定義できます。

プロセスが開始されると、進行状況バーと [停止] ボタンが表示されます。エラーが見つかった場合は、適切なエラー メッセージが表示されて転送が中止されます。ユーザーが [停止] ボタンをクリックしてプロセスを中止することもできます。転送が正常に完了すると、各ソースの行数が対応するターゲット テーブルと比較されます。行数が一致していた場合は、転送が成功したと見なされます。

クライアント アプリケーションは、データ移行プロセスを直接制御しないため、メッセージ テーブルを使用して移行の状態に関するフィードバックを受け取ります。

ストアド プロシージャのインターフェイス

移行プロセスは、以下の SQL Server ストアド プロシージャによって制御されます。

· bcp_save_migration_package: パッケージ ID と XML パラメータを bcp_migration_packages テーブルに書き込みます。

· bcp_start_migration_process: 移行実行可能ファイルを起動する SQL Server ジョブを作成し、そのジョブの ID を返します。

· bcp_read_new_migration_messages: 移行実行可能ファイルによって追加された行を、既知のジョブ ID でフィルタ選択して返します。

· stop_agent_process: 移行ジョブを停止します。これには、元の接続を閉じる操作と、移行実行可能ファイルを終了する操作が含まれます。データは部分的に移行されます。

· bcp_clean_migration_data: 移行ジョブをクリーンアップするプロシージャです。

· bcp_post_process: 移行された 1 つのテーブルに関連するすべての後処理を実行するプロシージャです。

データベース レイヤ

SSMA は、[ssma_oracle].[bcp_migration_packages] という名前のパッケージ テーブルを使用して、現在のパッケージに関する情報を格納します。このテーブルの各行は移行の 1 回の実行に対応し、パッケージの GUID と、RSA で暗号化された接続文字列と移行するテーブルを表す XML を格納します。

[ssma_oracle].[ssmafs_bcp_migration_messages] という名前のメッセージ テーブルには、移行実行可能ファイルの実行中に生成されたメッセージが格納されます。

移行実行可能ファイル

移行アプリケーション (SSMA for Oracle Data Migration Assistant.exe) は、SQL Server ホストで実行されます。この実行可能ファイルのディレクトリは、SSMA 拡張パックのインストール時に決定されます。bcp_start_migration_package が移行アプリケーションを起動するときには、サーバー環境変数からディレクトリ名が取得されて、ハードコードされたファイル名と共に使用されます。

移行アプリケーションは、起動時にコマンド文字列からパッケージ ID を取得し、パッケージ テーブルから他のすべてのパッケージ関連情報 (ソースとターゲットの接続文字列、移行するテーブルのリストなど) を読み取ります。その後、テーブルを一度に 1 つずつ処理します。IDataReader インターフェイスを使用してソース行を取得し、WriteToServer メソッドを使用してターゲット テーブルに移動します。

バッファの行数は BatchSize の設定によって決まります。バッファがいっぱいになると、バッファのすべての行がターゲットにコミットされます。

一括コピー操作の進行状況は、SqlRowsCopied イベントと NotifyAfter プロパティを使用して通知されます。SqlRowsCopied イベントが生成されると、新しい行が挿入されて、進行状況に関する情報がメッセージ テーブルに送信されます。NotifyAfter プロパティは、行がいくつ処理されたら SqlRowsCopied イベントが生成されるかを定義します。この数は、ソース テーブルの行数の 25% に設定されています。

出力レコードは他にもあります。アプリケーションが終了すると、正常に終了した場合も例外が発生した場合も、終了メッセージがメッセージ テーブルに書き込まれます。例外が発生した場合は、エラー テキストも書き込まれます。BatchSize = 1 の場合は、問題が発生した行の列に関する追加情報も抽出されるため、問題の行を特定できます。

メッセージ処理

クライアント アプリケーションは、メッセージ テーブルを使用して移行実行可能ファイルからのフィードバックを受け取ります。移行の間、クライアントはこのテーブルをループでポーリングして、正しいパッケージ ID の新しい行が追加されていることを確認します。長期間にわたって新しい行が追加されていない場合は、サーバー実行可能ファイルで問題が発生した可能性があるため、タイムアウト メッセージが生成されてプロセスが終了します。

テーブルの移行が完了すると、正常に完了したことを知らせるメッセージがサーバー実行可能ファイルによって書き込まれます。ある程度大きなテーブルの場合は、次のバッチが正常にコミットされたことを示す多くの中間メッセージも含まれます。エラーが発生した場合は、サーバー プロセスから受け取ったエラー メッセージがクライアントに表示されます。

結果の検証

移行が開始される前に、移行する各テーブルの行数がクライアント アプリケーションによって計算されます。これにより、進行状況を正確に評価できるようになります。

移行が完了すると、ターゲット テーブルの行数がクライアントによって計算されます。行数が一致した場合は、移行全体が成功したと見なされます。一致しない場合はユーザーに通知され、ユーザーはソースとターゲットの行数を確認できます。

Oracle のデータ型の移行

Oracle で使用されているほとんどのデータ型は、正確に対応するデータ型が Microsoft SQL Server 2008 になく、小数点以下桁数、有効桁数、長さ、および機能が異なります。ここでは、SSMA for Oracle V4.0 に実装されているデータ型マッピングと、変換の問題について説明します。

SSMA は、Oracle に実装されている ANSI 型および DB2 型と、組み込みの Oracle 型をサポートしています。SSMA の型マッピングは、テーブルの列、サブプログラムの引数、関数の戻り値、およびローカル変数に適用されます。通常は、これらのカテゴリのすべてに同じマッピング規則が使用されますが、そうでない場合もあります。SSMA では、いくつかの定義済みの制限のマッピング規則を調整することができます。Oracle ビュー ペインの [型マッピング] タブで、スキーマ全体、特定のオブジェクトのグループ、または 1 つのオブジェクトに対してカスタムのマッピングを設定できます (図 1)。

図 1: Oracle の [型マッピング] タブ

ここでは、オブジェクト型、コレクション、レコードなどの複雑なデータ型の移行については説明しません。任意型や一部の特殊な構造 (空間型、メディア型など) についても同様です。

Oracle では、サブタイプを作成することができます。サブタイプとは、いくつかの基本型の別名です。サブタイプは SSMA では処理されませんが、その基本型を変換できる場合は手動でエミュレートすることができます。通常は、次のような Oracle の宣言を置き換えるだけで十分です。

SUBTYPE IS [NOT NULL]

これを次のような SQL Server 2008 の宣言に置き換えます。

CREATE TYPE FROM [NOT NULL]

サブタイプが Oracle のパッケージで定義されている場合は、ターゲットの を変更する必要もあります。PackageName$ などのパッケージ プレフィックスを追加して、この名前のスコープを設定します。

数値型

Oracle の基本固定小数点数型は NUMBER(, ) です。整数の場合は NUMBER()、浮動小数点数の場合は NUMBER になります。

SSMA の既定の動作では、NUMBER(, ) は numeric(, ) に、NUMBER() は numeric() にマップされます。NUMBER は float(53) になります (SQL Server で最も有効桁数が大きい浮動小数点数)。

INTEGER() 型と INTEGER 型は、Oracle では NUMBER(, 0) のように扱われますが、SQL Server には整数をより効率的に格納する専用の int 型があるため、int にマップされます。BINARY_INTEGER や PLS_INTEGER などの PL/SQL 型も、既定で int にマップされます。

実際の値の正確な範囲がわかる場合は、数値型の既定のマッピングをカスタマイズすることもできます。実際、SQL Server のあらゆる数値型をマッピングのターゲットにすることができます。ソース型より有効桁数の少ない型をマッピングのターゲットにする場合 (NUMBER -> smallint、NUMBER(20) -> int など) は、データの移行時やコードの実行時にオーバーフローが発生したり有効桁数が失われたりする可能性があるので注意してください。有効桁数を既定値より大きくすることもできます (INTEGER を bigint にマップするなど)。

既定の数値マッピングを変更する理由は他にもあります。それは、NUMBER フィールドを SQL Server の ID 列に変換する場合です。SQL Server では浮動小数点数の ID はサポートされていないため、int 型または numeric 型に変更します。

SSMA では、NUMBER 型のさまざまなシノニム (NUMERIC、DECIMAL、NATURAL、POSITIVE、DOUBLE_PRECISION、REAL、BINARY_FLOAT、BINARY_DOUBLE など) が認識され、適切にマップされます。

SIGNTYPE は、-1 を有効な値として格納できるように smallint にマップされます。

文字型

SSMA では、基本文字型の VARCHAR2 と CHAR が SQL Server の varchar と char に変換され、それぞれの長さが保持されます。PL/SQL の変数が 8,000 を超える固定サイズで宣言されている場合は、varchar(max) にマップされます。

プロシージャや関数に文字型の仮引数が含まれている場合、Oracle ではその長さを明示的に宣言する必要はありませんが、SQL Server では、varchar や char のパラメータは常に正確なサイズがわかっている必要があります。そのため、SSMA では、既定で最大の長さを適用するしかありません。したがって、VARCHAR2 や CHAR のパラメータは、ターゲット コードでは自動的に varchar(max) として宣言されます。ソース データの正確な長さがわかる場合は、この既定のマッピングを変更できます。

Oracle の VARCHAR2 や CHAR の列または変数がマルチバイト文字列を格納するように構成されている場合は、マッピングをカスタマイズして SQL Server の Unicode 型にマップします。以下に例を示します。

VARCHAR2-> nvarchar

CHAR-> nchar

そうしないと、データの移行時やターゲット コードの実行時に、非 ASCII 文字列が正しく処理されなくなる可能性があります。各国語文字列型 (NVARCHAR2 および NCHAR) として宣言されたソース文字列は、自動的に nvarchar と nchar にマップされます。

Oracle の RAW 文字列に対しても同様の方法が適用されます。この型は、binary または varbinary (既定) にマップできますが、サイズが 8,000 バイトの制限を超えている場合は varbinary(max) にマップされます。

SSMA では、これらの型のさまざまなシノニム (VARCHAR、CHARACTER、CHARACTER VARYING、NATIONAL CHARACTER、NATIONAL CHARACTER VARYING、STRING など) が認識されます。

日付と時刻

DATE は既定で datetime2[0] に変換されます。ただし、SQL Server で格納できる日付の範囲は datetime 型が 01/01/1753 ~ 12/31/9999、datetime2 型が 01/01/0001 ~ 12/31/9999 で、Oracle の DATE (4712 BC ~) ほど広くありません。そのため、そのようなはるか昔の日付がアプリケーションで使用されている場合は問題になる可能性があります。一方、SQL Server には、現代の日付をより効率的に格納できる smalldatetime 型があります。この型は、01/01/1900 ~ 06/06/2079 の日付をサポートしています。マッピングをカスタマイズするには、SSMA で smalldatetime をターゲット型として選択します。

日付と時刻を保持する Oracle 型には、その他に TIMESTAMP があります。この型は DATE に似ていますが、DATE より有効桁数が大きくなります (ナノ秒単位まで)。SQL Server の timestamp は、瞬間的な時間とは関係のないまったく別の型なので、TIMESTAMP は、SSMA の既定のマッピングを使用して datetime2 に変換することをお勧めします。datetime2 の精度は 100 ナノ秒ですが、この変換による有効桁数の喪失はほとんどの場合に許容されます。SQL Server 2008 では、日付にタイム ゾーンの情報を格納できます。この機能は、datetimeoffset データ型でサポートされています。

SQL Server には、Oracle の INTERVAL データ型に対応する型はありませんが、期間を使用する操作は、DATEADD 関数と DATEDIFF 関数を使用してエミュレートできます。DATEADD と DATEDIFF は、構文がまったく異なります。また、このホワイト ペーパーの執筆時点では、SSMA でこれらの変換を自動的に行うことはできません。

ブール型

SQL Server にはブール型はありません。ブール値を含むステートメントを SSMA で変換すると、ブール値が条件式に置き換えられます。格納されているブール データは、SQL Server の bit 型を使用してエミュレートされます。

ラージ オブジェクト型

Oracle のラージ オブジェクト型 (LOB) は、SQL Server 2008 で導入された新しい型である varchar(max)、nvarchar(max)、および varbinary(max) を使用して移行することをお勧めします。

Oracle

SQL Server 2008

LONG, CLOB

varchar(max)

NCLOB

nvarchar(max)

LONG RAW, BLOB, BFILE

varbinary(max)

SSMA のマッピングを変更して、以前のように text、ntext、および image を使用することもできますが、お勧めしません。SQL Server 2005 と SQL Server 2008 の新しい型の操作は、Oracle や SQL Server 2000 の方法よりシンプルです。SSMA では、現時点ではラージ オブジェクト型の操作を自動的に変換することはできませんが、上記のすべての型のデータを移行できます。ただし、BFILE 型は他の型と少し異なります。SSMA では、データをデータベースの外部に保存するという Oracle の概念は変換されないため、BFILE 型のデータを移行すると、ファイルの内容がバイナリ形式で SQL Server のテーブルに読み込まれます。ファイルがテキスト ファイルの場合は、その結果を varchar 形式に変換することもできます。サイズの大きいバイナリ フィールドをファイル システムに格納する必要がある場合は、varbinary(max) データ型で SQL Server 2008 の新しい FILESTREAM 属性を使用して手動で変換できます。

Oracle サーバーがマルチバイト文字のエンコードをサポートしている場合は、Unicode 文字を保持するために LONG 型と CLOB 型を nvarchar(max) にマップします。

XML 型

Oracle の XMLType は既定で SQL Server の xml にマップされます。XMLType 列のすべての XML データを SSMA で問題なく移行できます。これらの型に対する XQuery 操作は、Oracle と SQL Server で似ていますが、違いもあるため手動で処理する必要があります。

ROWID 型

ROWID 型と UROWID 型は、各行に対して生成できる GUID である uniqueidentifier にマップされます。ROWID 疑似列に依存するコードを変換する際には、SSMA によって ROWID 列が追加されていることを事前に確認してください (SSMA のプロジェクトの設定の [ROWID 列を生成する] オプションを参照してください)。ROWID 型の列のデータはそのまま SQL Server に移行できますが、uniqueidentifier に変換されると行の物理アドレスを表さなくなるため、SSMA によって生成された ROWID 列との対応関係は損なわれます。

Oracle の空間データの移行

Oracle Spatial は Oracle のサブシステムで、Oracle データベースの空間機能を簡単に使用できるようにする SQL 関数を提供します。空間オブジェクトの幾何学的記述が、専用のオブジェクト型である MDSYS.SDO_GEOMETRY 型の列を使用して 1 つの行に格納されます。

空間データは SQL Server 2008 でもサポートされており、geography と geometry という SQL CLR 型として実装されています。geography 型を使用すると、地球座標系で定義されたオブジェクトを格納できます。geometry 型は、平面オブジェクトに使用されます。SQL Server 2008 の空間データ型には、Open Geospatial Consortium (OGC) 仕様で定義されている Well Known Text (WKT) と Well Known Binary (WKB) の 2 つの形式のデータをインポート/エクスポートするためのメソッドが実装されています。空間機能は、SQL Server 2008 のすべてのエディション (Express を含む) でサポートされています。

SSMA for Oracle V4.0 では、SDO_GEOMETRY 型のテーブル列の移行はサポートされていません。SQL Server Integration Services (SSIS) をそのまま使用しても、OLE DB、ADO.NET、ODBC などの既存のプロバイダでは Oracle Spatial の型は認識されないため、あまり役に立ちません。

ここで提案する解決策は、Oracle Spatial と SQL Server 2008 の両方で WKT 形式への変換がサポートされていることに基づいています。また、ソース SDO_GEOMETRY 列が geography 型の SQL Server 列にマップされていると想定しています。データを転送する前に、ソース Oracle インスタンスを参照する SQL Server のリンク サーバーを作成する必要があります。移行を実行するには、ソース列の値を WKT 形式に変換し、結果のプレーンテキストを、OPENQUERY ステートメントを使用してターゲット geography 列に挿入します。

例:

次のように定義されている Oracle テーブルがあるとします。

CREATE TABLE geoinfo (id NUMBER(10) NOT NULL, geo MDSYS.SDO_GEOMETRY);

対応する SQL Server のテーブルは次のようになります。

CREATE TABLE geoinfo (id NUMERIC(10) NOT NULL, geo geography);

この場合、次の INSERT ステートメントで空間データを正しくコピーできます。

INSERT INTO geoinfo (id, geo)

SELECT id, geography::STGeomFromText(CAST(geo as nvarchar(max)), srid)

FROM OPENQUERY(ORACLE_LS,

’SELECT id, SDO_UTIL.TO_WKTGEOMETRY(g.geo) geo, g.geo.sdo_srid srid

FROM geoinfo g’)

ここで、ORACLE_LS は、ソース Oracle インスタンスを参照するリンク サーバーの名前です。Oracle 関数の TO_WKTGEOMETRY は、Spatial ジオメトリ オブジェクトを Well Known Text 形式に変換して返します。srid (spatial reference ID) は、WKT 文字列が SQL Server で解釈される方法を定義するために必要です。

Oracle のシステム オブジェクトのエミュレート

ここでは、ビュー、標準関数、パッケージ サブルーチンなどの Oracle のシステム オブジェクトが SSMA for Oracle V4.0 でどのように変換されるのかを説明します。現在サポートされていないパッケージを変換する方法に関するヒントも紹介します。

Oracle のシステム ビューの変換

SSMA for Oracle V4.0 では、よく使用される Oracle システム ビューを変換できます。Oracle の物理構造に密接に関連付けられている列や、対応する列が SQL Server 2008 にない列は、変換されません。SQL Server のビューに自動的に移行できるビューを以下に示します。

· ALL_INDEXES

· DBA_INDEXES

· ALL_OBJECTS

· DBA_OBJECTS

· ALL_SYNONYMS

· DBA_SYNONYMS

· ALL_TAB_COLUMNS

· DBA_TAB_COLUMNS

· ALL_TABLES

· DBA_TABLES

· ALL_CONSTRAINTS

· DBA_ CONSTRAINTS

· ALL_SEQUENCES

· DBA_SEQUENCES

· ALL_VIEWS

· DBA_VIEWS

· ALL_USERS

· DBA _USERS

· ALL_SOURCE

· DBA_SOURCE

· GLOBAL_NAME

· ALL_JOBS

· DBA_ JOBS

· V$SESSION

ここでは、以下のビューを手動で変換する方法を説明します。

· ALL_EXTENTS

· V$LOCKED_OBJECT

· DBA_FREE_SPACE

· DBA_SEGMENTS

SSMA for Oracle V4.0 によって生成されるシステム ビューのエミュレーションの場所

Oracle の DBA_* ビューと ALL_* ビューをエミュレートするビューは、それぞれ、.ssma_oracle.DBA_* と .ssma_oracle.ALL_* に作成されます。

USER_* ビューは、それらのビューが使用される各スキームに作成されます。それらのビューには、次の形式の WHERE 条件が追加されます。

OWNER =

SSMA でそれらのターゲット ビューが作成されるのは、生成されたコードで実際に参照されている場合だけです。

注  次のコードでは、SSMA では DBA_* ビューと USER_* ビューは ALL_* に基づいて作成されると想定しています。したがって、このドキュメントでは、DBA_* と USER_* については説明しません。

例:

CREATE VIEW ssma_oracle.ALL_TRIGGERS

AS

select

UPPER(t.name) as TRIGGER_NAME,

UPPER(s.name) as TABLE_OWNER,

UPPER(o.name) as TABLE_NAME,

CASE

WHEN t.is_disabled = 0 THEN 'ENABLED'

ELSE 'DISABLED'

END as STATUS

from sys.triggers t, sys.tables o, sys.schemas AS s

where t.parent_id = o.object_id

and o.schema_id = s.schema_id

GO

CREATE VIEW USER1.USER_TRIGGERS

AS

SELECT * FROM ssma_oracle.ALL_TRIGGERS v

WHERE v.OWNER = N'TEST_USER'

CREATE SYNONYM ssma_oracle.DBA_TRIGGERS

FOR TEST_DATABASE.ssma_oracle.ALL_TRIGGERS

ALL_INDEXES システム ビュー

owner、index_name、index_type、table_owner、table_name、table_type、uniqueness、compression、および prefix_length の各列が SSMA によって変換されます。

ALL_OBJECTS システム ビュー

owner、object_name、object_type、created、last_ddl_time、および generated の各列が SSMA によって変換されます。

ALL_SYNONYMS システム ビュー

すべての列が SSMA によって変換されます。

ALL_TAB_COLUMNS システム ビュー

OWNER、table_name、column_name、DATA_TYPE、data_length、data_precision、data_scale、nullable、および column_id の各列が SSMA によって変換されます。

ALL_TABLES システム ビュー

owner 列と table_name 列が SSMA for Oracle V4.0 によって変換されます。

ALL_CONSTRAINTS システム ビュー

owner、constraint_name、constraint_type、table_name、search_condition、r_owner、r_constraint_name、delete_rule、status、deferable、および generated の各列が SSMA によって変換されます。

ALL_SEQUENCES システム ビュー

sequence_owner、sequence_name、minvalue、increment_by、cycle_flag、order_flag、cache_size、および last_number の各列が SSMA によって変換されます。

ALL_VIEWS システム ビュー

owner、view_name、text_length、および text の各列が SSMA によって変換されます。

ALL_USERS システム ビュー

すべての列が SSMA によって変換されます。

ALL_SOURCE システム ビュー

owner、name、および text の各列が SSMA によって変換されます。

GLOBAL_NAME システム ビュー

すべての列が SSMA によって変換されます。

ALL_JOBS システム ビュー

job、last_date、last_sec、next_date、next_sec、total_time、broken、および what の各列が SSMA によって変換されます。

V$SESSION システム ビュー

sid、username、status、schemaname、program、logon_time、および last_call_et の各列が SSMA によって変換されます。

DBA_EXTENTS システム ビュー

DBA_EXTENTS は、SSMA で自動的に変換されません。owner、segment_name、segment_type、bytes、および blocks をエミュレートできます。

DBA_EXTENTS に似た結果を生成するコードを以下に示します。

insert #extentinfo

exec( '

dbcc extentinfo ( 0 ) with tableresults

' )

select

UPPER(s.name) AS owner,

UPPER(t.name) AS object_name,

'TABLE' AS segment_type,

ext_size*8192 as bytes,

ext_size as blocks

from #extentinfo AS e, sys.tables AS t, sys.schemas AS s

WHERE t.schema_id = s.schema_id

AND e.obj_id = t.object_id

UNION ALL

select

UPPER(s.name) AS owner,

UPPER(i.name) AS object_name,

'INDEX' AS segment_type,

ext_size*8192 as bytes,

ext_size as blocks

from #extentinfo AS e, sys.indexes AS i,

sys.tables AS t, sys.schemas AS s

WHERE t.schema_id = s.schema_id

AND i.object_id = t.object_id

AND e.obj_id = t.object_id

V$LOCKED_OBJECT システム ビュー

V$LOCKED_OBJECT は、SSMA で自動的に変換されません。V$LOCKED_OBJECT のデータをエミュレートするには、SQL Server 2008 の os_user_name、session_id、oracle_username、locked_mode の各列を使用します。

このエミュレーションを提供するビューを以下に示します。

CREATE VIEW ssma_oracle.V$LOCK_OBJECT AS

SELECT

s.hostname as OS_USER_NAME,

s.spid as SESSION_ID,

UPPER(u.name) as ORACLE_USERNAME,

CASE

WHEN d.request_mode = 'IX' THEN 3

WHEN d.request_mode = 'IS' THEN 2

WHEN d.request_mode = 'X' THEN 6

WHEN d.request_mode = 'S' THEN 4

ELSE 0

END as LOCKED_MODE

FROM sys.dm_tran_locks as d LEFT OUTER JOIN

(master..sysprocesses as s LEFT OUTER JOIN sysusers as u

ON s.uid = u.uid) ON d.request_session_id = s.spid

WHERE resource_type = 'OBJECT' and request_mode NOT IN ('Sch-M', 'Sch-S')

DBA_FREE_SPACE システム ビュー

DBA_FREE_SPACE は、SSMA で自動的に変換されません。SQL Server 2008 でこのビューをエミュレートするには、file_id、bytes、blocks の各列を使用します。

このエミュレーションを実行するコードを以下に示します。

CREATE VIEW DBA_FREE_SPACE AS

SELECT

a.data_space_id as FILE_ID,

SUM(a.total_pages - a.used_pages)*8192 as BYTES,

SUM(a.total_pages - a.used_pages) as BLOCKS

FROM sys.allocation_units as a

GROUP BY a.data_space_id

DBA_SEGMENTS システム ビュー

DBA_SEGMENTS ビューは、SSMA で自動的に変換されません。SQL Server 2008 でこのビューをエミュレートするには、owner、segment_name、segment_type、bytes の各列を使用します。

このエミュレーションの例を以下に示します。

CREATE VIEW ssma_ora.DBA_SEGMENTS AS

SELECT

UPPER(s.name) AS owner,

UPPER(o.name) AS SEGMENT_NAME,

'TABLE' AS SEGMENT_TYPE,

SUM(a.used_pages*8192) as BYTES

FROM sys.tables AS o INNER JOIN

sys.schemas AS s ON s.schema_id = o.schema_id left join

(sys.partitions as p join sys.allocation_units a on p.partition_id = a.container_id

left join sys.internal_tables it on p.object_id = it.object_id)

on o.object_id = p.object_id

WHERE (o.is_ms_shipped = 0)

GROUP BY s.name, o.name

UNION ALL

SELECT

UPPER(s.name) AS owner,

UPPER(i.name) AS SEGMENT_NAME,

'INDEX' AS OBJECT_TYPE,

SUM(a.used_pages*8192) as BYTES

FROM sys.indexes AS i INNER JOIN

sys.objects AS o ON i.object_id = o.object_id and

o.type = 'U' INNER JOIN

sys.schemas AS s ON o.schema_id = s.schema_id left join

(sys.partitions as p join sys.allocation_units a on p.partition_id = a.container_id

left join sys.internal_tables it on p.object_id = it.object_id)

on o.object_id = p.object_id

GROUP BY s.name, i.name

Oracle のシステム関数の変換

SSMA では、Oracle のシステム関数が SQL Server のシステム関数か Microsoft Extension Library for SQL Server のユーザー定義関数に変換されます。このライブラリは、SSMA 拡張パックをインストールすると sysdb データベースに作成されます。次の表に、Oracle のシステム関数と SQL Server のマッピングの一覧を示します。

関数の変換の状態 (S)

変換の種類 (T)

Y: 関数が完全に変換されます。

M: 標準の Transact-SQL のマッピングを使用します。

P: 関数が部分的に変換されます。

F: データベースのユーザー定義関数を使用します。

注: sysdb.ssma_oracle スキーマの関数には [ssma_oracle] というプレフィックスが付いています。このプレフィックスは、SSMA 拡張パックのインストールに含まれている SQL Server 関数に必要です。

Oracle のシステム関数

S

T

SQL Server への変換

コメント

ABS(p1)

Y

M

ABS(p1)

 

ACOS(p1)

Y

M

ACOS(p1)

 

ADD_MONTHS(p1, p2)

Y

M

DATEADD(m, p2, p1)

 

ASCII(p1)

Y

M

ASCII(p1)

 

ASIN(p1)

Y

M

ASIN(p1)

 

AVG(p1)

Y

M

AVG(p1)

ATAN(p1)

Y

M

ATAN(p1)

 

BITAND(p1, p2)

Y

F

ssma_oracle.BITAND(p1, p2)

 

CAST(p1 AS t1)

Y

M

CAST(p1 AS t1)

 

CEIL(p1)

Y

M

CEILING(p1)

 

CHR(p1 [USING NCHAR_CS])

P

M

CHAR(p1)

USING NCHAR_CS は現在サポートされていません。

COALESCE(p1, …)

Y

M

COALESCE(p1, …)

 

CONCAT(p1, p2)

Y

M

式 (p1 + p2)

COS(p1)

Y

M

COS(p1)

 

COSH(p1)

Y

F

ssma_oracle.COSH(p1) (ssma_ora ユーザー名にスペースは使用できません)

 

COUNT(p1)

Y

M

COUNT(p1)

CURRENT_DATE

P

M

SYSDATETIME()

制限: CURRENT_DATE で返されるのは DB セッションのタイム ゾーンの日付ですが、SYSDATETIME() で返されるのは SQL Server インスタンスのコンピュータの日付です。

DECODE(p1, p2, p3 [, p4])

Y

M

CASE p1 WHEN p2 THEN p3 [ELSE p4] END

 

DENSE_RANK()

Y

M

DENSE_RANK()

EXP(p1)

Y

M

EXP(p1)

 

EXTRACT(p1 FROM p2)

P

M

DATEPART(part-p1, p2)

p1 = (YEAR, MONTH, DAY, HOUR, MINUTE, SECOND) のみが変換されます。p1 = (TIMEZONE_HOUR, TIMEZONE_MINUTE, TIMEZONE_REGION, TIMEZONE_ABBR) の場合は、変換できないという内容のメッセージが生成されます。

FLOOR(p1)

Y

M

FLOOR(p1)

 

FROM_TZ(p1, p2)

Y

M

TODATETIMEOFFSET(p1, p2)

GREATEST(p1,p2

P

F

ssma_oracle.

関数の種類は p1 のデータ型に基づいて決定されます。Oracle ソースが

[,p3…pn])

GREATEST_DATETIME(p1, p2)

GREATEST(p1,p2,p3) の場合、SSMA による変換の結果は

 

GREATEST_FLOAT(p1, p2)

GREATEST(p1, GREATEST(p2,p3)) になります (引数がさらに増えた場合も同様です)。

 

GREATEST_INT(p1, p2)

 

 

GREATEST_NVARCHAR(p1, p2)

 

 

GREATEST_REAL(p1, p2)

 

 

GREATEST_VARCHAR(p1, p2)

 

INITCAP(p1)

Y

F

ssma_oracle.

関数の種類は p1 のデータ型に基づいて決定されます。現在サポートされている引数の型は、CHAR、NCHAR、VARCHAR2、NVARCHAR2 です。その他の型に対してはメッセージが生成されます。

INITCAP _VARCHAR(p1)

INITCAP _NVARCHAR(p1)

INSTR(p1,p2[,p3,p4])

P

F

ssma_oracle.

INSTRB、INSTRC、INSTR2、INSTR4 は、現時点では変換されません。

INSTR2_CHAR(p1, p2)

INSTR2_NCHAR(p1, p2)

INSTR2_NVARCHAR(p1, p2)

INSTR2_VARCHAR(p1, p2)

INSTR3_CHAR(p1, p2, p3)

INSTR3_NCHAR(p1, p2, p3)

INSTR3_NVARCHAR(p1, p2, p3)

INSTR3_VARCHAR(p1, p2, p3)

INSTR4_CHAR(p1, p2, p3, p4)

INSTR4_NCHAR(p1, p2, p3, p4)

INSTR4_NVARCHAR(p1, p2, p3, p4)

INSTR4_VARCHAR(p1, p2, p3, p4)

LAST_DAY(p1)

Y

F

ssma_oracle.LAST_DAY(p1)

 

LEAST(p1, p2 [, p3 … pn])

P

F

ssma_oracle.

関数の種類は p1 のデータ型に基づいて決定されます。Oracle ソースが

LEAST_DATETIME (p1, p2)

 LEAST (p1,p2,p3) の場合、SSMA による変換の結果は

LEAST_FLOAT (p1, p2)

LEAST (p1,  LEAST (p2,p3)) になります (引数がさらに増えた場合も同様です)。

LEAST_INT (p1, p2)

 

LEAST_NVARCHAR (p1, p2)

 

LEAST_REAL (p1, p2)

 

LEAST_VARCHAR (p1, p2)

 

LENGTH(p1)

P

F

ssma_oracle.

LENGTHB、LENGTHC、LENGTH2、LENGTH4 は、現時点では変換されません。

LENGTH_CHAR(p1)

関数の種類は p1 のデータ型に基づいて決定されます。

LENGTH_NCHAR(p1)

 

LENGTH_NVARCHAR(p1)

 

LENGTH_VARCHAR(p1)

 

LN(p1)

Y

M

LOG(p1)

 

LOCALTIMESTAMP

Y

M

SYSDATETIME()

LOG(p1, p2)

Y

F

ssma_oracle.LOG_ANYBASE(p1, p2)

 

LOWER(p1)

Y

M

LOWER(p1)

 

LPAD(p1, p2)

Y

F

ssma_oracle.

関数の種類は p1 のデータ型に基づいて決定されます。P3 = ' ' です (既定)。現在サポートされている引数の型は、CHAR、NCHAR、VARCHAR2、NVARCHAR2 です。その他の型に対してはメッセージが生成されます。

LPAD_VARCHAR(p1, p2, p3)

LPAD_NVARCHAR(p1, p2, p3)

LPAD(p1, p2, p3)

Y

F

ssma_oracle.

関数の種類は p1 のデータ型に基づいて決定されます。現在サポートされている引数の型は、CHAR、NCHAR、VARCHAR2、NVARCHAR2 です。

LPAD_VARCHAR(p1, p2, p3)

LPAD_NVARCHAR(p1,p2,p3)

LTRIM(p1)

Y

M

LTRIM(p1)

 

LTRIM(p1, p2)

Y

F

ssma_oracle.

関数の種類は p1 のデータ型に基づいて決定されます。現在サポートされている引数の型は、CHAR、NCHAR、VARCHAR2、NVARCHAR2 です。

LTRIM2_VARCHAR(p1, p2)

LTRIM2_NVARCHAR(p1, p2)

MOD(p1, p2)

Y

M

式 (p1 % p2)

パラメータのデータ型はチェックされません。

MONTHS_BETWEEN(p1, p2)

Y

M

DATEDIFF( MONTH, CAST(p2 AS float), CAST( DATEADD(DAY, ( -CAST(DATEPART(DAY, p2) AS float(53)) + 1 ), p1) AS float))

 

NEXT_DAY (p1, p2)

Y

F

ssma_oracle.NEXT_DAY (p1, p2)

 

NEW_TIME(p1, p2, p3)

Y

F

ssma_oracle.NEW_TIME(p1, p2, p3)

 

NLS_INITCAP(p1[, p2])

P

F

ssma_oracle.

現在サポートされているのは、引数が 1 つの呼び出しだけです。関数の種類は最初の引数のデータ型に基づいて決定されます。現在サポートされている最初の引数のデータ型は、NCHAR と NVARCHAR2 です。その他のデータ型に対してはメッセージが生成されます。

NLS_INITCAP_NVARCHAR(p1)

NTILE()

Y

M

NTILE()

NULLIF(p1, p2)

Y

M

NULLIF(p1, p2)

 

NVL(p1, p2)

Y

M

ISNULL(p1, p2)

 

POWER(p1,p2)

Y

M

POWER(p1,p2)

 

RANK()

Y

M

RANK()

RAWTOHEX (p1)

Y

F

ssma_oracle.RAWTOHEX_VARCHAR (p1)

戻り値の型としては varchar がサポートされています。

REPLACE(p1, p2)

REPLACE(p1, p2, p3)

P

M

REPLACE(p1, p2 , ‘’)

REPLACE(p1, p2 , p3)

ROUND(p1) [ p1 date ]

ROUND(p1, p2) [ p1 date ]

Y

F

ssma_oracle.ROUND_DATE (p1, NULL)

ssma_oracle.ROUND_DATE (p1, p2)

 

ROUND(p1) [ p1 numeric ]

Y

F

ssma_oracle.ROUND_NUMERIC_0 (p1)

 

ROUND (p1, p2) [ p1 numeric ]

Y

M

ROUND (p1, p2)

 

ROW_NUMBER()

Y

M

ROW_NUMBER()

RPAD(p1, p2)

Y

F

ssma_oracle.

関数の種類は最初の引数のデータ型に基づいて決定されます。P3 = ' ' です (既定)。現在サポートされている最初の引数のデータ型は、CHAR、NCHAR、VARCHAR2、NVARCHAR2 です。その他のデータ型に対してはメッセージが生成されます。

RPAD_VARCHAR(p1, p2, p3)

RPAD_NVARCHAR(p1, p2, p3)

RPAD(p1, p2, p3)

Y

F

ssma_oracle.

関数の種類は最初の引数のデータ型に基づいて決定されます。現在サポートされている最初の引数のデータ型は、CHAR、NCHAR、VARCHAR2、NVARCHAR2 です。その他のデータ型に対してはメッセージが生成されます。

RPAD_VARCHAR(p1, p2, p3)

RPAD_NVARCHAR(p1,p2,p3)

RTRIM(p1)

Y

M

RTRIM(p1)

 

RTRIM(p1,p2)

Y

F

ssma_oracle.

関数の種類は p1 のデータ型に基づいて決定されます。現在サポートされている引数の型は、CHAR、NCHAR、VARCHAR2、NVARCHAR2 です。

RTRIM2_VARCHAR(p1,p2)

RTRIM2_NVARCHAR(p1,p2)

SIGN(p1)

Y

M

SIGN(p1)

 

SIN(p1)

Y

M

SIN(p1)

 

SINH(p1)

Y

F

ssma_oracle.SINH(p1)

 

SQRT(p1)

Y

M

SQRT (p1)

 

SUBSTR(p1, p2[, p3])

P

F

ssma_oracle.

関数の種類は p1 のデータ型に基づいて決定されます。

SUBSTR2_CHAR(p1,p2)

SUBSTR2_NCHAR(p1,p2)

SUBSTR2_NVARCHAR(p1,p2)

SUBSTR2_VARCHAR(p1,p2)

SUBSTR3_CHAR(p1,p2,p3)

SUBSTR3_NCHAR(p1,p2,p3)

SUBSTR3_NVARCHAR(p1,p2,p3)

SUBSTR3_VARCHAR(p1,p2,p3)

SUM()

Y

M

SUM()

SYS_GUID()

P

M

NEWID()

正常な動作は保証されていません。たとえば、SELECT SYS_GUID() from dual は SELECT NEWID() とは異なります。

SYSDATE

Y

M

-SYSDATETIME()

SYSTIMESTAMP

Y

M

SYSDATETIMEOFFSET()

TAN(p1)

Y

M

TAN(p1)

 

TANH(p1)

Y

F

ssma_oracle.TANH(p1)

 

TO_CHAR(p1)

Y

M

CAST(p1 AS CHAR)

正常な動作は保証されていません。

TO_CHAR(p1, p2)

P

F

ssma_oracle.

p1 は、日付型または数値型を取ることができます。現在サポートされていない書式は、E、EE、TZD、TZH、TZR です。サポートされている数値の書式は、コンマ、ピリオド、'0'、'9'、および 'fm' です。

TO_CHAR_DATE (p1, p2)

p1 の文字値はサポートされていません。

TO_CHAR_NUMERIC (p1, p2)

 

TO_DATE(p1)

TO_DATE(p1, p2)

P

F

CAST(p1 AS datetime)

ssma_oracle.TO_DATE2 (p1, p2)

引数が 1 つか 2 つの形式のみが変換されます。

TO_NUMBER(p1[, p2[, p3]])

P

M

CAST(p1 AS NUMERIC)

現在サポートされているのは引数が 1 つの場合だけです。変換の完全な等価性は保証されていません。

TRANSLATE(p1, p2, p3)

Y

F

ssma_oracle.

関数の種類は最初の引数のデータ型に基づいて決定されます。現在サポートされている最初の引数のデータ型は、CHAR、NCHAR、VARCHAR2、NVARCHAR2 です。その他のデータ型に対してはメッセージが生成されます。

TRANSLATE_VARCHAR(p1, p2, p3)

TRANSLATE_NVARCHAR(p1, p2, p3)

TRUNC(p1[, p2])

Y

F

ssma_oracle.

現在サポートされているのは、p1 が NUMERIC 型または DATE 型の場合だけです。

TRUNC(p1[, p2])

TRUNC_DATE(p1)

TRUNC_DATE2(p1, p2)

TRIM

Y

F

ssma_oracle.TRIM2、ssma_oracle.TRIM3

パラメータが変換されます。

UID

P

M

SUSER_SID()

変換の完全な等価性は保証されていません。

UPPER(p1)

Y

M

UPPER(p1)

 

USER

Y

M

SESSION_USER

 

WIDTH_BUCKET(p1, p2, p3, p4)

Y

F

ssma_oracle.WIDTH_BUCKET(p1, p2, p3, p4)

 

Oracle のシステム パッケージの変換

ここでは、Oracle の標準パッケージに含まれている、よく使用されるサブルーチンの移行について説明します。SSMA で自動的に移行されるモジュールもあれば、手動で処理する必要があるモジュールもあります。変換の方法を示す例も紹介します。

DBMS_SQL パッケージ

次の場合は SSMA で自動的に処理されます。

· 動的 SQL を手動で処理する場合。

· ステートメントが SELECT ではない場合。

Oracle の関数またはプロシージャ

SQL Server への変換

コメント

OPEN_CURSOR()

[ssma_oracle].DBMS_SQL_OPEN_CURSOR

変換の完全な等価性は保証されていません。

PARSE(p1,p2,p3)

[ssma_oracle].DBMS_SQL_PARSE  p1,p2,p3

変換の完全な等価性は保証されていません。

EXECUTE(p1)

[ssma_oracle].DBMS_SQL_EXECUTE -p1

変換の完全な等価性は保証されていません。

CLOSE_CURSOR(p1)

[ssma_oracle].DBMS_SQL_CLOSE_CURSOR -p1

変換の完全な等価性は保証されていません。

例:

Oracle

declare

cur int;

ret int;

begin

cur := dbms_sql.open_cursor();

dbms_sql.parse(cur, ' select col1 from t1', dbms_sql.NATIVE);

ret := dbms_sql.execute(cur);

dbms_sql.close_cursor(cur);

end;

SQL Server

Declare

@cur numeric(38),

@ret numeric(38)

begin

EXECUTE sysdb.ssma_oracle.dbms_sql_open_cursor @result = @cur OUTPUT

EXECUTE sysdb.ssma_oracle.dbms_sql_parse @cur, 'SELECT t1.col1 FROM dbo.t1'

DECLARE @temp nvarchar(4000)

SET @temp = db_name()

EXECUTE sysdb.ssma_oracle.dbms_sql_execute @cur, @temp, @ssma$rows_processed = @ret OUTPUT

EXECUTE sysdb.ssma_oracle.dbms_sql_close_cursor @cur

end

DBMS_OUTPUT パッケージ

よく使用される PUT_LINE 関数を SSMA で処理できます。

Oracle の関数またはプロシージャ

T

SQL Server への変換

コメント

PUT_LINE(p1)

M

PRINT p1

変換の完全な等価性は保証されていません。

例:

Oracle

declare

tname varchar2(255);

begin

tname:='Hello, world!';

dbms_output.put_line(tname);

end;

SQL Server

DECLARE

@tname varchar(255)

BEGIN

SET @tname = 'Hello, world!'

PRINT @tname

END

UTL_FILE パッケージ

SSMA で自動的に処理される UTL_FILE のサブプログラムを次の表に示します。

Oracle の関数またはプロシージャ

T

SQL Server への変換

コメント

IS_OPEN(p1)

S

UTL_FILE_IS_OPEN(p1)

 

FCLOSE(p1)

S

UTL_FILE_FCLOSE p1

 

FFLUSH (p1)

S

UTL_FILE_FFLUSH p1

 

FOPEN ( p1,p2,p3, p4)

S

UTL_FILE_FOPEN$IMPL(p1,p2,p3,p4,p5)

p5 は戻り値です。

GET_LINE

S

UTL_FILE_GET_LINE(p1,p2,p3)

p2 は戻り値です。

PUT

S

UTL_FILE_PUT(p1,p2)

 

PUTF(p1, p2)

S

UTL_FILE_PUTF(p1,p2)

 

PUT_LINE

S

UTL_FILE_PUT_LINE(p1,p2)

 

例:

Oracle

DECLARE

outfile utl_file.file_type;

my_world varchar2(4) := 'Zork';

V1 VARCHAR2(32767);

Begin

outfile := utl_file.fopen('USER_DIR','1.txt','w',1280);

utl_file.put_line(outfile,'Hello, world!');

utl_file.PUT(outfile, 'Hello, world NEW! ');

UTL_FILE.FFLUSH (outfile);

IF utl_file.is_open(outfile) THEN

Utl_file.fclose(outfile);

END IF;

outfile := utl_file.fopen('USER_DIR','1.txt','r');

UTL_FILE.GET_LINE(outfile,V1,32767);

DBMS_OUTPUT.put_line('V1= '||V1);

IF utl_file.is_open(outfile) THEN

Utl_file.fclose(outfile);

END IF;

End write_log_file;

SQL Server

DECLARE

@outfile XML,

@my_world varchar(4),

@V1 varchar(max)

SET @my_world = 'Zork'

BEGIN

EXEC sysdb.ssma_oracle.UTL_FILE_FOPEN$IMPL 'USER_DIR', '1.txt', 'w', 1280, @outfile OUTPUT

EXEC sysdb.ssma_oracle.UTL_FILE_PUT_LINE @outfile, 'Hello, world!'

EXEC sysdb.ssma_oracle.UTL_FILE_PUT @outfile, 'Hello, world NEW! '

EXEC sysdb.ssma_oracle.UTL_FILE_FFLUSH @outfile

IF (sysdb.ssma_oracle.UTL_FILE_IS_OPEN(@outfile) != /* FALSE */ 0)

EXEC sysdb.ssma_oracle.UTL_FILE_FCLOSE @outfile

EXEC sysdb.ssma_oracle.UTL_FILE_FOPEN$IMPL 'USER_DIR', '1.txt', 'r', 1024, @outfile OUTPUT

EXEC sysdb.ssma_oracle.UTL_FILE_GET_LINE @outfile, @V1 OUTPUT, 32767

PRINT ('V1= ' + isnull(@V1, ''))

IF (sysdb.ssma_oracle.UTL_FILE_IS_OPEN(@outfile) != /* FALSE */ 0)

EXEC sysdb.ssma_oracle.UTL_FILE_FCLOSE @outfile

END

DBMS_UTILITY パッケージ

SSMA でサポートされているのは GET_TIME 関数だけです。

Oracle の関数またはプロシージャ

T

SQL Server への変換

コメント

GET_TIME

M

SELECT CONVERT(NUMERIC(38, 0), (CONVERT(NUMERIC(38, 10), getdate()) * 8640000))

 

DBMS_SESSION パッケージ

SSMA でサポートされているのは UNIQUE_SESSION_ID 関数だけです。

Oracle の関数またはプロシージャ

T

SQL Server への変換

コメント

UNIQUE_SESSION_ID

M

[sysdb].ssma_oracle.unique_session_id()

戻り値は異なります。

DBMS_PIPE パッケージ

DBMS_PIPE システム パッケージは、SSMA for Oracle V4.0 では変換されません。ここでは、手動でエミュレートするためのヒントを紹介します。

DBMS_PIPE パッケージには以下のサブプログラムがあります。

· 関数 Create_Pipe()

· プロシージャ Pack_Message()

· 関数 Send_Message()

· 関数 Receive_Message()

· 関数 Next_Item_Type()

· プロシージャ Unpck_Message()

· プロシージャ Remove_Pipe()

· プロシージャ Purge()

· プロシージャ Reset_Buffer()

· 関数 Unique_Session_Name()

パイプで転送されるデータを別のテーブルに格納します。

次に例を示します。

Use sysdb

Go

Create Table sysdb.ssma.Pipes(

ID Bigint Not null Identity(1, 1),

PipeName Varchar(128) Not Null Default 'Default',

DataValue Varchar(8000)

);

go

Grant Select, Insert, Delete On sysdb.ssma.Pipes to public

Go

pack-send コマンドと receive-unpack コマンドは、通常はペアで使用されます。したがって、次のように置き換えることができます。

Oracle

s := dbms_pipe.receive_message('');

if s = 0 then

dbms_pipe.unpack_message(chr);

end if;

SQL Server

DECLARE

@s bigint,

@chr varchar(8000)

BEGIN

SET @chr = ''

Select @s = Min(ID) from sysdb.ssma.Pipes where PipeName = ''

If @s is not null

Begin

Select @chr = DataValue From sysdb.ssma.Pipes where ID = @s

Delete From sysdb.ssma.Pipes where ID = @s

End

END

Oracle

dbms_pipe.pack_message(info);

status := dbms_pipe.send_message('');

SQL Server

INSERT INTO sysdb.ssma.Pipes (PipeName, DataValue) Values ('', @info)

このパッケージ変換の考慮事項を以下に示します。

· Create_Pipe(): 無視できます。

· Pack_Message()、Unpack_Message(): バッファとして記憶域を追加するか、無視します。

· Send_Message()、Receive_Message(): Pipes テーブルに対する insert/select としてエミュレートします (前のコード例を参照)。

· Next_Item_Type(): Pipes テーブルに datatype フィールドを追加する必要があります。

· Remove_Pipe(): Delete From Pipes where PipeName = '' としてエミュレートします。

· Purge(): このエミュレーションでは Remove_Pipe() と同義です。

· Reset_Buffer(): バッファ (および pack/unpack プロシージャ) をエミュレートする場合は必要です。

· Unique_Session_Name(): セッション名を返します。SessionID としてエミュレートできます。

DBMS_LOB パッケージ

SSMA では、DBMS_LOB パッケージの一部の関数を自動的に変換できます。それらの関数は、SSMA 拡張パックのプロシージャと関数によってエミュレートされます。

SSMA で自動的に処理される DBMS_LOB のサブプログラムを次の表に示します。

Oracle の関数またはプロシージャ

T

SQL Server への変換

コメント

DBMS_LOB.READ

S

ssma_oracle.dbms_lob$read_blob

ssma_oracle.dbms_lob$read_clob

 

DBMS_LOB.WRITE

S

ssma_oracle.dbms_lob$write_blob

ssma_oracle.dbms_lob$write_clob

 

DBMS_LOB.WRITEAPPEND

S

ssma_oracle.dbms_lob$writeappend blob

ssma_oracle.dbms_lob$writeappend clob

 

DBMS_LOB.GETLENGTH

S

ssma_oracle.dbms_lob$getlength_blob

ssma_oracle.dbms_lob$getlength_clob

-

DBMS_LOB.SUBSTR

S

ssma_oracle.dbms_lob$substr_blob

ssma_oracle.dbms_lob$substr_clob

-

DBMS_LOB.OPEN

S

このプロシージャは変換時に無視されます。

 

DBMS_LOB.CLOSE

S

このプロシージャは変換時に無視されます。

 

DBMS_JOB システム パッケージ

ジョブは、Oracle と SQL Server の両方でサポートされていますが、作成および実行の方法はまったく異なります。DBMS_JOB パッケージの変換は SSMA でサポートされていないため、ここでは手動の変換について説明します。ここで紹介する例は、Oracle のジョブに対応するものを SQL Server で作成する方法を示しています。以下は、ここで取り上げるサブルーチンです。

ジョブ キューへのジョブの送信:

DBMS_JOB.SUBMIT (

OUT binary_integer,

IN varchar2,

IN date DEFAULT defaultsysdate,

IN varchar2 DEFAULT 'NULL',

IN boolean DEFAULT false,

IN DEFAULTany_instance,

IN boolean DEFAULT false);

キューのジョブの削除:

DBMS_JOB.REMOVE ( IN binary_integer);

パラメータの内容は次のとおりです。

· は、作成されたジョブの ID です。通常はプログラムによって保存され、後でそのジョブを (REMOVE ステートメントで) 参照するために使用されます。

· は、ジョブ プロセスによって実行されるコマンドを表す文字列です。Oracle では、このパラメータを BEGIN…END ブロックに挿入してコマンドを実行します (BEGIN END)。

· は、ジョブの初回の実行がスケジュールされる日時です。

· は、ジョブの実行時に評価される DATE 型の式を含む文字列です。式の値は、次回の実行の日付 + 時間です。

パラメータと パラメータは、Oracle のクラスタリング機構に関連するものなので、ここでは無視します。Oracle でコマンドが解析される時期を制御する パラメータも、ここでは変換しません。

注    と の動的 SQL 文字列は別に変換します。このコードで参照するすべてのオブジェクト名に [database].[owner] という修飾子を追加することが重要です。これが必要になるのは、ジョブの実行時にはデータベースの既定値を使用できないためです。

SUBMIT と REMOVE の 2 つのルーチンを、DBMS_JOB_SUBMIT と DBMS_JOB_REMOVE という新しいストアド プロシージャにそれぞれ変換します。また、実行時の評価の実装と次回の実行のスケジュールのために _JOB_WRAPPER という新しい特殊なラッパー プロシージャを作成します。

Oracle と SQL Server では、ジョブの識別方法が異なります。ジョブは、Oracle では 2 進整数の連番 (job_id) で識別されますが、SQL Server では uniqueidentifier の job_id と一意のジョブ名で識別されます。

このエミュレーション方法では、SQL Server のストアド プロシージャを 3 つ作成します。以降では、それらのストアド プロシージャについて説明します。

DBMS_JOB_SUBMIT プロシージャ

この SQL Server プロシージャは、ジョブを作成し、初回の実行をスケジュールします。このプロシージャの全文は、このセクションの後の方で示してあります。

SQL Server でジョブを送信するには、次の手順を実行します。

1. sp_add_job を使用して、ジョブを作成してその ID を取得します。

2. sp_add_jobstep を使用して、ジョブに実行ステップを追加します (ここでは 1 つのステップを使用します)。

3. sp_add_jobserver を使用して、ジョブをローカル サーバーに関連付けます。

4. sp_add_jobschedule を使用して、初回の実行をスケジュールします (特定の時刻に 1 回だけ実行されるようにします)。

Oracle のジョブ情報を保存するには、Oracle の を Transact-SQL の job_name パラメータに格納し、 のコマンドをジョブの説明として格納します。ジョブの説明は nvarchar(512) なので、Unicode 文字 512 文字より長いコマンドは変換できません。MS SQL の識別子は、sp_add_job の実行時に job_id として自動的に生成されます。

DBMS_JOB_REMOVE プロシージャ

このプロシージャは、指定された Oracle のジョブ番号を使用して SQL Server のジョブ ID を見つけ、sp_delete_job を使用してそのジョブとすべての関連情報を削除します。

JOB_WRAPPER プロシージャ

このプロシージャは、ジョブ コマンドを実行し、 パラメータに従って次回の実行が設定されるようにジョブのスケジュールを変更します。

DBMS_JOB.SUBMIT

SUBMIT プロシージャの呼び出しを次の SQL Server コードに変換します。

EXEC DBMS_JOB_SUBMIT

OUTPUT,

,

,

,

パラメータの内容は次のとおりです。

·  は、Oracle 形式のジョブ番号です。ソース プログラムに宣言が含まれている必要があります。

·  は、個別に SQL Server に変換される、ソースの パラメータのコマンド (動的 SQL ステートメント) です。変換後のコードに複数のステートメントが含まれる場合は、セミコロン (;) で区切ります。 は現在のコンテキストの外で (_JOB_WRAPPER プロシージャ内で非同期に) 実行されるため、生成されたすべての宣言をこの文字列に含めます。

· は、初回のスケジュール実行の日付です。通常の日付式として変換します。

· は、動的 SQL 式を含む文字列です。ジョブが実行されるたびにこの式が評価されて、次回の実行の日時が取得されます。 と同様に、対応する SQL Server の式に変換します。

· は、Oracle の形式には存在しないパラメータです。このパラメータは、変更されていない元の パラメータです。参照用に保存します。

変換後のステートメントには、、、 の各パラメータは含まれず、代わりに という新しいアイテムが含まれています。

DBMS_JOB.REMOVE

REMOVE プロシージャの呼び出しを次のコードに変換します。

EXEC DBMS_JOB_REMOVE

は、削除するジョブの Oracle 形式の番号です。ソース プログラムに宣言が含まれている必要があります。

Oracle ジョブの変換の例

このセクションには、2 つのステップから成るジョブの変換の例と、ジョブが参照する新しい sysdb プロシージャのソースが含まれています。

ステップ 1: ジョブを送信する

Oracle PL/SQL

· ジョブで変更するテーブル:

create table ticks (d date);

· 各ステップで実行されるプロシージャ:

create or replace procedure ticker (curr_date date) asbegin insert into ticks values (curr_date); commit;end;

· ジョブの送信:

declare j number; sInterval varchar2(50);begin sInterval := 'sysdate + 1/8640'; -- 10 sec dbms_job.submit(job => j, what => 'ticker(sysdate);', next_date => sysdate + 1/8640, -- 10 sec interval => sInterval); dbms_output.put_line('job no = ' || j);end;

SQL Server

この例では、AUS というデータベースの sa ユーザーがコマンドを実行します。

USE AUS

GO

· ジョブで変更するテーブル:

CREATE TABLE ticks (d datetime)

GO

· 各ステップで実行されるプロシージャ:

CREATE PROCEDURE ticker (@curr_date datetime) AS

BEGIN

INSERT INTO ticks VALUES (@curr_date);

END;

GO

· ジョブの送信:

declare @j float(53),

@sInterval varchar(50)

begin

set @sInterval = 'getdate() + 1./8640'

/* パラメータの計算は、通常は自動的に生成されます */

declare @param_expr_0 datetime

set @param_expr_0 = getdate() + 1./8640 -- 10 sec

/* AUS.DBO.ticker になっていることに注意してください */

exec DBMS_JOB_SUBMIT

@j OUTPUT,

N'DECLARE @param_expr_1 DATETIME; SET @param_expr_1 = getdate(); EXEC AUS.DBO.TICKER @param_expr_1',

@param_expr_0,

@sInterval,

N'ticker(sysdate);'/* 元のコマンドを保存するパラメータ */

print 'job no = ' + cast (@j as varchar)

end

go

ステップ 2: ジョブを見つけて削除する

ここでは、SSMA for Oracle V4.0 によって生成される Oracle USER_JOBS システム ビューのエミュレーションを使用しています。

Oracle

declare j number;begin SELECT job INTO j FROM user_jobs WHERE (what = 'ticker(sysdate);'); dbms_output.put_line(j); dbms_job.remove(j);end;

SQL Server

declare @j float(53);

begin

SELECT @j = job

FROM USER_JOBS

WHERE (what = 'ticker(sysdate);'); -- ここに Oracle の式が残っています

print @j

exec DBMS_JOB_REMOVE @j

end

新しい sysdb プロシージャのソース

------------------------ 送信 -------------------

create procedure DBMS_JOB_SUBMIT (

@p_job_id int OUTPUT, -- Oracle のジョブ ID

@p_what nvarchar(4000), -- SQL Server に変換されたコマンド

@p_next_date datetime, -- 初回の実行の日時

@p_interval nvarchar(4000),-- SQL Server に変換された期間式

@p_what_ora nvarchar(512) -- 元の Oracle コマンド

) as

begin

declare @v_name nvarchar(512),

@v_job_ora int,

@v_job_ms uniqueidentifier,

@v_command nvarchar(4000),

@v_buf varchar(40),

@v_nextdate int,

@v_nexttime int

-- 1. 新しいジョブを作成する

select @v_job_ora =

max(

case isnumeric(substring(name,6,100))

when 1 then cast(substring(name,6,100) as int)

else 0

end

)

from msdb..sysjobs

where substring(name,1,5)='_JOB_'

set @v_job_ora = isnull(@v_job_ora,0) + 1

set @v_name = '_JOB_' + cast(@v_job_ora as varchar(12))

exec msdb..sp_add_job

@job_name = @v_name,

@description = @p_what_ora, -- saving non-converted Oracle command for reference

@job_id = @v_job_ms OUTPUT

-- 2.