メニューボタン
IBMi海外記事2023.10.25

長いオブジェクト名と短いオブジェクト名を取得する

Bob Cozzi 著

IBM i で、ファイル名およびライブラリー名に「長いSQL名」が導入されたのは、ずいぶん前のリリースでのことです。これらの新たな長い名前(最大128文字)は、SQLマニアには好評を博しましたが、本流のIBM i 開発者からは、ほとんど無視されることとなりました。IBM i の新バージョンが登場するたびに、ますます多くのショップが、10文字より長い名前を持つオブジェクトに遭遇するようになっているようです。

先日、私は、BOAT_TRAFFICという名前のファイルを作成しました。このファイル名は、明らかに10文字より長い名前です。そのファイルは、SQL DDL(CREATE or REPLACE TABLEステートメント)を使用して作成しました。長い名前を持つオブジェクトを作成するには、SQL DDLを使用するのが現実的な唯一の方法です(IBM i システム コマンド インターフェース(すなわち、CLコマンド)は、長い名前をサポートするように機能強化されていません)。これはCLまたはコマンドの制限ではありません。CLコマンドは、これまでもずっと128バイトの名前をサポートすることができていました(実際に、1980年、私が初めてユーザー記述CLコマンドを書いたときに、オブジェクト名パラメーターが誤って長さ「32」に指定されていましたが、問題なく動作しました)。長いオブジェクト名およびライブラリー名をサポートするために、中核となるCLをアップデートすることは、「決して起こらない」ことであるように思われます。

BOAT_TRAFFICファイル(つまり、表)を作成するのに使用した、SQL DLLの短縮バージョンを以下に示します。

CREATE or REPLACE customs.BOAT_TRAFFIC (
   CID  INTEGER  PRIMARY KEY                             
        GENERATED ALWAYS AS IDENTITY                   
          (START WITH 101, INCREMENT BY 1),           
 INVNBR      DEC(7,0) NOT NULL DEFAULT 0 ,               
 INVDATE     DATE NOT NULL DEFAULT CURRENT_DATE ,        
 CONTACT     VARCHAR(30) NOT NULL DEFAULT '',            
 DESTINATION VARCHAR(50) NOT NULL DEFAULT '',            
 BOATNAME    VARCHAR(30) NOT NULL DEFAULT ''
) RCDFMT TRAFFIC;

昔ながらのCPYFコマンドの出る幕はない

このファイルを開発者ライブラリーまたはバックアップ ライブラリーへコピーするとしたら、状況に応じて、CRTDUPOBJ(複製オブジェクト作成)またはCPYF(ファイル・コピー)を使用するのが一般的でしょう。たとえば、現行データで開発者ライブラリーのデータをリフレッシュしたいので、CPYFを使用するとします。この場合、コマンド入力画面の表示は、下図のようになるでしょう。

実際には、このコピー操作は、SQLを使用して行うことができました。まず、ターゲット ファイルのデータをクリアしてから、SQL INSERTステートメントを使用して新しいデータで上書きコピーする必要がありました。以下のようになります。

INSERT INTO BOBDEV.BOAT_TRAFFIC
SELECT * FROM customs. BOAT_TRAFFIC

これだと十分ではありません。(A)TRUNCATEまたは同様のステートメントを使用してターゲット ファイルをクリアして、(B)識別列にデータを供給しながらレコードをコピーする必要があるからです。そうするには、以下のように、INSERTステートメントにOVERRIDING XXX VALUEを追加します。

TRUNCATE TABLE BOBDEV.BOAT_TRAFFIC
     REUSE STORAGE
     IGNORE DELETE TRIGGERS
     IMMEDIATE;
INSERT INTO BOBDEV.BOAT_TRAFFIC OVERRIDING SYSTEM VALUE
SELECT * FROM customs. BOAT_TRAFFIC;

通常、識別列があるファイルに行が追加されると、データベースは自動的に識別列を増分します。それを回避するためには、OVERRIDING USER VALUEまたはOVERRDING SYSTEM VALUE節を使用することができます。

OVERRIDING USER VALUEは、INSERTの副照会(すなわち、SELECTステートメント)に識別列値が含まれているが、システムにその値を無視させて、新たに追加された各行に新規の値を生成させることを意味します。

OVERRIDING SYSTEM VALUEは、INSERTの副照会(すなわち、SELECTステートメント)に識別列値が含まれていて、ターゲット ファイルへコピーすることによって、システムにその値を保持させることを意味します。

この例では、明らかに、OVERRIDING SYSTEM VALUEです。

その他の長い名前

データベース ファイル以外にも、SQLには、SEQUENCE(順序)、ALIAS(別名)、FUNCTION(関数)、PROCEDURE(プロシージャー)など、他のオブジェクトもあります。これらのオブジェクトはすべて、最大長128バイトのSQL名をサポートします。たとえば、SQL ALIASを作成して、長い名前を指定するとします。ALIASオブジェクトは、IBM i のショップによって、特にメンバーの処理でしばしば使用されます。SQLはメンバーを認識しないため、IBMは、ファイルの特定のメンバーにアクセスするのに使用できるようにALIASを機能強化しました。

CREATE or REPLACE ALIAS CUSTOMS.BOAT_TARIFF_BAHAMAS 
        FOR CUSTOMS.TARIFF(BAHAMAS);      

この例では、CUSTOMSライブラリーにBOAT_TARIFF_BAHAMASという名前のALIASを作成しています。このALIASをSELECTステートメントで使用して、TARIFFファイルのBAHAMASメンバーを照会することができます。ALIASは、他のすべてのSQLタイプと同様に、SQLカタログでIBM i システム オブジェクト名に対応する長い名前を保管しています。

SQLカタログ

データベース ファイルは、ファイルのオブジェクト記述に自身の長いSQL名を保管しており、QDBRTVFD(データベース・ファイル記述の検索)APIを介してその名前へのアクセスを提供します。そしてもうひとつ、長いSQL名に対応するIBM i オブジェクト名を返す、QDBRTVSN(短縮名の検索)というAPIもあります。ただし、これもまた、データベース ファイルにのみ(最近では、ライブラリー名にも)適用されます。

長いSQL名を持つ他のすべてのオブジェクト タイプは、SQLカタログで相互参照されます。IBMは、カタログ名で極めて一貫性のある命名規則を使用しているため、どのカタログを照会する必要があるのか、ある程度覚えやすくなっています。以下に、すべてのSQLオブジェクトと、暗黙的にSQLオブジェクトである多くのIBM i オブジェクト(物理ファイルおよび論理ファイルなど)のプロパティが格納されている、カタログ ファイル名のリストを示します。

SYSTABLESカタログは、以下のような様々なタイプのファイル/表で使用されます。

短い名前から長い名前へシームレスに変換する関数

私がQDBRTVSN(短縮名の検索)APIを使用して、長いSQL名から短いIBM i システム オブジェクト名への変換をし始めたのは数年前のことです。しかし、SEQUENCES(順序)、Functions(関数)、Triggers(トリガー)などを使用し始めると、フラストレーションを感じるようになってしまいました。当初のアプローチは、カタログを使用して、タイプに基づいて特定のカタログ ファイルを動的に照会するというやり方でした。しかし、このやり方は、必ずしも直観的でも実用的でもありませんでした。そのため、私はもっと良いインターフェースを開発することとしました。

GETOBJNAME SQL関数は、通常のIBM i の短いシステム オブジェクト名およびライブラリー名、または、長いSQL名および長いまたは短いスキーマ名を受け取り、そのオブジェクトの長い名前と短い名前の両方を、呼び出し元へ返します。返されるのは1行のみで、以下の6つの属性がすべて格納されています。

以下は、GETOBJNAME関数のRPG IVでの使用例です。

   dcl-s objname  varchar(10);
   dcl-s objlib   varchar(10);
   dcl-s objtype  varchar(10);
   dcl-s longName varchar(128);
   dcl-s longLib  varchar(128);
   dcl-s sType    varchar(18);

   EXEC SQL SELECT objname, objlib, objtype,
                   longObjName, longObjLib, SQL_OBJECT_TYPE
             INTO :objName, :objLib, :objType,
                  :longName,:longLib, :sType
             FROM TABLE(SQLTOOLS.getObjName(
                         '*LIBL',' BOAT_TARIFF_BAHAMAS','ALIAS')
                        );
    If (SQLState < '02000'); 
      // We have the Short Object Name!  
    endif;   

GETOBJNAME SQL関数

GetObjName SQL関数は、任意のオブジェクトの長い名前と短い名前の両方を返します。皆さんのオブジェクトの大半は、短い名前があるのみで、おそらくSQLオブジェクト タイプは割り当てられていないでしょう。そうだとすると、LONGOBJNAME列およびLONGOBJLIB列には、それぞれOBJNAME列およびOBJLIB列と同じ値が入り、SQL_OBJECT_TYPEはNULLになります。

GETOBJNAMEは、IBM i 7.2以降で動作します。お使いのシステムでこの関数を使用するには、後述するコードをソース メンバーにカット&ペーストして、そのメンバーでRUNSQLSTM(SQLステートメント実行)コマンドを実行します。代りに、IBM ACSの「SQLスクリプトの実行」インターフェースにコードにペーストして、直接、実行することもできます。GETOBJNAMEは「SQL Tools」に組み込まれているため、「SQLTOOLS」が、使用されるライブラリー/スキーマ名になる点に注意してください。

GitHubをご利用の場合は、私のGitHubページ( https://github.com/bobcozzi/GETOBJNAME )で、直接、ダウンロードすることもできます。

あわせて読みたい記事

PAGE TOP