sql >> データベース >  >> RDS >> Oracle

関数を使用してOracleでアカウントの詳細を取得する

    問題の説明が少し混乱しているようです。質問をフォーマットして、読みやすくしてください。とにかく解決策は簡単です。 ifが1つだけ必要です ステートメント。レベルに応じて、最初または2番目のテーブルと適切な列を検索します。

    create or replace function get_accountdetails (par_input in varchar2) return varchar2 is
      v_aid varchar2(10);
      v_db  varchar2(10);
      v_lvl varchar2(10);
      v_ret varchar2(20) := '';
    begin
      v_aid := regexp_substr(par_input, '\d+', 1, 1);
      v_db  := regexp_substr(par_input, '\d+', 1, 2);
      v_lvl := regexp_substr(par_input, '\d+', 1, 3);
    
      if v_lvl = 1 then
         select dim_cust_key
           into v_ret
           from dim_cust_acnt
           where level1_account_id = v_aid and database_id = v_db;
      elsif v_lvl = 2 then
         select dim_cust_key
           into v_ret
           from dim_cust_dept
           where level2_account_id = v_aid and database_id = v_db;
      else
         select dim_cust_key
           into v_ret
           from dim_cust_dept
           where level3_account_id = v_aid and database_id = v_db;
      end if;
      return v_ret;
    end;
    

    表とサンプル関数呼び出しは次のとおりです。

    create table dim_cust_acnt (dim_cust_key, level1_account_id, database_id) as (
        select 1123, 112, 22 from dual union all
        select 1234, 113, 23 from dual );
    
    create table dim_cust_dept (dim_cust_key, level2_account_id, level3_account_id, database_id) as (
        select 1587, 245, 301, 21 from dual union all
        select 1576, 289, 304, 20 from dual);
    
    select get_accountdetails('[112].[22].[1]') from dual;     -- result: 1123
    select get_accountdetails('[289].[20].[2]') from dual;     -- result: 1576
    select get_accountdetails('[301].[21].[3]') from dual;     -- result: 1587
    

    実際のデータにある適切な列名を使用し、必要に応じて変数の型と長さを調整してください。以下のような特別な関数を必要とせずに、1つの結合クエリを使用することもできると思います。 full joinを使用しました 、例に一致する行が含まれていないためです。おそらく単純なjoin 十分になります。

    with t(par_input) as (select '[112].[22].[1]' from dual)
    select dim_cust_key
      from dim_cust_acnt a
      full join dim_cust_dept d using (dim_cust_key) 
      cross join t
      where ( 1 = regexp_substr(par_input, '\d+', 1, 3)  
              and regexp_substr(par_input, '\d+', 1, 1) = level1_account_id 
              and regexp_substr(par_input, '\d+', 1, 2) = a.database_id )
         or ( 2 = regexp_substr(par_input, '\d+', 1, 3)  
              and regexp_substr(par_input, '\d+', 1, 1) = level2_account_id 
              and regexp_substr(par_input, '\d+', 1, 2) = d.database_id )
         or ( 3 = regexp_substr(par_input, '\d+', 1, 3)  
              and regexp_substr(par_input, '\d+', 1, 1) = level3_account_id 
              and regexp_substr(par_input, '\d+', 1, 2) = d.database_id )
    

    結果:

    DIM_CUST_KEY
    ------------
            1123
    

    withを削除した場合 およびcross join パーツを追加し、intoに追加します 句を使用すると、ifの代わりにこのクエリを関数で使用できます ステートメント。

    編集:

    遅れて申し訳ありませんが、最近StackOverflowを見ていません。関数の記述方法の2つの例を次に示します。

    この関数は連結された文字列を返します:

    select get_details_1('[112].[22].[1],[289].[20].[2],[301].[21].[3]') as list from dual;
    
    LIST
    ------------------
    1123,1576,1587
    

    また、2番目の関数はパイプライン化され、事前定義された文字列の集合としてデータを返すため、値は別々の行にあります。

    select column_value 
      from table(get_details_2('[112].[22].[1],[289].[20].[2],[301].[21].[3]'));
    
    COLUMN_VALUE
    ------------
            1123
            1576
            1587
    

    また、最初にすべての入力データを解析し、それらをいくつかのコレクションに格納してから、1つのクエリで一括収集を使用することもできます。多くの解決策と可能性があります。個人的にはパイプライン関数を使用しますが、必要な出力の形式(コレクションまたは連結文字列)によって異なります。また、begin ... endを追加することもできます 例外when no_data_foundをブロックして処理します 。その後、特別な情報を提示したり、実行を中断したりできます。これは、そのような状況で予想される動作によって異なります。

    機能1:

    create or replace function get_details_1 (par_input in varchar2) return varchar2 is
        v_aid varchar2(10);
        v_db  varchar2(10);
        v_lvl varchar2(10);
        v_ret varchar2(20);
        v_all varchar2(200) := '';
    
        i_cnt int := 0;
    begin
        loop
            v_aid := regexp_substr(par_input, '\d+', 1, i_cnt + 1);
            v_db  := regexp_substr(par_input, '\d+', 1, i_cnt + 2);
            v_lvl := regexp_substr(par_input, '\d+', 1, i_cnt + 3);
            i_cnt := i_cnt + 3;
        exit when v_aid is null;
            select dim_cust_key
              into v_ret
              from dim_cust_acnt a
              full join dim_cust_dept d using (dim_cust_key)
              where (v_lvl = 1 and level1_account_id = v_aid and a.database_id = v_db)
                 or (v_lvl = 2 and level2_account_id = v_aid and d.database_id = v_db)
                 or (v_lvl = 3 and level3_account_id = v_aid and d.database_id = v_db);
           v_all := v_all||','||v_ret;
      end loop;
      return ltrim(v_all, ',');
    end;
    

    機能2:

    create or replace function get_details_2 (par_input in varchar2) 
        return sys.odcinumberlist pipelined is
    
        v_aid varchar2(10);
        v_db  varchar2(10);
        v_lvl varchar2(10);
        v_ret varchar2(20);
        i_cnt int := 0;
    begin
        loop
            v_aid := regexp_substr(par_input, '\d+', 1, i_cnt + 1);
            v_db  := regexp_substr(par_input, '\d+', 1, i_cnt + 2);
            v_lvl := regexp_substr(par_input, '\d+', 1, i_cnt + 3);
            i_cnt := i_cnt + 3;
        exit when v_aid is null;
            select dim_cust_key
              into v_ret
              from dim_cust_acnt a
              full join dim_cust_dept d using (dim_cust_key)
              where (v_lvl = 1 and level1_account_id = v_aid and a.database_id = v_db)
                 or (v_lvl = 2 and level2_account_id = v_aid and d.database_id = v_db)
                 or (v_lvl = 3 and level3_account_id = v_aid and d.database_id = v_db);
           pipe row (v_ret);
      end loop;
      return;
    end;
    



    1. PhalconPHPデータベーストランザクションがサーバーで失敗する

    2. ノード js 用の db-oracle をインストールします。

    3. Createステートメントを使用してSQLServerでテーブルを作成する-SQLServer/T-SQLチュートリアルパート34

    4. SQLステートメントですべてのパラメーターが使用されたわけではありません(Python、MySQL)