0

--- ここで、他のファイルで削除したい顧客番号を見つけました。最初に顧客マスターを読み取り、次に注文履歴または請求履歴に顧客番号が存在するかどうかを確認します。そうでない場合は、この顧客を顧客マスターと他の 2 つのファイルから消去します。

ただし、2 番目のファイルで、顧客番号のマーケティング列に「A」または「C」があり、それが 2007 年以降のものである場合、この番号をどのファイルからも削除したくありません。

だから私は、顧客レコードを保存/保留ファイルに書き込んで削除する前に、はい、これは削除してもよいというフラグを返すコードを作成しました。

C                   IF        PUGFIL = 'Y' AND        
C                             ACENT# <> ACENT#_OLD    
c                   EXSR      CHKCUS_SR               
c     ACFLAG        IFEQ      'N'                     
C                   WRITE     TRCMASRR                
c*                  delete    arcmasrr                

c     CHKCUS_SR     BEGSR      
c                   eval      ACFLAG = ' '                        
C     ORHKEY        SETLL     dRCST1                              
C     ORHKEY        READE     dRCST1                              
 * If the order entity is found, write the rec into VRCSTKBI file 
C                   DOW       NOT %EOF(dRCST1)                    
c                   if        BICOTC <> 'A' AND BICOTC <> 'C'     
C                   WRITE     VRCSTKRR                            
c                   EVAL      ACFLAG = 'N'                        
c                   endif                                         
c                   if        bicotc = 'A'                        
c                   if        BISTPD <  20070101                  
C                   WRITE     VRCSTKRR                            
c                   EVAL      ACFLAG = 'N'                        
c                   endif                                         
c                   endif                                         
c                   if        bicotc = 'C'                        
c                   if        BISTPD <  20070101                  
C                   WRITE     VRCSTKRR                            
c                   EVAL      ACFLAG = 'N'         
c                   endif                          
c                   endif                          
c     acflag        ifeq      'N'                  
C                   EXSR      CHKADR_SR            
4

4 に答える 4

5

Buck と Benny は、RPG コードを改善する方法について多くの良い提案をしてくれました。

  • フリーフォーマットを使用して読みやすくする
  • 物事が実際に何であるかを明確にするために、より長い説明的な名前を使用してください。(最初から明確な名前を付けられたのに、誰かに名前を解読させないでください)
  • サブルーチンではなく、サブプロシージャを使用します。サブプロシージャから値を返すと、ユーザー定義関数になり、さらに優れたものになります

手順は 1 つのアイデアを実行する必要があります。その手順のすべては、その 1 つのことを行うことに関連している必要があります。これは結束と呼ばれます。手順をかなり小さくシンプルに保ちます。なんて小さい。マサチューセッツ工科大学の AI ラボの責任者だったセムール パパートは、若い学生が興味のあることを実行できるようにコンピューターをプログラミングできるようにすることに関心を持っていました。彼が彼らの一人に、手術はどれくらいの大きさであるべきかを尋ねたところ、彼が得た答えは「心の大きさの一口」でした.

プロシージャ間の不必要な依存関係を最小限に抑えて、ある領域での変更が別の領域で問題を引き起こす可能性を低くしたいと考えています。これをカップリングと呼びます。

ループ内で、「A」または「C」をチェックする場所の数に注意してください。同じコード ブロックを「A」に対して 1 回繰り返し、次に「C」に対してもう一度繰り返します。代わりに IF .. OR.. を使用することもできたので、将来のメンテナンスの問題につながる可能性のあるコード ブロックを繰り返さないようにすることができます。DRY の原則、Don't Repeat Yourself に違反しています。自分のことを、すべて [コード行] のための場所があり、すべて [コード行] がその場所にあると言っている整頓された家政婦だと考えることができます。

さて、マイナーポイントに。いたるところで、同じキーを使用して SETLL を使用し、その後すぐに READE を使用する人を見かけます。代わりに CHAIN を使用してください。内部では、CHAIN は SETLL によって実行されるロジックを実行し、次に READE のロジックを実行します。SETLL の成功を条件として READE を作成することで、時間を節約できると考えている人もいます。しかし、何が起こっているかというと、各 I/O ステートメントで、コンパイラーは I/O モジュールを呼び出すパラメーターを準備するコードを生成し、モジュールを呼び出して I/O 関数を実行し、返されたパラメーターを処理します。2 つの I/O ステートメントでは、これを 2 回行っています。CHAIN オペレーションに任せれば、内部効率を向上させる機会もあります。さらに、RPG コードが少し単純になりました。あらゆる角度からの方が優れています。

それの準備をしなさい...

従来の I/O ステートメントを使用する代わりに、埋め込み SQL を使用する必要があります。ここで論文全体を書きたくない理由はたくさんあります。今のところ私を信頼してください。これを学ぶための投資は本当に報われます。

SELECT、DECLARE、および OPEN CURSORS (オープン データ パスのような) を学習し、次にカーソルからレコードを FETCH し、一度に複数のレコードを FETCH または INSERT することもできます。

さて、本当に大きなことは

従来の RPG パラダイムは、一般にループを通過し、ループを通過するたびに 1 つのレコードを処理し、多くの場合、一度に 1 つのレコードで他のファイルに対して追加の I/O を実行します。

SQL を使用すると、単一のステートメント、ファイル全体、または複数のファイルでレコードをセットとして処理できます。ファイル全体と他の 2 つのファイルを 1 つの SQL ステートメントで実行することにより、RPG コードを大幅に削減および単純化できます。

CREATE TABLE QTEMP/PURGING AS
( SELECT c.customer, ...
    FROM Customers c
    LEFT EXCEPTION JOIN Orders o
            on c.customer = o.customer
    LEFT EXCEPTION JOIN Invoices i
            on c.customer = i.customer
    WHERE c.customer not in 
           (select s.customer
              from secondfile s
              where marketing in ('A','C')
                and eventdate > '2007-12-31'
           )
) with data;

DELETE FROM secondfile x
  WHERE x.customer in
          (select p.customer
             from purging p
          );

DELETE FROM thirdfile x
  WHERE x.customer in
          (select p.customer
             from purging p
          );

DELETE FROM Customers x
  WHERE x.customer in
          (select p.customer
             from purging p
          );

4 つのステートメント。それだけです。ループなし。最初のステートメントを正しく理解したら、残りは非常に単純です。

CREATE TABLE ... WITH DATA は、SELECT の結果を新しいテーブルに書き込みます。あなたがそれを保持したいかどうか確信が持てなかったので、私はそれが QTEMP に入ることだけを示しています。LEFT EXCEPTION JOIN は、検索条件に一致する右側の行を持たない、左側のテーブルの行を使用することを示しています。これにより、注文履歴にも請求書ファイルにもない顧客レコードを選択できます。削除する顧客のリストを含むファイルが作成されたら、そのリストを使用して、顧客マスターと他の 2 つのファイルからそれらの顧客を削除できます。

于 2013-09-05T04:56:31.237 に答える
2

より多くの列を選択することを暗示する 3 つのドットを削除して、顧客列だけが必要です。

明確なキーワードを追加してパージ テーブルを一意にすると、3 つの例外結合を使用できるようになります。これは、分析で例外結合から非結合へギアをシフトする必要がないため、はるかに読みやすくなります。テーブルには顧客の主キーがありました。

念のため、ドロップ テーブルも追加します。

drop table qtemp/purging;

CREATE TABLE QTEMP/PURGING AS
( SELECT distinct c.customer
FROM Customers c
LEFT EXCEPTION JOIN Orders o
        on c.customer = o.customer
LEFT EXCEPTION JOIN Invoices i
        on c.customer = i.customer
left    exception join secondfile s on 
        c.customer = s.customer and
          marketing in ('A','C')
            and eventdate > '2007-12-31'
       )
) with data;
于 2013-09-11T17:20:02.073 に答える
1

これはあなたが望んでいるものですか?

/free
    if pugfil = 'Y' and agent# <> agent#_old;
       exsr chkcus_sr;
       if do_purge = 'Y';
          write trcmasrr;
          delete arcmasrr;
       endif;
    endif;

    begsr chkcus_sr;
       // Assume we will purge this customer.
       do_purge = 'Y';
       setll orhkey drcst1;
       reade orhkey drcst1;
       dow not %eof(drcst1);
          // If bicotc is A or C and the date is January 1, 2007 or later, do NOT purge and stop checking other records.
          if (bicotc = 'A' and bistpd >= 20070101) or
             (bicotc = 'C' and bistpd >= 20070101);
             // Make sure you change the flag to say NO - DON'T PURGE THIS CUSTOMER
             do_purge = 'N';
             leavesr;
          endif;
          write vrcstkrr;
          // Looks like you are doing more processing here but you don't show the code...
          reade orhkey drcst1;
       enddo;
    endsr;
 /end-free

または、固定フォーマットに固執したい場合:

c                   ifeq      pugfil = 'Y' and
c                             agent# <> agent#_old
c                   exsr      chkcus_sr
c                   if        do_purge = 'Y'
c                   write     trcmasrr
c                   delete    arcmasrr
c                   endif
 *------------------------------------------------------------------
c     chkcus_sr     begsr      
c                   eval      do_purge = 'Y'
c     orhkey        setll     drcst1
c     orhkey        reade     drcst1
 * If the order entity is found, write the rec into VRCSTKBI file
c                   dow       not %eof(drcst1)
c                   if        (bicotc = 'A' and bistpd >= 20070101) or
c                             (bicotc = 'C' and bistpd >= 20070101)
c                   eval      do_purge = 'N'
c                   leavesr
c                   endif

c                   write     vrcstkrr
 * // Do some other processing here that you don't show...
c     orhkey        reade     drcst1
c                   enddo
于 2013-09-04T21:00:59.167 に答える