Question

Veuillez consulter la requête suivante. Le SQL n'est pas aussi mauvais qu'il n'y paraît. Fondamentalement, nous avons une table de faits et quelques jointures simples à certaines tables de dimension. Ensuite, nous nous sommes jointes à un tableau dérivé, compte tenu de l'alias comptes-dim-dep

  SELECT dw_mgr.fa_trans_fct.period,
         dw_mgr.fa_trans_fct.asset_cost_company_code,
         dw_mgr.fa_trans_fct.asset_cost_center_id,
         dw_mgr.fa_trans_fct.depreciation_account_id,
         accounts_dim_dep.description, 
         dw_mgr.projects_dim.project_num,
         dw_mgr.projects_dim.project_name,
         ROUND (dw_mgr.fa_trans_fct.activity_deprn_amount_us, 2),
         organizations_cost.major_geography,
         organizations_cost.business_unit || organizations_cost.bu_desc,
         organizations_cost.industry_sector_num
              ||organizations_cost.industry_sector_desc,
         hyperion_organizations.hyperion_num,
         hyperion_organizations.hyperion_desc,
         hyperion_organizations.hyperion_reporting
    FROM dw_mgr.fa_trans_fct,
         (SELECT DISTINCT flex_value account_id, description
                     FROM rf_fnd_flex_values_det
                    WHERE flex_value_set_id = '1002363' 
                      AND summary_flag = 'N') accounts_dim_dep,
         dw_mgr.projects_dim,
         dw_mgr.organizations organizations_cost,
         dw_mgr.organizations hyperion_organizations
   WHERE 
         --Fact to Org on Company Code / Cost Center
         (dw_mgr.fa_trans_fct.asset_cost_center_id   
                                     = organizations_cost.cost_center_id)
     AND (dw_mgr.fa_trans_fct.asset_cost_company_code 
                                     = organizations_cost.company_code)
     --Fact to Projects Dim on Proj Num
     AND (dw_mgr.projects_dim.project_num = dw_mgr.fa_trans_fct.project_num)
     --Fact to Accounts_Dim_Dep on Account ID
     --convert account_ID on left to_number??????
     AND (accounts_dim_dep.account_id 
                            = dw_mgr.fa_trans_fct.depreciation_account_id) 
     --Fact Hyp Company Code Cost Center to Hyp Org
     AND (hyperion_organizations.cost_center_id 
                            = dw_mgr.fa_trans_fct.asset_cost_center_id AND
          hyperion_organizations.company_code  
                            = dw_mgr.fa_trans_fct.asset_cost_company_code)
   --Filters
     AND (
          dw_mgr.fa_trans_fct.period IN ('01-Jun-2009')
          --works
          --AND dw_mgr.fa_trans_fct.asset_cost_center_id IN ('000296') 
          --does not work               
          AND dw_mgr.fa_trans_fct.asset_cost_center_id IN ('000296','000296') 
          AND dw_mgr.fa_trans_fct.asset_cost_company_code = '0007'
         )



  ------------------------------------------------------------

  Statement Id=4203172   Type=
  Cost=2.64018716311899E-308  TimeStamp=06-10-09::17::51:43

       (1)  SELECT STATEMENT  CHOOSE 
     Est. Rows: 1  Cost: 6
       (14)  NESTED LOOPS 
     Est. Rows: 1  Cost: 6
           (11)  NESTED LOOPS 
                Est. Rows: 1  Cost: 5
               (9)  HASH JOIN 
                    Est. Rows: 1  Cost: 3
                   (3)  TABLE TABLE ACCESS BY INDEX ROWID DW_MGR.ORGANIZATIONS  [Analyzed] 
                   (3)   Blocks: 1,669 Est. Rows: 1 of 31,748  Cost: 1 
                        Tablespace: DIM_DATA
                       (2)  INDEX (UNIQUE) INDEX UNIQUE SCAN DW_MGR.ORG_PK  [Analyzed] 
                            Est. Rows: 1  Cost: 1
                   (8)  PARTITION RANGE SINGLE 
                        Est. Rows: 7  Cost: 1
                       (7)  PARTITION LIST ALL 
                            Est. Rows: 7  Cost: 1
                           (6)  TABLE TABLE ACCESS BY LOCAL INDEX ROWID DW_MGR.FA_TRANS_FCT  [Analyzed] 
                                Blocks: 1,431,026 Est. Rows: 7 of 32,900,663  Cost: 1
                               (5)  BITMAP CONVERSION TO ROWIDS
                                   (4)  INDEX (BITMAP) BITMAP INDEX SINGLE VALUE DW_MGR.FA_TRANS_AST_COMP_CC_BM_I
               (10)  REMOTE REMOTE.RF_FND_FLEX_VALUES_DET 
                    Est. Rows: 1  Cost: 2
           (13)  TABLE TABLE ACCESS BY INDEX ROWID DW_MGR.PROJECTS_DIM  [Analyzed] 
           (13)   Blocks: 12,184 Est. Rows: 1 of 163,117  Cost: 1 
                Tablespace: PROJECT_DATA
               (12)  INDEX (UNIQUE) INDEX UNIQUE SCAN DW_MGR.PROJECTS_UI  [Analyzed] 
                    Est. Rows: 1  Cost: 1

Les utilisateurs se plaignaient que lorsque leur rapport Webi (Business Intelligence) comprenait plusieurs centres de coûts dans leur filtre, résultant en un SQL avec un "in" incluent plusieurs valeurs, l'erreur suivante a été retournée:

   [1]: (Error): ORA-01722: invalid number ORA-02063: preceding line from [dbname]

Sinon, pour un centre à coût unique, le rapport a bien fonctionné. La partie intéressante est que j'ai remarqué que la condition de jointure suivante, qui pour moi apparaît Sans rapport, a eu un impact négatif sur le SQL:

accounts_dim_dep.account_id = dw_mgr.fa_trans_fct.depreciation_account_id

Le problème ici est que la colonne à gauche, accouts_dim_dep.account_id, est définie dans la base de données comme un charchar et le col à droite, dw_mgr.fa_trans_fct.depreciation_account_id, est défini comme un nombre.

Lorsque j'ai modifié la condition de jointure pour convertir le numéro en Varchar ...

accounts_dim_dep.account_id 
                       = to_char(dw_mgr.fa_trans_fct.depreciation_account_id)

... Le SQL fonctionne quel que soit le nombre de centres de coûts spécifiés dans le filtre.


J'aimerais savoir comment une incompatibilité de type sur une colonne apparemment non liée affecte la question de savoir si l'on peut spécifier plusieurs centres de coûts dans la liste IN.

Était-ce utile?

La solution

Si les erreurs PLW ont été activées, vous auriez été alerté de la situation plus tôt - vous auriez obtenu une erreur "Conversion loin du type". J'ai réécrit votre requête:

SELECT t.period,
       t.asset_cost_company_code,
       t.asset_cost_center_id,
       t.depreciation_account_id,
       add.description, 
       pd.project_num,
       pd.project_name,
       ROUND(t.activity_deprn_amount_us, 2),
       o.major_geography,
       o.business_unit || o.bu_desc,
       o.industry_sector_num || o.industry_sector_desc,
       o.hyperion_num,
       o.hyperion_desc,
       o.hyperion_reporting
  FROM DW_MGR.FA_TRANS_FCT t
  JOIN DW_MGR.PROJECTS_DIM pd ON pd.project_num = t.project_num
  JOIN DW_MGR.ORGANIZATIONS o ON o.cost_center_id = t.asset_cost_center_id
                             AND o.company_code = t.asset_cost_company_code
  JOIN (SELECT TO_NUMBER(rffvd.flex_value) 'account_id',
               rffvd.description
          FROM RF_FND_FLEX_VALUES_DET rffvd
         WHERE rffvd.flex_value_set_id = '1002363' 
           AND rffvd.summary_flag = 'N'
      GROUP BY rffvd.flex_value,
               rffvd.description) add ON add.account_id = t.depreciation_account_id
 WHERE t.period IN ('01-Jun-2009')
   AND t.asset_cost_center_id IN ('000296','000296') --doesn't work        
   AND t.asset_cost_company_code = '0007'

ChangeLog:

  • Gardez-vous un peu de frappe en utilisant des alias de table (permet également aux autres de lire et d'aider)
  • Supprimé: Hyperion_organisation était une jointure du même tableau, en utilisant les mêmes critères
  • Spécifié TO_NUMBER(RF_FND_FLEX_VALUES_DET.flex_value) La conversion se produit donc avant la jointure

Je ne sais pas pourquoi l'erreur ORA se produirait sur 2+ entrées dans la clause In, mais vous en fournissez deux de la même chose que vous avez publiée, alors ce n'est probablement pas un problème de données.

Autres conseils

L'erreur ORA-02063 signifie que l'erreur ORA-01722 se produit dans une base de données distante. Cela correspond au fait que (selon le plan d'explication), la table RF_FND_FLEX_VALUES_DET est distante.

La valeur accounts_dim_dep.account_id est un alias pour un flex_value, qui semble être un varchar2 et contient presque certainement des valeurs non nucères. Lorsque vous le comparez à une colonne numérique, Oracle applique un implicite TO_NUMBER() Pour cela, qui échoue avec l'ORA-01722 s'il atteint une valeur qui n'est pas un nombre. En convertissantdw_mgr.fa_trans_fct.depreciation_account_id À une chaîne, vous évitez la conversion implicite.

Alors pourquoi la requête d'origine réussit-elle alors que vous n'avez qu'un seul centre de coûts mais échoue quand vous en avez plusieurs? Sans avoir accès à vos données pour exécuter certains tests, ou à tout le moins les plans d'explication des différentes versions, il est difficile d'être sûr. Mais le plan Explication que vous avez publié montre que l'opération distante récupère une seule ligne de RF_FND_FLEX_VALUES_DET. Je suppose que lorsque vous exécutez la requête avec plusieurs centres de coûts, il tire une poignée de lignes, qui incluent certains où flex_value a une valeur non numérique.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top