関数があるのに見つからない理由
こんにちは、Ted:
SQLで使用するためにRPGで関数を作成しようとしていて行き詰まっています。ベースにしたのはTedさんのFMTDATE関数です。正常にインストールしましたし、問題なく動作しています。作成した関数を動作させようと、5時間、奮闘したのですが、万策尽きました。何かパッとお気付きになることなど、ありませんでしょうか。
-Andrew
Andrew氏が受け取っていたメッセージは、「SQL0204 (HISFUNCT in *LIBL type *N not found)」(*LIBLのタイプ*NのHISFUNCTが見つからない)だったようです(Andrew氏の関数の名前をHISFUNCに変更してあります)。けれども、その関数も、サービス プログラムも存在していました。Andrew氏のRPGコードにも、CREATE FUNCTIONステートメントにも、何も問題はありませんでした。それでは、なぜ動作しなかったのでしょうか。原因を見つけるのに数回の試行錯誤が必要だったのですが、Andrew氏がCHARパラメーターをVARCHARパラメーターに置換したら、システムはその関数を見つけるようになりました。
SQL0204は誤解を招きやすいエラー メッセージですが、これはSQLの素晴らしい機能(関数のオーバーロード)によるものです。SQLでは、パラメーター リストが異なっていれば、同じ名前の関数を2つ以上定義することができます。システムが伝えているのは、互換性のあるパラメーター リストを持つその関数のバージョンが存在しないということであって、その関数のバージョン自体が存在しないということではありません。パラメーターが互換性ありとみなされるのは、呼び出しで渡されるデータがそのデータ タイプである場合か、(パラメーター定義の)そのデータ タイプにキャストできる場合です。
暗黙的キャストは、必要があり、可能なときにシステムが裏で自動的にデータを1つのデータ タイプから別のデータ タイプへ変換することを意味します。これは新しい機能というわけではありません。威厳あるこの刊行物でも、約8年前にSkip Marchesaniがそれについて記事を書いています。以前は正しく機能しなかった暗黙的キャストを、ますます多く目にするようになっていることからすると、IBMの優秀な人々は、その間、数独パズルで遊んでいたわけではなかったようです。IBMはIBM i 7.2で暗黙的キャストを大幅に機能強化しましたが、Andrew氏のシステムは7.1でした。7.2のシステムではそのエラーを再現できませんでした。CHARとVARCHARとの間でのキャストは、データベースおよび関数でデータがどのように定義されていても、毎回、機能しました。さらに、char(1)およびvarchar(1)パラメーターに数値リテラルを渡すこともできました。
ビジネス プロセスを実行するためにSQL関数を書く(そうすることはお勧めですが)場合は、パラメーターをできるだけ融通無碍に(すなわち、キャスト可能に)するよう心掛けてください。私はそれでもCHARよりもVARCHARを選びます。システムは問題なくCHAR引数をVARCHARパラメーターにキャストできると確信しているからです。同様に、パック10進数およびゾーン10進数データで使用するつもりの場合でも、私は数値パラメーターをINTEGERまたはDOUBLEとして定義することがよくあります。私または他の誰かがどのようなデータを投入したとしても、必ず関数が処理できる可能性が高まるためです。IBM Knowledge Centerのこのページの表1には、データ タイプの互換性について詳しい情報が掲載されていますので、参照してみてください。