2017-02-28 7 views
0

un conseil de progrès 4GL gourou pour jeter un coup d'oeil sur le bloc de code 4GL ci-dessous et voir si c'est trop fait? peut-il être fait pour qu'il soit plus facile à suivre/plus lisible?Openedge Progress 4GL Table rejoindre

je tblA

Report 
6998077 
6998078 
6998097 
7062816 

Et TblB

+-----------+------------+-----------+ 
| ID  |  Source| Report | 
+-----------+------------+-----------+ 
| 4976117 | 6998077 | 6998077 | 
| 4976118 | 6998078 | 6998078 | 
| 4976137 | 6998097 | 6998097 | 
| 5107798 | 7062816 | 6998078 | 
| 5107799 | 7062816 | 6998097 | 
+-----------+------------+-----------+ 

et je dois, à mon avis, une boucle complexe Progress 4GL:

def temp-table TblTemp no-undo 
field cTypeOfRec  as char 
field Report   as int 
field Source   as int 
field ID    as int 
index key is unique primary Report Source ID. 

procedure SOOptimize: 
    output stream dOut1 to value("/OutPut.txt"). 
    export stream dOut1 delimiter "|" 
    "Report" 
    "Source" 
    "ID". 
    for each TblA no-lock 
      on error undo, return error on stop undo, return error: 
    for each TblB no-lock where 
      TblB.Source = TblA.Report 
      on error undo, return error on stop undo, return error: 

     find TblTemp exclusive-lock where 
      TblTemp.SrcPltSeq = TblA.Report and 
      TblTemp.RptPltSeq = TblB.Report and 
      TblTemp.ID  = TblB.ID 
      no-error. 
     if NOT available TblTemp 
     then do: 
     create TblTemp. 
     assign 
      TblTemp.cTypeOfRec = "From LoopA" 
      TblTemp.SrcPltSeq = TblA.Report 
      TblTemp.RptPltSeq = TblB.Report 
      TblTemp.ID   = TblB.ID. 
     end. 
    end. 
    for each TblB no-lock where 
      TblB.Report = TblA.Report 
      on error undo, return error on stop undo, return error: 
     find TblTemp exclusive-lock where 
      TblTemp.SrcPltSeq = TblB.Source  and 
      TblTemp.RptPltSeq = TblA.Report  and 
      TblTemp.ID  = TblB.ID 
      no-error. 

     if NOT available TblTemp 
     then do: 
     create TblTemp. 
     assign 
      TblTemp.cTypeOfRec = "From LoopB" 
      TblTemp.SrcPltSeq = TblB.Source  
      TblTemp.RptPltSeq = TblA.Report 
      TblTemp.ID   = TblB.PltSrcSeq.   
     end. 
    end. 
    end. 
    for each TblTemp no-lock 
    on error undo, return error on stop undo, return error: 
    export stream dOut1 delimiter "|" 
     TblTemp.  
    end. 
end procedure. 

Ensuite, la sortie de mes progrès Le code est:

+------------+---------+---------+---------+ 
| cTypeOfRec | Source | Report | ID | 
+------------+---------+---------+---------+ 
| From LoopA | 6998077 | 6998077 | 4976117 | 
| From LoopA | 6998078 | 6998078 | 4976118 | 
| From LoopB | 7062816 | 6998078 | 5107798 | 
| From LoopA | 6998097 | 6998097 | 4976137 | 
| From LoopB | 7062816 | 6998097 | 5107799 | 
+------------+---------+---------+---------+ 

J'ai une connaissance très limitée de Progress 4GL. Est-ce que ce code semble trop fait? peut-il être plus simple?

Je viens de l'arrière-plan SQL. Donc, en SQL, je peux résoudre cela assez rapidement et facilement. Et ce que je veux dire par là, TOUT ce bloc de code de code fait simplement dire, dire "From LoopA" si NULL dans LoopB, autrement dit "from LoopB"

Voici l'équivalent SQL que je viens avec :

Select 
case when B.ID is null then 'From LoopA' 
else B.cTypeOfRec 
End "cTypeOfRec" 
, A.* 
from #TblTemp A 
left join (
    select A.*, 'From LoopB' "cTypeOfRec" from (select * from #TblTemp)A 
    left join (
     select B.Source, A.Report, B.ID from #TblA A 
     Inner join #TblB B 
     on B.Report=A.Report)B 
    on A.Source = B.Report 
    where B.Source is null) B 
on A.Report=B.Report 
and a.ID = b.ID 
and a.Source= b.Source 
order by A.Report 
, case when B.ID is null then 'From LoopA' 
else B.cTypeOfRec 
End 

tout conseiller du progrès gourou 4GL prendre un coup d'oeil sur le bloc de code 4GL ci-dessus et voir si elle est trop fait? peut-il être fait pour qu'il soit plus facile à suivre/à lire?

Mais je suis ouvert à toute réponse, si c'est la bonne façon de coder en 4GL pour atteindre le résultat final, alors je suis d'accord.

Merci Merci

Répondre

1

Vous semblez passer par tblA et TblB deux fois. Au lieu de cela, créez un TblTemp pour chaque TblB. Passez ensuite par TblA pour voir s'il correspond à un enregistrement TblTemp. Vous pouvez déplacer la logique de la table temporaire vers sa propre procédure.

def temp-table TblTemp no-undo 
field cTypeOfRec  as char 
field RptPltSeq  as int 
field SrcPltSeq  as int 
field ID    as int 
index key is unique primary RptPltSeq SrcPltSeq ID. 

define stream dOut1. 

run SOOptimize. 

procedure SOOptimize: 
    output stream dOut1 to value("OutPut.txt"). 
    export stream dOut1 delimiter "|" 
    "Report" 
    "Source" 
    "ID". 

    for each TblB no-lock: 
    run updateTempRec (input "From LoopB", input TblB.Source, input TblB.Report, input TblB.ID). 
    end. 

    for each TblA no-lock: 
    run updateTempRec (input "From LoopA", input TblA.Report, input TblA.Report, input 0).  
    end. 

    for each TblTemp no-lock: 
    export stream dOut1 delimiter "|" 
     TblTemp.  
    end. 
end procedure. 

procedure updateTempRec: 
    define input parameter pcType as character no-undo. 
    define input parameter piSrc as integer no-undo. 
    define input parameter piRpt as integer no-undo. 
    define input parameter piID as integer no-undo. 

    find first TblTemp where 
     TblTemp.SrcPltSeq = piSrc and 
     TblTemp.RptPltSeq = piRpt 
     no-error. 

    if available(TblTemp) then 
     TblTemp.cTypeOfRec = pcType. 
    else 
     if piID <> 0 then 
     do: 
     create TblTemp. 

     assign 
      TblTemp.cTypeOfRec = pcType 
      TblTemp.SrcPltSeq = piSrc  
      TblTemp.RptPltSeq = piRpt 
      TblTemp.ID   = piID. 
     end. 
end procedure. 
0

Vous pouvez écrire quelque chose comme

for each TblA no-lock, 
    each TblB no-lock where 
      TblB.Source = TblA.Report 
     or TblB.Report = TblA.Report 
      on error undo, return error on stop undo, return error: 
    /* ... */ 
end. 

Je ne sais pas si cela aide déjà, à savoir. si vous pouviez passer la table temporaire. Au moins pour un enregistrement TblA, vous ne devriez pas voir le même enregistrement TblB deux fois (ce qui se produirait autrement pour les enregistrements avec TblB.Source = TblB.Report). Si je remplace TblA.Report avec TblB.Source dans la première for each TblB et TblA.Report avec TblB.Report alors les seules différences semblent être TblTemp.cTypeOfRec et TblTemp.ID donc vous devriez être en mesure de raccourcir le code.