1

次のクエリを確認してください。SQLは見た目ほど悪くはありません。基本的に、ファクトテーブルといくつかのディメンションテーブルへのいくつかの単純な結合があります。次に、エイリアスACCOUNTS-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

ユーザーは、WebI(ビジネスインテリジェンス)レポートのフィルターに複数のCOST CENTERが含まれているため、「IN」に複数の値が含まれるSQLが生成されると、次のエラーが返されると不満を漏らしていました。

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

それ以外の場合、単一のCOST CENTERの場合、レポートは正常に機能しました。興味深いのは、次の結合条件(私には無関係に見える)がSQLに悪影響を及ぼしていることに気づいたことです

accounts_dim_dep.account_id = dw_mgr.fa_trans_fct.depreciation_account_id

ここでの問題は、左側の列accounts_dim_dep.account_idがデータベースでcharcharとして定義され、右側の列dw_mgr.fa_trans_fct.depreciation_account_idが数値として定義されていることです。

結合条件を変更して数値をvarcharに変換したとき...

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

... SQLは、フィルターで指定されているコストセンターの数に関係なく機能します。


一見無関係に見える1つの列の型の不一致が、INリストで複数のコストセンターを指定できるかどうかにどのように影響するかを知りたいです。

4

2 に答える 2

5

ORA-02063エラーは、ORA-01722エラーがリモート・データベースで発生したことを意味します。これは、(説明プランによると)RF_FND_FLEX_VALUES_DETテーブルがリモートであるという事実と一致します。

accounts_dim_dep.account_idはのエイリアスでありflex_value、varchar2のように見え、ほぼ確実に数値以外の値が含まれています。これを数値列と比較すると、Oracleは暗黙TO_NUMBER()を適用しますが、数値以外の値にヒットすると、ORA-01722で失敗します。文字列に変換 dw_mgr.fa_trans_fct.depreciation_account_idすることで、暗黙的な変換を回避できます。

では、コストセンターが1つしかない場合に元のクエリが成功するのに、複数ある場合は失敗するのはなぜですか?いくつかのテストを実行するためにデータにアクセスできない場合、または少なくとも異なるバージョンの計画を説明する必要がない場合、確信を持てません。しかし、公開したExplain Planは、リモート操作がRF_FND_FLEX_VALUES_DETから1行だけを取得することを示しています。flex_value複数のコストセンターでクエリを実行すると、数値以外の値を持つ行を含む、一握りの行が引き戻されると思います。

于 2009-10-07T00:48:10.080 に答える
3

PLWエラーを有効にしていた場合は、以前に状況が通知されていました。「タイプからの変換」エラーが発生していました。私はあなたの質問を書き直しました:

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'

変更ログ:

  • テーブルエイリアスを使用して入力を節約します(他の人が読みやすく、助けやすくなります)
  • 削除:hyperion_organizationは、同じ基準を使用した同じテーブルへの結合でした
  • TO_NUMBER(RF_FND_FLEX_VALUES_DET.flex_value)JOINの前に変換が行われるように指定されています

IN句の2+エントリでORAエラーが発生する理由はわかりませんが、投稿したものと同じものを2つ指定すると、データの問題になる可能性は低くなります。

于 2009-10-07T00:20:46.227 に答える