} I言語VER7システム開発の入門編 8/9 (承認機能の追加)


(★注意:VER7.25以前は最新にバージョンアップして下さい。COPY=@...の新機能を使用しました。2010年9月3日改定)
(8)承認機能の追加。
承認機能の場合は,色々の解決策がありますので,ここに示すのはほんの一例です。
まず,どのような仕様にするか決めます。
「仕様」
①めったに有ることではないので,承認が必要になった時点で承認者にはメールを送り承認を促す。
②承認者のテーブルを作るが,I言語の持っている認証システム用テーブルも使う。
③承認済みの場合は,市実表を更新出来ないようにする。
【テータ名】-------------------【データ型】{【I言語の型】}
①ZZZYAA_承認者     CHAR(8){I} (ZZZZ_I_SECURITY_TABLEのZZZZ_PERSONに合わせる)
(I言語の型が{I}は「ファイル名に出来る半角文字全て」で,ZZZZ_PERSONに合わせています)
②ZZZYAA_メールアドレス CHAR(160){,L}(メールアドレスは正しくは160文字では足らな場合もありますが, I言語では1項目最大80文字までしか入力出来ません, 今回は2項目でメールアドレスを構成するものとします)
(I言語の型が{,L}は型1が空白は「汎用機(EBCDIC)互換半角文字」で,型2がLは英小文字を入力可とします)
(I言語では型1が「!」以外は英小文字も,半角カナも入力できません)
【テーブル名】-------------------【主キー】{【従属項目】}
①ZZZYAA_承認者実表    ZZZYAA_承認者{ZZZYAA_メールアドレス}(新規)
②ZZZYAA_市実表       ZZZYAA_し{ZZZYAA_市,ZZZYAA_都道府県,ZZZYAA_承認者}(ZZZYAA_承認者を最後に追加,データ名登録時登録位置注意)

◎(8.1)ZZZYAA_承認者はZZZZ_I_SECURITY_TABLEに有るものとするためデータ辞書に設定します。
ZZZZ010225の「テスト データ辞書 更新」に行き、 '*',[Enter],'←','2','ZZZYAA_承認者','JA','','TEST',’承認者','CHAR','I','',8,'','','LISTBOX21'と入れると 上記画面になるのでここで許可ZZZZのテーブルを選ぶ為'ZZZZ'を選択し以後、?_M_ZZZ?I_SECURITY_TABLEを選びたいですが見つかりません これはI言語のインストールでZZZZ_I_で始まるテーブルは手抜きしてテスト用としてテーブルを作成していない事が原因です。

◎(8.2)ZZZZ_I_SECURITY_TABLEをテスト用にコピーしますが、インストールで更に手抜きをしており、ZZZZ_I_SCURITY_TABLEには全ての人がSELECT出来るPUBLIC権限が付いていますが、インストール時点でZZZZ_I_TABLE_TABLEには登録されていないためそのままコピーしてもテスト用にPUBLIC権限が付きません。 (尚、朝の立ち上げ処理を実行してあると更新されるためこの問題は出ません)そこで手動で設定します。
ZZZZ010426の「本番テーブルの更新(新規不可)」に行き使用者’ZZZZZZZZ'とパスワードを入れて許可ZZZZの管理者で入ります。
[Tab],'ZZZZ_I_SECURITY_TABLE',[Enter]で検索した後,'←','3','1'(インデックスも設定されていないので1を入れます),'PUBLIC','↓',「Enter」で正しい状態に修正します。

◎(8.3)ZZZZ_I_SECURITY_TABLEをテスト用にコピーします。 ZZZZ010413の「本番からテストへテーブルコピー)」に行き使用者’ZZZZZZZZ'とパスワードを入れて許可ZZZZの管理者で入ります。
'ZZZZ_I_SECURITY_TABLE',[Enter]で検索した後,'←','0'で選択します。

◎(8.4)[Tab],[Tab],'YES'でコピー完了です。

◎(8.5)再度データ辞書にZZZYAA_承認者を作成します。今度は?_M_ZZZZ?_I_SECURITY_TABLEが見えますのでこれを選びます。

◎(8.6)CHECK62ではZZZZ_PERSONを選びます。

◎(8.7)CHECK63ではZZZZ_PERSON_NAMEを選びます。

◎(8.8)CHECK64では許可がZZZYの人のみ選ぶ設定を加え"?_X?.ZZZZ_PERMISSION='ZZZY'"とし作成します。
(註:列名には自身の別名用の?_X?.を付加する必要があります)
☆データ辞書とテーブルに関する作成方法は説明したので省略します。ZZZYAA_メールアドレスの作成、ZZZYAA_承認者実表の作成とZZZYAA_市実表のZZZYA_承認者の追加を行って下さい。

◎(8.9)承認者を登録するプログラムを「ZZZYAA_承認者実表」使ってZZZZ300138に「承認者 更新処理」で作ってテスト実行して下さい。
I言語の仕様でメールアドレスが80文字しか入力できません,そこで,2項目に分け160文字入力に改造します。

◎(8.10)これでメールアドレスが分けられます、プログラムを説明します。
1100 DATA={N}X1.?&.DATA&~~AA_メールアドレス?
「N」を付加しました。これはこの項目を画面には表示しない事を意味します。更新対象ですが、画面表示の必要はないので、このようにします。
1110 DATA={*}メールアドレス1{80,,,L}メールアドレス1/2
ここでメールアドレスの前半の80文字を設定します。
「*」はこの項目を更新処理対象としない意味です。実際の更新対象は1100のDATA=ですので、このようにします。
{80,,,L}のLは英小文字を認める意味です,I言語では型1が「!」以外は英小文字と,半角カナは通常では入力できません。
1120 SELECT=?_SUBSTR?(X1.~~AA_メールアドレス,1,80)
これで、検索のSQLではX1.~~AA_メールアドレスの1から80文字目までを受信します。
(「?_SUBSTR?」は文字列を抜き出す関数がRDBMSで異なるためシステム提供データ名で対応しています)
(注意:この方法は,全角文字が有る場合は問題が出ます,今回は全角文字無しですので可能です)
1130 DATA={*}メールアドレス2{80,,,L}メールアドレス2/2
ここでメールアドレスの後半の80文字を設定します。
1140 SELECT=?_SUBSTR?(X1.~~AA_メールアドレス,81,160)
これで、検索のSQLではX1.~~AA_メールアドレスの81から160文字目までを受信します。
1150 =SET{X1.~~AA_メールアドレス=メールアドレス1+メールアドレス2};
実際の更新はX1.~~AA_メールアドレスで行うので,更新されるように転送します。
「+」は文字列を結合する意味です。

◎(8.11)これでメールアドレスが160文字分正しく更新出来るようになりました。
テスト作業をするためZZZZZZZYを承認者として登録しました。(メールアドレスをお持ちの場合は、正しく設定して下さい)
★補足説明:ZZZZ_はI言語システム用テーブルでその中でもZZZZ_I_が付いているものは,本番用のみ作られています, 権限はPUBLICに読み込み権限があり,全ての利用者が読む事ができます,本来はテーブル情報にPUBULIC指定ありを設定すべきですが, インストールソフトはこれをしないでテーブルに直接PUBLIC権限を与えているため,余分な作業が必要でした。
I言語でのPUBLIC権限とはそのデータベースを扱える全てのログインIDに対しSELECT権限を与えます。
このように,I言語と言えどもデータベース上で色々の問題が出ますので,難しいですが,ある程度は知っておくべき事が有りますので説明します。
まず,データベースには大きく3種類の物が登録されます。(SQL Serverのみで他のRDBMSでは大きく違います)
①データベース---テーブルを作る器です。SQL Serverでは全部で8個作られます。(SQL Server以外は1個です)
②ログインID---データベースに接続する時ログインIDを使用して接続します。I言語では全部で16個作られます。
③バックアップデバイス---データベースをバックアップ(保存)する器です。I言語では全部で16個作られます。 (これは開発には直接関係はないので,ここでの説明は省きます)
まずはデータベースから見てみます。

◎(8.12)データベース名一覧を見るためZZZZ010412「SQLを実行」を起動します。ここで全てを見るため必ず'ZZZZZZZZ'の使用者で入ります (メニューの認証が「A]の場合は,必ず使用者を要求してきます) (尚,この作業はSAのパスワードを知っている必要があります)
[Enter]で「」,「LOGIN」(SAでログインする為),「SQL=」(SELECTで検索する場合使用)を'0'で選択します。

◎(8.13)SAで接続するため’Tab'2回でS_PASSWORDに行き「AS」のパスワードを入れ[Enter]で検索します。

◎(8.14)[Enter],'←','2','100','',"SELECT NAME FROM MASTER.SYS.DATABASES WHERE NAME LIKE 'I_?_SYSTEM?%' ORDER BY 1",[Enter]で作成後, '0'で選択します。

◎(8.15)データベースの一覧が見えました,名前の内訳を説明をします。
①I_:I言語で作るものにはすべて「I_」で始まります。
②ABC:システム名でシステム別に作ります。
③REAL/TEST:REALが本番用でTESTがテスト用です。
④MAST/WORK:MASTがマスタ用でI言語で「テーブル 更新」で作るテーブルはここに作られます,WORKは一時作業で作るテーブル用です。
⑤ZZZY/ZZZZ:許可の単位でデータベースを分けています。
このようにデーターベースを複数持つ事で,管理しやすくしています。

◎(8.16)次はログインIDの一覧を調べます。
'←'、'200'、「Enter]で検索,'←','2','200','',"SELECT NAME FROM MASTER.SYS.SYSLOGINS WHERE NAME LIKE 'I_?_SYSTEM?%' ORDER BY 1",[Enter]で作成後, '0'で選択します。
注意:再検索しないと、プログラムに問題が有り、「(65536)ユーザー 'SA' はログインできませんでした。」のエラーが出ます。

◎(8.17)ログインIDの一覧です内訳です。
データベースのMASTとWORKの部分はなく,その場所に,DBO,INP,LNK,OUTが有ります。
①DBO:DB Ownerの意味でデータベースの管理者用です。I言語自身がログインする場合は許可ZZZZのDBOを使用します。
プログラムの中でDBO_を命令の先頭に付加した場合はその命令のみ,その許可のDBOでログインし直します。
このログインIDにはDB_OWNERと呼ぶロールを付与しており,そのデータベースの全ての操作が出来る設定になっています。
②INP:INPUTの略でメニューの処理種類を「INPUT」とした場合このログインID付きで接続します。
③OUT:OUTPUTの略でメニューの処理種類を「OUTPUT」とした場合このログインID付きで接続します。
④LNK:リンクサーバーを使用して接続する場合のみこのログインIDを使用します,つまり,リンクサーバーの設定以外では使用しません。
このようにプログラムがログインするIDをI言語が使い分けるので,テーブルの権限の設定が重要になります。
それでは,具体的にどのように権限が設定されているのか確認してみます。

◎(8.18)ZZZZ010211の「テスト テーブル内容 表示,消滅」を起動し,ZZZZの管理者'ZZZZZZZZZZ'を使用者としてパスワード入り ,名前に'ZZZZ_SYS_MAST%GRANT'と入力し検索します。
'←','0'で選択します。

◎(8.19)SQLに"WHERE ZZZZ_NAME=N'ZZZYAA_市実表'"と入力し[Enter]します,これで,権限がどのように設定されているのか分かります。
SがSELECT,IがINSERT,UがUPDATE権限です,DはDELETE権限ですがどこにも設定されていないのがI言語の特徴です, つまりDELETEは通常の状態では実行できません,また,許可が自分自身とZZZZのみに与えらてているので, 何もしないとZZZZ以外の他の許可からは一切使えないようになっています。
また,OUTはOUTPUTで検索用ですのでSELECT権限しかありません。

◎(8.20)それでは先ほどのZZZZ_I_SECURITY_TABLEを見てみます。
[Esc]で戻って,'↓','0'で"ZZZZ_SYS_MAST_ZZZZ_GRANT_VIEW"を選択しSQLに"WHERE ZZZZ_NAME=N'ZZZZ_I_SECURITY_TABLE'"と入力し[Enter]します。
今度はZZZY分がないので少ないですが,PUBLICが増えています,PUBLICは全てのログインID共通の設定と同じ事ですので, PUBLICでどのログインIDでもSELECTが実行できます。
ほかに,LNKや他の許可にもSELECT権限を与えられるようになっていますが,ここでは説明を省きます。

◎(8.21)次はZZZZ300131のメニューで「承認 処理」を作ります、ZZZZ010221の「テスト 全 プログラム 更新」で「ZZZYAA_市実表」 からプログラムを作り承認機能に変更します。
プログラムの説明をします。
410 CONTROL=1,2
CONTROL=はI言語に対し細かな指示を与えます。承認は修正処理のみで良いので、 「1」で削除処理の抑止、「2」で作成処理の抑止を指示しています。
420 BEGIN
ここから下に書いた命令群をプログラムの開始で実行する指定です。
430 =SET{未承認='YES'};
通常では未承認分を検索し承認するので、「未承認」に’YES'を初期値として転送します。
440 SET=未承認{3}{YES,NO};
未承認分のみ(YES)か全て(NO)を指定できる入力項目を設定します。
450 =SET{W.ZZZYAA_承認者=_PERSON};
PROGRAMで使用するデータに初期値を与えます。
_PERSONはI言語の認証で使われた使用者でこの人が認証する事になります。
460 =PROGRAM{?_M?AA_承認者実表}{W.ZZZYAA_承認者}{}{0};
最後に書かれている{0}で検索処理を実行します。
470 =IF{_PROGRAM_COUNT!=1}ERROR{あなたは承認できません!};
検索データが無い(1件以外)場合は「あなたは承認できません!」でエラーとします。
480 =SET{_DATA@WHERE=};
490 =IF{_DATA='YES'}SET{_DATA@WHERE='X1.~~AA_承認者='' '''};
未承認が「YES」の場合は検索条件に~~AA_承認者が空白の条件を設定します。
引用符(')の中の引用符は2個で1個と見なします。
_DATA@WHEREは通常はI言語が設定しますが、今回は通常の使い方ではないのでプログラムで設定しています。
1300 DATA={O}X1.?&.DATA&~~AA_市?
1500 DATA={O,&X3}X1.?&.DATA&~~AA_都道府県?
~~AA_市と~~AA_都道府県は修正しないので表示のみで'O'を付加します。
(I言語ではデータが変更されなければSQL文でそのデータを変更する部分は作られないので、更新対象としない意味の*は不要です)
1710 =CHECK2=,,?_PERSON?,?_PERSON_NAME?
空白と使用者のみ入力できるようにしています。

◎(8.22)実際に「し」が「いいだ」を処理をしてみると承認者が修正出来、承認処理が出来ました。

◎(8.23)次はZZZZ300121の「市 更新処理」を修正します。
1610 START
STARTは更新の1,2,3の入力直後に実行するプログラム用です。
1620 =IF{_START!=2}IF{X1.~~AA_承認者!=}ERROR{承認済です!};
_STARTは1,2,3のどれかの値です。
_STARTは2以外かつX1.承認者が空白以外のときは承認済みですので、処理出来ないようにエラー表示します。
1630 =IF{_START=1}EXIT{};
_STARTが1の時はメール不要なので次に行きます。
1640 =SQL_SET{W.~~AA_メールアドレス}{SELECT ~~AA_メールアドレス
1650 = FROM ?_M?AA_承認者実表 WHERE Z_CANCEL=' '}
メールアドレスを受信します。(尚、今回はメールアドレスは1個のみを想定しました)
1660 = ERROR{承認者実表に登録情報がありません};
メールアドレスが無い場合はエラーとします。
2210 DATA={*O}X1.?&.DATA&~~AA_承認者?
~~AA_承認者は無かったので追加します。
{*O}の*は更新対象で無い事を意味し,OはOUTOUTで入力しない意味です。
2220 STOP_AFTER
STOP_AFTERは更新処理後に実行される処理用です。(更新処理前はSTOP_BEFOREです)
2230 =IF{_START=1}EXIT{};
削除の場合はメール不要ですのでそのまま終了します。
2240 =SMTP{}{}{?W.~~AA_メールアドレス?}
2250 ={?@ZZZZ_SMTP_FROM_ZZZY?}{市承認依頼の件}
2260 ={市(?X1.~~AA_し?,?X1.~~AA_市?,?X1.~~AA_都道府県?)
2270 =の承認をよろしくお願いします。};
これでメールを出します。一応確認の画面が出ますので、送信するか、送信しないか選べますが、更新処理は行われます。
尚、SMTPの最初の{}はSMTPサーバーを指定しますが空白の場合特殊データ名の@ZZZZ_SMTP_SERVERを使用します。
また、2番目の{}はSMTPサーバーのポート番号ですが空白の場合特殊データ名の@ZZZZ_SMTP_PORTを使用します。
さらに、4番目の{}は送信者のメールアドレスですがこれも特殊データ名の@ZZZZ_SMTP_FROM_ZZZYを陽に指定しています。
よって、事前に3個の特殊データ名を登録する必要があります。

◎(8.24)@ではじまる特殊データ名はI言語提供の混在テーブルのキー1が'ZZZZ_@'に登録します。
テスト中は混在テーブルもテスト用のテーブルを使用しますが、混在テーブルは本番用を更新すると同時にテスト用も更新されるようになっていますので、今回は本番用の混在テーブルを更新します。
ZZZZ010137の「混在テーブル 更新」に行き検索後キー1のZZZZ_@を'0'で選択します。

◎(8.25)3項目を作成します。(ETCデータは私の場合ですので、ご自分の環境に合わせて作成下さい)

◎(8.26)承認済みを修正しようとすると「承認済みです!」と出て修正できなくなりました。

◎(8.27)新規に作成するとメール配信確認画面が出ます。(註:ここでキャンセルしても作成は完了しておりメールが送られないだけです)
これで、承認機能の追加は全て完了です。
次へ(9/9,インターネットでの公開)
All Rights Reserved, Copyright (C) 2009-2010 Nobumichi Harasawa.