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 では、変数と定数を定義できる。定数について、Oracle Database ドキュメントにて、次のように記載されている。

> 変更されない値を保持します。

引用元：[13.14 定数の宣言 (oracle.com)](https://docs.oracle.com/cd/F19136_01/lnpls/constant-declaration.html)

%TYPE 属性や%ROWTYPE 属性を指定することで、定義済みのデータ型などを再利用することができる。

> %ROWTYPE属性を使用すると、データベースの表またはビュー内の行の全体または一部を表すレコードを宣言できます。

引用元：[1.2.8.3 %ROWTYPE属性の使用 (oracle.com)](https://docs.oracle.com/cd/F19136_01/lnpls/overview.html#GUID-C945E7E2-DDF6-4EC0-95FB-BFE1C2C66708)

> %TYPE属性を使用すると、事前に宣言されている変数または列と同じデータ型のデータ項目を(データ型を知らなくても)宣言できます。

引用元：[1.2.8.4 %TYPE属性の使用 (oracle.com)](https://docs.oracle.com/cd/F19136_01/lnpls/overview.html#GUID-1A95AA8C-9BA2-4018-B82B-535D25E24EBF)

### 参考リンク

特になし。

## Azure SQL Database への移行

### SSMA による変換

Azure SQL ファミリーでは、定数をサポートしていないため、変数に変換される。%TYPE 属性と%ROWTYPE 属性に相当する機能がないため、参照元のデータ型などを静的なコードに変換される。

### 移行方針

特になし。

### 変換例

#### 変換例 1 変数

##### Oracle Database のコード

```sql
DECLARE 
    var NUMBER(10,0) :=10;
BEGIN
    var := 100;
    DBMS_OUTPUT.PUT_LINE(var);
END;
```

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

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

```sql
BEGIN

   DECLARE
      @VAR numeric(10, 0) = 10

   SET @VAR = 100

   PRINT @VAR

END
GO
```

#### 変換例 2 定数

##### Oracle Database のコード

```sql
DECLARE
    CONST_NUM CONSTANT NUMBER(10,0) := 12;
BEGIN
    DBMS_OUTPUT.PUT_LINE(CONST_NUM);
END;
```

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

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

```sql
BEGIN

   DECLARE
      @CONST_NUM numeric(10, 0) = 12

   PRINT @CONST_NUM

END
GO
```

#### 変換例 3 %TYPE 属性

##### Oracle Database のコード

```sql
DECLARE
    var HR.departments.manager_id%TYPE;
BEGIN
    select manager_id INTO var from HR.departments WHERE department_id = 90;
    DBMS_OUTPUT.PUT_LINE(var);
END;
```

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

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

```sql
BEGIN

   DECLARE
      @VAR numeric(6, 0)

   SELECT @VAR = DEPARTMENTS.MANAGER_ID
   FROM HR.DEPARTMENTS
   WHERE DEPARTMENTS.DEPARTMENT_ID = 90

   PRINT @VAR

END
GO
```

#### 変換例 4 %ROWTYPE 属性

##### Oracle Database のコード

```sql
DECLARE 
    d_row HR.departments%ROWTYPE;
BEGIN
    SELECT * INTO d_row FROM HR.departments WHERE department_id = 90;
    DBMS_OUTPUT.PUT_LINE(d_row.MANAGER_ID);
END;
```

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

SSMA のプロジェクト設定値である`Convert record as a list of separates variables`が`YES`の場合に、SSMA により次のように変換される。

```sql
BEGIN

   DECLARE
      @D_ROW$DEPARTMENT_ID numeric(4, 0), 
      @D_ROW$DEPARTMENT_NAME varchar(30), 
      @D_ROW$MANAGER_ID numeric(6, 0), 
      @D_ROW$LOCATION_ID numeric(4, 0)

   SELECT @D_ROW$DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID, @D_ROW$DEPARTMENT_NAME = DEPARTMENTS.DEPARTMENT_NAME, @D_ROW$MANAGER_ID = DEPARTMENTS.MANAGER_ID, @D_ROW$LOCATION_ID = DEPARTMENTS.LOCATION_ID
   FROM HR.DEPARTMENTS
   WHERE DEPARTMENTS.DEPARTMENT_ID = 90

   PRINT @D_ROW$MANAGER_ID

END
GO
```