概要
本記事の位置付けについて
Oracle Database から Azure SQL Database へ SQL Server Migration Assistant for Oracle (SSMA)によるプログラム移行検証結果の一部である。次の記事にて個別機能別記事へのリンクを整理している。
例外処理 について
Oracle Database ドキュメントにて、次のように記載されている。
PL/SQLランタイム・エラーの処理
事前定義の例外が次のドキュメントにて整理されている。すべての例外を取得する方法として、OTHERS 例外ハンドラを利用する方法もある。
参考リンク
- ホワイトペーパー
- Guide to Migrating from Oracle to SQL Server 2014 and Azure SQL Database
Azure SQL Database への移行
SSMA による変換
Oracle Database の 例外機能のほぼすべてをエミュレーションすることが可能である。
詳細については、次のホワイトペーパーに記載されている。
- Guide to Migrating from Oracle to SQL Server 2014 and Azure SQL Database
移行方針
エラー出力など一部の機能が Oracle Database の仕様とは異なるプログラムに変換される場合があるため、検証を行いながら移行する必要がある。
変換例
変換例 1 EXCEPTION 句の利用
Oracle Database のコード
DECLARE
id NUMBER(3,0);
BEGIN
SELECT
EMP_ID
INTO id
FROM (
SELECT 1 AS EMP_ID FROM DUAL
UNION ALL
SELECT 2 AS EMP_ID FROM DUAL
)
;
EXCEPTION
WHEN too_many_rows THEN
dbms_output.put_line('行が多すぎます。');
END;
Azure SQL Database への変換
SSMA により次のように変換される。
BEGIN
DECLARE
@ID numeric(3, 0)
BEGIN TRY
SELECT @ID = fci.EMP_ID
FROM
(
SELECT 1 AS EMP_ID
UNION ALL
SELECT 2 AS EMP_ID
) AS fci
END TRY
BEGIN CATCH
DECLARE
@errornumber int
SET @errornumber = ERROR_NUMBER()
DECLARE
@errormessage nvarchar(4000)
SET @errormessage = ERROR_MESSAGE()
DECLARE
@exceptionidentifier nvarchar(4000)
SELECT @exceptionidentifier = ssma_oracle.db_error_get_oracle_exception_id(@errormessage, @errornumber)
IF (@exceptionidentifier LIKE N'ORA-01422' + '%')
PRINT '行が多すぎます。'
ELSE
THROW
END CATCH
END
GO
変換例 2 raise_application_error
の利用
Oracle Database のコード
DECLARE
emp_id NUMBER(3,0);
BEGIN
emp_id := 999;
IF emp_id > 200 THEN
raise_application_error(-20001, 'emp_id の指定値に誤りがあります');
END IF;
END;
Azure SQL Database への変換
SSMA により次のように変換される。
BEGIN
DECLARE
@EMP_ID numeric(3, 0)
SET @EMP_ID = 999
IF @EMP_ID > 200
BEGIN
DECLARE
@db_raise_application_error_message nvarchar(4000)
SET @db_raise_application_error_message = N'ORA' + CAST(-20001 AS nvarchar) + N': ' + N'emp_id の指定値に誤りがあります'
;
THROW 59998, @db_raise_application_error_message, 1
END
END
GO
変換例 3 sqlcode
とsqlerrm
の利用
Oracle Database のコード
DECLARE
id NUMBER(3,0);
BEGIN
id := 1234;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(sqlcode);
dbms_output.put_line(sqlerrm);
END;
Azure SQL Database への変換
SSMA により次のように変換されるが、Oracle Database の同等の動作とならない。
BEGIN
DECLARE
@ID numeric(3, 0)
BEGIN TRY
SET @ID = 1234
END TRY
BEGIN CATCH
DECLARE
@errornumber int
SET @errornumber = ERROR_NUMBER()
DECLARE
@errormessage nvarchar(4000)
SET @errormessage = ERROR_MESSAGE()
DECLARE
@exceptionidentifier nvarchar(4000)
SELECT @exceptionidentifier = ssma_oracle.db_error_get_oracle_exception_id(@errormessage, @errornumber)
BEGIN
PRINT ssma_oracle.db_error_sqlcode(@exceptionidentifier, @errornumber)
PRINT ssma_oracle.db_error_sqlerrm_0(@exceptionidentifier, @errornumber)
END
END CATCH
END
GO
変換例 4 ユーザー定義例外の利用
Oracle Database のコード
DECLARE
test_excep EXCEPTION;
BEGIN
RAISE test_excep;
EXCEPTION
WHEN test_excep THEN
dbms_output.put_line('ユーザー定義例外が発生');
END;
Azure SQL Database への変換
次のように変換される。
BEGIN
DECLARE
@TEST_EXCEP$exception nvarchar(1000)
BEGIN TRY
SET @TEST_EXCEP$exception = N'local:oracle:{HR|00000001#Statement}:000:TEST_EXCEP'
DECLARE
@temp nvarchar(4000)
SET @temp = N'SSMA Oracle exception emulation for [' + @TEST_EXCEP$exception + ']'
;
THROW 59999, @temp, 1
END TRY
BEGIN CATCH
DECLARE
@errornumber int
SET @errornumber = ERROR_NUMBER()
DECLARE
@errormessage nvarchar(4000)
SET @errormessage = ERROR_MESSAGE()
DECLARE
@exceptionidentifier nvarchar(4000)
SELECT @exceptionidentifier = ssma_oracle.db_error_get_oracle_exception_id(@errormessage, @errornumber)
IF (@exceptionidentifier LIKE @TEST_EXCEP$exception + '%')
PRINT 'ユーザー定義例外が発生'
ELSE
THROW
END CATCH
END
GO