sql >> Database teknologi >  >> RDS >> Oracle

samling af poster til ud sys_refcursor

Forudsat din formData tabelstrukturen er fast og kendt, du kan bare bruge et kasusudtryk til at oversætte formOption.fName til den matchende kolonneværdi:

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 derefter få din procedure til at åbne en ref-markør for den forespørgsel ved at bruge en argumentværdi for ID-værdien.

Hvis formData struktur er ikke kendt, eller er ikke statisk, så har du sandsynligvis større problemer; men for dette skal du falde tilbage til dynamisk SQL. Som udgangspunkt kunne du gøre noget 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;
/

Dette bruger alle de kolonner, der faktisk er defineret i tabellen, til at skabe sagsudtrykket under kørsel; fordi tilfældet med dit fieldName passer muligvis ikke til dataordbogen, jeg tvinger alt til små bogstaver til sammenligning. Jeg begrænser mig også til strengkolonner for at gøre sagen enklere, men hvis du har brug for kolonner, der er andre datatyper, så hver when ... then klausulen i kasusudtrykkene skal kontrollere kolonnens datatype (som du kan tilføje til r markør) og konverter den faktiske kolonneværdi til en streng korrekt. Alle værdier skal ende med den samme datatype, så det skal virkelig være strenge.

I hvert fald, tester dette fra 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 forespørge fieldOptions for at få de mulige kolonnenavne i stedet, men du kan stadig have datatypekonverteringsproblemet, som ville være sværere at håndtere; men hvis alle de refererede formData felter er faktisk strenge, så ville det være:

  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. Brug af en variabel i Ruby Mysql-forespørgsel

  2. Indkodning af SQL_Latin1_General_CP1_CI_AS til UTF-8

  3. Sådan fungerer UNIX_TIMESTAMP() i MariaDB

  4. Forbindelsesadgang nægtet for brugeren www-data