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

SQLの一部をOracle関数に変換します

    取得しようとしているクエリ:

    SELECT id, split_function(city) FROM COMMA_SEPERATED
    

    ソース行ごとに複数の行を返そうとしているため、機能しません。残念ながら、それよりも少し複雑にする必要があります。

    分割メカニズムを非表示にすることが目標である場合、私が考えることができる最も近い方法は、文字列のコレクションを返す関数を作成することです。これは、パイプライン

    create or replace function split_function (p_string varchar2)
    return sys.odcivarchar2list pipelined as
    begin
      for r in (
        select result
        from xmltable (
          'if (contains($X,",")) then ora:tokenize($X,"\,") else $X'
          passing p_string as x
          columns result varchar2(4000) path '.'
        )
      )
      loop
        pipe row (trim(r.result));
      end loop;
    end split_function;
    /
    

    提案された呼び出しでは、コレクションを含むIDごとに1つの行が提供されます:

    select id, split_function(city) from comma_seperated;
    
            ID SPLIT_FUNCTION(CITY)
    ---------- -----------------------------------------------------------------
             1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
             2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
    

    これはあなたが望むものではありません。ただし、代わりにテーブルコレクション式と相互結合を使用して複数の行に変換できます:

    select cs.id, t.column_value as city
    from comma_seperated cs
    cross join table(split_function(cs.city)) t;
    
            ID CITY                          
    ---------- ------------------------------
             1 CHENNAI                       
             1 HYDERABAD                     
             1 JABALPUR                      
             2 BHOPAL                        
             2 PUNE                          
    

    db<>フィドルデモ

    これは思ったほど簡単ではありませんが、xmltable()に相互結合するよりも間違いなく優れています。 特に、その分割ロジック/関数を複数の場所で再利用したり、分割の実行方法の詳細を非表示にしたりする場合は、必要に応じてメカニズムを簡単に変更できます。より一般的な正規表現を使用して分割を実行します。



    1. /docker-entrypoint-initdb.d/db_init.shでpsqlコマンドを実行するとエラーが発生します(psql:サーバーに接続できませんでした:接続が拒否されました)

    2. SQLコマンドを使用してPostgresのmax_connectionsを変更する方法

    3. オフラインWebアプリケーションに2つの異なるデータベースを使用することは可能ですか?

    4. MySQL-文字列の長さでデータを選択する方法