SQL Server Migration Assistant for Oracle  による Oracle Database から Azure SQL Database への移行検証～ Oracle 制御文編～


## 概要

### 本記事の位置付けについて

Oracle Database から Azure SQL Database へ SQL Server Migration Assistant for Oracle （SSMA）によるプログラム移行検証結果の一部である。次の記事にて個別機能別記事へのリンクを整理している。

- [SQL Server Migration Assistant for Oracle による Oracle Database から Azure SQL Database への移行検証記事のまとめ - Qiita](https://qiita.com/manabian/items/0ec96b66033a7bd03a25)


### 制御文 について

Oracle Database ドキュメントである[4 PL/SQLの制御文 (oracle.com)](https://docs.oracle.com/cd/F19136_01/lnpls/plsql-control-statements.html#GUID-18777904-23F6-4F6D-8B41-46BABF00BA03)にて、次の制御文がサポートされている旨の記述がある。

- 条件付き選択文
    - IF 文
    - CASE 文
- ループ文
    - LOOP 文
    - WHILE 文
- 順次制御文
    - GOTO 文
    - NULL 文


### 参考リンク

- ホワイトペーパー
    - Guide to Migrating from Oracle to SQL Server 2014 and Azure SQL Database

## Azure SQL Database への移行

### SSMA による変換

Oracle Database における制御処理の変換を基本的にサポートしている。

### 移行方針

特になし。

### 変換例

#### 変換例 1 IF 文

##### Oracle Database のコード

```sql
DECLARE 
    var NUMBER :=10;
BEGIN
    IF var = 10 THEN
        DBMS_OUTPUT.put_line('10 だよ');
    ELSE
        DBMS_OUTPUT.put_line('10じゃない');
    END IF;
END;  
```

##### Azure SQL Database への変換

SSMA により次のように変換される。

```sql
BEGIN

   DECLARE
      /*
      *   SSMA warning messages:
      *   O2SS0356: Conversion from NUMBER datatype can cause data loss.
      */

      @VAR float(53) = 10

   IF @VAR = 10
      PRINT '10 だよ'
   ELSE 
      PRINT '10じゃない'

END
GO
```

#### 変換例 2 CASE 文

##### Oracle Database のコード

```sql
DECLARE 
    var NUMBER :=10;
BEGIN
    CASE var
        WHEN 10 THEN 
            DBMS_OUTPUT.put_line('10 だよ');
        ELSE
            DBMS_OUTPUT.put_line('10じゃない');
    END CASE;
END;
```

##### Azure SQL Database への変換

SSMA により次のように変換される。

```sql
BEGIN

   DECLARE
      /*
      *   SSMA warning messages:
      *   O2SS0356: Conversion from NUMBER datatype can cause data loss.
      */

      @VAR float(53) = 10

   IF @VAR = 10
      PRINT '10 だよ'
   ELSE 
      PRINT '10じゃない'

END
GO
```

#### 変換例 3 LOOP 文

##### Oracle Database のコード

```sql
BEGIN
  FOR r IN 1..3 LOOP
    DBMS_OUTPUT.PUT_LINE(r);
  END LOOP;
  LOOP
    DBMS_OUTPUT.PUT_LINE('OK');
    EXIT;
  END LOOP;
END;
```

##### Azure SQL Database への変換

SSMA により次のように変換される。

```sql
BEGIN

   DECLARE
      @R int

   SET @R = 1

   WHILE @R <= 3
   
      BEGIN

         PRINT @R

         SET @R = @R + 1

      END

   WHILE 1 = 1
   
      BEGIN

         PRINT 'OK'

         BREAK

      END

END
GO
```

#### 変換例 4 WHILE 文

##### Oracle Database のコード

```sql
DECLARE
    r int;
BEGIN
    r := 0;
    WHILE (r<=5) LOOP
        DBMS_OUTPUT.PUT_LINE(r);
        r := r + 1;
    END LOOP;
END;
```

##### Azure SQL Database への変換

SSMA により次のように変換される。

```sql
BEGIN

   DECLARE
      @R int

   SET @R = 0

   WHILE (@R <= 5)
   
      BEGIN

         PRINT @R

         SET @R = @R + 1

      END

END
GO
```

#### 変換例 5 GOTO 文

##### Oracle Database のコード

```sql
BEGIN
  GOTO label;
    DBMS_OUTPUT.PUT_LINE('処理1');
    DBMS_OUTPUT.PUT_LINE('処理2');
    <<label>>
    DBMS_OUTPUT.PUT_LINE('ラベル処理');
END;
```

##### Azure SQL Database への変換

SSMA により次のように変換される。

```sql
BEGIN

   GOTO LABEL

   PRINT '処理1'

   PRINT '処理2'

   LABEL:

   PRINT 'ラベル処理'

END
GO
```

#### 変換例 6 NULL 文

##### Oracle Database のコード

```sql
DECLARE
  var VARCHAR2(2) := 'OK';
BEGIN
  IF var = 'OK'
    THEN
      DBMS_OUTPUT.PUT_LINE('OK');
    ELSE
      NULL;
  END IF;
END;
```

##### Azure SQL Database への変換

SSMA により次のように変換される。

```sql
BEGIN

   DECLARE
      @VAR varchar(2) = 'OK'

   IF @VAR = 'OK'
      PRINT 'OK'
   ELSE 
      DECLARE
         @db_null_statement int

END
GO
```