sql >> Databasteknik >  >> RDS >> Oracle

samling av poster till ut sys_refcursor

Förutsatt din formData tabellstrukturen är fixerad och känd, du kan bara använda ett kasusuttryck för att översätta formOption.fName till det matchande kolumnvärdet:

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                                   

Du kan sedan låta din procedur öppna en ref-markör för den frågan med ett argumentvärde för ID-värdet.

Om formData struktur är inte känd, eller är inte statisk, då har du förmodligen större problem; men för detta måste du falla tillbaka till dynamisk SQL. Som utgångspunkt kan du göra något som:

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;
/

Detta använder alla kolumner som faktiskt definieras i tabellen för att skapa falluttrycket vid körning; eftersom fallet med ditt fieldName kanske inte matchar dataordboken, jag tvingar allt att ge små bokstäver för jämförelse. Jag begränsar mig också till strängkolumner för att göra fallet enklare, men om du behöver kolumner som är andra datatyper så är var och en when ... then satsen i kasusuttrycken skulle behöva kontrollera kolumnens datatyp (som du kan lägga till i r markören) och konvertera det faktiska kolumnvärdet till en sträng på lämpligt sätt. Alla värden måste hamna i samma datatyp, så det måste verkligen vara strängar.

Hur som helst, testar detta från 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.

Du kan fråga fieldOptions för att få de möjliga kolumnnamnen istället, men du kan fortfarande ha problem med datatypskonvertering, vilket skulle vara svårare att hantera; men om alla refererade formData fält är faktiskt strängar då det skulle vara:

  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. PostgreSQL - Hur ser man funktionstext/källa i pgAdmin?

  2. Behöver skapa en utlösare som ökar ett värde i en tabell efter infogning

  3. MySQL Storage Engine Optimization:Konfigurera InnoDB-optimering för hög prestanda

  4. Hur man får radnummer i MySQL