(QA)IBM i QUERY/400定義をSQL文に変換したい

主題の質問をいただきまして。
こんなコマンドがあるとは知らなんだー、ありがとうMさん♪

## QUERY/400定義　*QRYDFN をSQL文に変換出力するコマンド RTVQMQRY

参考URL: 
[Converting Query/400 Queries to SQL](https://www.ibm.com/support/pages/converting-query400-queries-sql)
[RTVQMQRY (QUERY 管理機能プログラム検索) コマンド](https://www.ibm.com/docs/ja/i/7.4?topic=ssw_ibm_i_74/cl/rtvqmqry.html) ※IBM i 7.5版は執筆時点で英語のため7.4リンクです

### RTVQMQRY概要
QUERY/400定義 *QRYDFN または QUERY管理機能プログラム *QMQRY 読取り、SQL文に変換して出力ファイルに書き込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/9b871749-2a27-d392-b2ac-ad69262be6ec.png)
※作成する出力ファイルの桁数はSRCPFデフォルトの92としています。

## RTVQMQRYコマンド使用例① (かんたんな*QRYDFNからSQL文を生成)

事前にSQL出力ファイル（例ではQSQLSRC）を作成します。

CRTSRCPF FILE(DEMOLIB/QSQLSRC) IGCDTA(*YES) 
```
CRTSRCPF FILE(DEMOLIB/QSQLSRC) IGCDTA(*YES)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/0a47547e-9312-b717-547d-2dc6349a6191.png)

次にRTVQMQRYコマンドを実行します。
サンプルは、単純にDb2 for i テーブル名（ビュー名）だけを指定したものです。
画像では見えませんが、DEMOLIB/HINMSPを指定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/7fcf72c4-9437-873f-1921-faa6e7cb0d44.png)
実行結果は下記のように10個のカラムのデータが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/914f500d-285b-b887-11e7-7d0c093fa057.png)

RTVQMQRYを実行します。
```
RTVQMQRY QMQRY(DEMOLIB/HINMSP) SRCFILE(DEMOLIB/QSQLSRC) SRCMBR(*QMQRY) ALWQRYDFN(*YES)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/e01f5a40-ad88-5111-a129-626b75cfbad6.png)
***ポイントはQRYDFNからの情報使用可能ALWQRYDFNパラメーターを*YESにすることです***
コマンド名を見ると分かるようにこのコマンドは本来、QUERY管理機能プログラム＝オブジェクトタイプ *QMQRYを検索してSQL文を書き出すコマンドだからです。

出力結果を確認すると、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/9d285c1a-b07d-c317-f74d-61d61327da4d.png)
SELECT文が生成されています。

では、このコマンドをACS SQL実行画面にコピペして実行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/18547c66-591f-7fd4-a1d0-8183f7b642aa.png)
失敗しましたT T)
理由はライブラリー/ファイル名になっているからでした。うーむ、これSQLネイティブ形式出力も指定可能にしてほしいですね。
気を取り直してライブラリー名.ファイル名に修正実行すると、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/a48043bd-f6af-f35d-67bb-4b5fe2708058.png)
実行されました！

## RTVQMQRYコマンド使用例② (やや複雑めな*QRYDFNからSQL文を生成)
次にちょっと複雑な指定をした*QRYDFNからSQL生成をやってみます。
テーブルは1と同じHINMSPです。
***売上-原価=粗利 ARARIフィールドを追加***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/ea3a6c3f-8b75-6561-abf8-34e40b12cae7.png)
***カラムを指定、表示順の変更***下記のようにいくつかのフィールドを除外、順番並べ替えをしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/6c1a35e4-1259-ec44-8575-1e0ac09addec.png)
***原価 GENKA が2,000円以上のレコードのみ選択します***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/af36bb59-526b-d5f6-4c22-68c58036ba9c.png)
以上の*QRYDFNを保管します。実行結果は下記のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/a135a1ce-efe2-eb97-f251-8e7dc5dc7033.png)

それでは、RTVQMQRYコマンドで上記QUERY/400定義をSQL文に変換出力してみます。
```
RTVQMQRY QMQRY(DEMOLIB/HINMSP_Q2) SRCFILE(DEMOLIB/QSQLSRC) SRCMBR(*QMQRY) ALWQRYDFN(*YES)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/f89898bf-b717-baf2-d55c-8cf97f5b19e9.png)
生成されたSQL文はコチラです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/a895e090-b473-4e91-af94-744640ab82f7.png)
ライブラリー/ファイル名をライブラリー.ファイルに修正してACS SQLスクリプト実行してみます。
結果を比較すると、QUERY/400と同様なようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/84e2182c-604d-5fa5-3955-18bec64a5b7b.png)

## RTVQMQRYコマンドコマンド使用例③　さらに条件を追加してみる
使用例②に加えてさらに条件を加えてみます。
***分類フィールド（ソート順）を、粗利ARARI 降順、仕入先番号HNVEND 昇順　を指定***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/73301e26-5f61-db5e-4b4c-61986077cb8b.png)
***カラムヘッダーが2列のものは1列に修正
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/bf1859bd-6ffc-afc6-18a1-73b90d6fa9a0.png)
現実的な意味合いはありませんが、計算機能1～5を追加***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/6f382eb2-5621-2eb7-027b-1f43192db3f3.png)
以上を設定してQUERY/400を実行してみると下記のような結果が返ります。
・ソート順が、ARARI降順→仕入先番号照準
・カラムヘッダーは1行になった
・計算機能1-5(合計、平均、最大、最小、レコード数)はすべて正常計算されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/c5db3acd-33c4-c275-7e86-6b2c1095221c.png)

RTVQMQRYコマンドでこのQUERY/400定義 *QRYDFNをリトリーブしてみます。以下の結果になりました。計算機能などは省略された（出力されていない）ようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/2b43ad23-821a-f7da-a2bd-1c61dc0ec9f6.png)

ACS SQLで実行します。結果はQUERY/400と同様なようです。（のぞく計算機能）粗利 ARARIカラムもヘッダーを設定していない為別な値が入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/ae74c163-e372-1609-7755-08f5aee4a294.png)

## SQL出力ファイルのレコード長の検証
SQL文を書き出すPFのレコード長は92桁以上であれば大丈夫なようです。
SQL文を出力した事後にDSPFFDコマンドで確認するとSQL出力ファイル中に3つのフィールド（カラム）が生成されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/eb4b78fc-ec03-fbcb-cf50-6d77196f3630.png)
SRCPFのレコード長を伸ばすと、SRCDTAのレコード長が大きくなります。

ですが、SQL文の出力桁数は固定のようで80桁前後で折り返されてしまうようです。一方、SQL出力ファイルの桁数が小さいと出力されたSQL文の一部がSQL出力ファイルに保管されない場合がありました。
***SQL出力ファイルレコード長：92***　基本形とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/f39b5ce6-7751-e38c-7155-32de88a44856.png)
***SQL出力ファイルレコード長：132*** 桁数が伸びても出力桁数は92の場合と同様。スクショでは切れていますが右端に日付6桁が入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/6b81f8aa-d3fe-5186-5bfd-2d1ddff2e251.png)
***SQL出力ファイルレコード長：79***　 HNNSUR, が抜けてしまいました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/25bcc969-e5f9-22f8-ddc8-0daa4532450b.png)

よってSQL出力ファイルのレコード長を長くとってもあまり意味が無い& (ひとまず)92より短いといけないようです。

## QUERY/400定義がSQL文に落とせるか？のチェックコマンド ANZQRYコマンド
QUERY/400定義 *QRYDFN をSQL文に落とした際のエラー有無をチェックできます。

使い方は
```
ANZQRY QRY(DEMOLIB/HINMSP_Q3)  
```
のように*QRYDFN名を指定し実行します。

## 考察：今後の、IBM i アプリ資産（ソースコードやIBM i上のオブジェクトの定義）のSQL化、オープン化について

こちらの記事[Source Orbit：ソース・オービット IBM i のアプリコードDevOps・可視化ツール](https://qiita.com/gomAnomalocaris/items/3cb1948ca750f1f6c304)にもあるように、今後どんどん、
　- IBM iのアプリ資産をGitなど外部リポジトリで管理できるようにする
　- IBM iのアプリ資産をSQLベースに移行していく
ということが言えそうです。


※細かい所調べきれてないのでまた追記したいと思います。