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

sys_refcursorを出力するためのレコードのコレクション

    formDataを想定 テーブル構造は固定されており、既知です。case式を使用してformOption.fNameを変換できます。 一致する列の値に:

    select fo.fieldLabel as label,
      case fo.fieldName
        when 'fName' then fd.fName
        when 'lName' then fd.lName
        when 'nName' then fd.mName
      end as value
    from formData fd
    join fieldOptions fo
    on fo.formType = fd.formtype
    where fd.id = 3;
    
    LABEL                VALUE               
    -------------------- --------------------
    First                Frank               
    Surname              Peterson            
    Middle Initial                           
    
    ...
    where fd.id = 3;
    
    LABEL                VALUE               
    -------------------- --------------------
    First Name           Bob                 
    Last Name            Smith               
    Middle                                   
    

    次に、ID値の引数値を使用して、プロシージャでそのクエリの参照カーソルを開くことができます。

    formDataの場合 構造が不明であるか、静的でない場合は、おそらくより大きな問題が発生します。ただし、このためには、動的SQLにフォールバックする必要があります。出発点として、次のようなことができます。

    create procedure p42 (p_id number, p_refcursor out sys_refcursor) as
      l_stmt varchar2(32767);
    begin
      l_stmt := 'select fo.fieldLabel as label, case lower(fo.fieldName) ';
      for r in (
        select column_name from user_tab_columns
        where table_name = 'FORMDATA'
        and data_type = 'VARCHAR2'
      )
      loop
        l_stmt := l_stmt || ' when ''' || lower(r.column_name) || ''' then fd.' || r.column_name;
      end loop;
      l_stmt := l_stmt || ' end as value '
        || 'from formData fd '
        || 'join fieldOptions fo '
        || 'on fo.formType = fd.formtype '
        || 'where fd.id = :d1';
      open p_refcursor for l_stmt using p_id;
    end p42;
    /
    

    これは、テーブルで実際に定義されているすべての列を使用して、実行時にケース式を作成します。 fieldNameの場合 データディクショナリと一致しない可能性があるため、比較のためにすべてを小文字に強制しています。また、大文字と小文字を区別するために文字列列に制限していますが、他のデータ型の列が必要な場合は、各when ... then ケース式の句では、その列のデータ型をチェックする必要があります(rに追加できます)。 カーソル)を選択し、実際の列の値を適切に文字列に変換します。すべての値は同じデータ型になる必要があるため、実際には文字列である必要があります。

    とにかく、SQL * Plusからこれをテストします:

    var rc refcursor
    exec p42(1, :rc);
    
    PL/SQL procedure successfully completed.
    
    print rc
    
    LABEL                VALUE
    -------------------- --------------------
    First Name           Bob
    Last Name            Smith
    Middle
    
    3 rows selected.
    

    fieldOptionsをクエリできます 代わりに可能な列名を取得しますが、それでもデータ型変換の問題が発生する可能性があり、対処が難しくなります。ただし、参照されているすべてのformData フィールドは実際には文字列であるため、次のようになります。

      for r in (
        select fo.fieldName
        from formData fd
        join fieldOptions fo
        on fo.formType = fd.formtype
        where fd.id = p_id
      )
      loop
        l_stmt := l_stmt || ' when ''' || r.fieldName || ''' then fd.' || r.fieldName;
      end loop;
    


    1. 他の 2 つの属性から Oracle データベースに新しい属性を作成する

    2. Oracle 11gでは、2つの日付の間で1時間ごとに重量平均データをどのように計測しますか?

    3. Laravelは親行を削除または更新できません:外部キー制約が失敗します

    4. テーブルに存在しない値を検索する