RPGにおけるファジー・マッチング
注: 本記事に記載のコードはここからダウンロードできます。
http://www.itjungle.com/fhg/fhg120314-story01.zip
SQL では、LIKE 演算子でワイルドカード文字を使用し、あるパターンの桁を検索できます。GEICOコマーシャルで言っているように、「それは皆が知っています」。では、同じことを RPG プログラムでもできることを知っていましたか?
LIKE 演算子を使用して、不完全一致のデータを検索できます。例えば、名前に「ACME」という文字が含まれたすべてのお客様を検索します。
select * from cust
where name like '%ACME%'
ID NAME
===== ==========================================
19883 ACME Amalgamated Widget and Doodad Company
58842 ACME Glass Home Builders, LLC
大文字と小文字を区別しない検索をする場合、UPPER (または UCASE) 関数を使用します。
select * from cust
where upper(name) like '%ACME%'
ID NAME
===== ==========================================
19883 ACME Amalgamated Widget and Doodad Company
39003 Pete Slacmen Tricycle Supplies, Inc.
58842 ACME Glass Home Builders, LLC
皆が知っているもう 1 つの点は、RPG プログラムで SQL 機能を使用できることです。サブプロシージャー MATCHES は RPG ホスト変数を指定した LIKE を使用します。
dcl-proc Matches;
dcl-pi Matches ind;
inSource like(String) const options(*trim);
inPattern like(String) const options(*trim);
end-pi;
dcl-s Matched char(1);
// 完全一致を試す
if inSource = inPattern;
return *on;
endif;
// ワイルドカード一致を試す
exec sql
set :Matched = case
when :inSource like :inPattern
then '1' else '0' end;
if Matched = '1';
return *on;
endif;
//それ以外の場合、一致なし
return *off;
end-proc Matches;
部分固定フォーマット・コードは次のようになります。
P Matches b
D Matches pi n
D inSource like(String) const options(*trim)
D inPattern like(String) const options(*trim)
D Matched s 1a
/free
// 完全一致を試す
if inSource = inPattern;
return *on;
endif;
// ワイルドカード一致を試す
exec sql
set :Matched = case
when :inSource like :inPattern
then '1' else '0' end;
if Matched = '1';
return *on;
endif;
// それ以外の場合、一致なし
return *off;
/end-free
P Matches e
まず MATCHES は、2 つの文字列の完全一致を試します。一致が見つからない場合、LIKE 演算子を試します。以下の RPG ソース・コードは *ON の値をインジケーター FOUND に割り当てます。
SearchName = 'ACME%Widget%Corporation';
CustomerName = 'ACME Amalgamated Widget and Doodad Corporation';
Found = Matches(CustomerName: SearchName);
どこでこの技法を学んだのかは忘れましたが、Birgitta Hauser が Web に掲載した内容からだったと思います (Birgitta は真の指導者ですが、それは皆わかっています)。誰であれ、「どうもありがとう!」と言いたいです。この技法を使用して終日動作する実動コードを手に入れることができました。