2017-06-19 2 views
2

Je convertis mon application DB d'oracle en postgres. Je suis bloqué sur une fonction ayant se connecter par syntaxe. Voici la requête Oracle.Comment convertir les requêtes ci-dessous d'Oracle à Postgres ayant se connecter?

PROCEDURE Get_Report_Data(parm_Billing_Month VARCHAR2, OUT Ref_Cur) IS 
BEGIN 
OPEN p_Data FOR 
    SELECT CASE 
      WHEN Id = 1 THEN 
      'Amount < 10000' 
      WHEN Id = 2 THEN 
      '10000-15000' 
      WHEN Id = 3 THEN 
      '15000-20000' 
      ELSE 
      'Amount > 20000' 
     END "Range", 
     SUM(Nvl(N1, 0)) N1, 
     SUM(Nvl(N2, 0)) N2, 
     SUM(Nvl(C1, 0)) C1, 
     SUM(Nvl(C2, 0)) C2, 
     SUM(Nvl(C3, 0)) C3, 
     SUM(Nvl(S1, 0)) S1, 
     SUM(Nvl(S2, 0)) S2, 
     COUNT(Site_Id) "No of Sites" 
    FROM (SELECT CASE 
        WHEN Nvl(Ed.Actual_Bill, 0) < 10000 THEN 
        1 
        WHEN Ed.Actual_Bill < 15000 THEN 
        2 
        WHEN Ed.Actual_Bill < 20000 THEN 
        3 
        ELSE 
        4 
       END Amount_Sort, 
       Decode(Er.Region_Id, 1, 1, 0) N1, 
       Decode(Er.Region_Id, 2, 1, 0) N2, 
       Decode(Er.Region_Id, 3, 1, 0) C1, 
       Decode(Er.Region_Id, 4, 1, 0) C2, 
       Decode(Er.Region_Id, 5, 1, 0) C3, 
       Decode(Er.Region_Id, 6, 1, 0) S1, 
       Decode(Er.Region_Id, 7, 1, 0) S2, 
       Ed.Site_Id 
      FROM Tbl_Details Ed, 
       Tbl_Site  Es, 
       Tbl_Region Er, 
       Tbl_Subregion Esr 
      WHERE Ed.Site_Id = Es.Site_Id 
      AND Es.Subregion_Id = Esr.Subregion_Id 
      AND Esr.Region_Id = Er.Region_Id 
      AND Ed.Billing_Month_f = parm_Billing_Month) Data, 
     (SELECT Regexp_Substr('1,2,3,4,', '[^,]+', 1, Rownum) Id 
      FROM Dual 
      CONNECT BY Rownum <= Length('1,2,3,4,') - 
        Length(REPLACE('1,2,3,4,', ','))) All_Value 
    WHERE Data.Amount_Sort(+) = All_Value.Id 
    GROUP BY All_Value.Id 
    ORDER BY AVG(All_Value.Id); 
END; 

Lorsque je convertir cette requête postgre avoir quelques changements comme Ref_Cur à refcursor et NVL à Coalesce fonction. Je suis toujours incapable de résoudre la connexion par syntaxe. Certaines personnes ont suggéré d'utiliser CTE, mais je suis incapable de l'obtenir. Toute aide les gars?

Modifier Pour les googlers aléatoires ci-dessous est la réponse à mon problème ci-dessus. Un merci spécial au MTO.

WHERE Ed.Site_Id = Es.Site_Id 
AND Es.Subregion_Id = Esr.Subregion_Id 
AND Esr.Region_Id = Er.Region_Id 
AND Ed.Billing_Month_f = p_Billing_Month) data 

Right Outer Join (Select 1 as Id union All 
        Select 2 as Id union All 
        Select 3 as Id union All 
        Select 4 as Id) all_value 
      On data.Amount_Sort = all_value.Id 
GROUP BY all_value.Id 
ORDER BY AVG(all_value.Id); 

Répondre

2

Étant donné que votre requête hiérarchique semble utiliser des chaînes statiques, vous pouvez convertir ceci:

SELECT Regexp_Substr('1,2,3,4,', '[^,]+', 1, Rownum) Id 
FROM Dual 
CONNECT BY Rownum <= Length('1,2,3,4,') - Length(REPLACE('1,2,3,4,', ',') 

Pour:

SELECT 1 AS id FROM DUAL UNION ALL 
SELECT 2 FROM DUAL UNION ALL 
SELECT 3 FROM DUAL UNION ALL 
SELECT 4 FROM DUAL 

qui devrait alors être plus simple de se convertir à PostgreSQL.

+2

Merci beaucoup. Très belle et simple réponse. –

3

La "génération" d'ID peut être simplifiée dans Postgres.

soit utiliser une clause values():

Right Outer Join (values (1,2,3,4)) as all_value(id) On data.Amount_Sort = all_value.Id 

ou, si ceux-ci sont toujours un consécutifs numéros, utilisez generate_series():

Right Outer Join generate_series(1,4) as all_value(id) On data.Amount_Sort = all_value.Id 
+2

En fait, dans mes prochains rapports, il y a une requête complexe qui retourne des nombres. Donc j'ai simplement besoin de cette syntaxe fournie par le MTO. Mais merci beaucoup pour l'info. –

+0

@ Meta-Coder: Personnellement, je trouve la clause 'values ​​()' beaucoup plus simple à lire et à maintenir que la syntaxe 'select .. union tout select ...' alambiquée –

+2

Je suis totalement d'accord avec vous. Même dans mon rapport, j'ai utilisé la clause values ​​(1,2,3,4), mais dans mes prochains rapports j'ai besoin d'une requête complexe ayant plusieurs jointures. Cela me déroutait pour la syntaxe avec Connect by. À votre santé !!! –