Click here to load reader
Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
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.