Oracle
 sql >> Baza danych >  >> RDS >> Oracle

zbieranie rekordów do out sys_refcursor

Zakładając, że Twoje formData struktura tabeli jest stała i znana, możesz po prostu użyć wyrażenia case, aby przetłumaczyć formOption.fName do pasującej wartości kolumny:

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                                   

Następnie możesz zlecić swojej procedurze otwarcie kursora ref dla tego zapytania, używając wartości argumentu dla wartości identyfikatora.

Jeśli formData struktura nie jest znana lub nie jest statyczna, to prawdopodobnie masz większe problemy; ale w tym celu musiałbyś wrócić do dynamicznego SQL. Na początek możesz zrobić coś takiego:

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

Powoduje to użycie wszystkich kolumn faktycznie zdefiniowanych w tabeli do utworzenia wyrażenia przypadku w czasie wykonywania; ponieważ przypadek Twojego fieldName może nie pasować do słownika danych, zmuszam wszystko do małych liter dla porównania. Ograniczam się również do kolumn ciągów, aby uprościć sprawę, ale jeśli potrzebujesz kolumn, które są innymi typami danych, to każdy when ... then klauzula wyrażeń case będzie musiała sprawdzić typ danych tej kolumny (który można dodać do r kursor) i odpowiednio przekonwertuj rzeczywistą wartość kolumny na ciąg. Wszystkie wartości muszą kończyć się tym samym typem danych, więc tak naprawdę muszą to być łańcuchy.

W każdym razie, testując to z 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.

Możesz zapytać fieldOptions aby zamiast tego uzyskać możliwe nazwy kolumn, ale nadal możesz mieć problem z konwersją typu danych, który byłby trudniejszy do rozwiązania; ale jeśli wszystkie przywołane formData pola są w rzeczywistości ciągami, wtedy byłoby to:

  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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Konwertuj kolumny na wiersze w SQL

  2. Błąd podczas łączenia z Oracle. Uzyskiwanie błędu UnsatisfiedLinkError dla metody t2cGetCharSet

  3. Oracle PL/SQL:Pomóż w rozwiązaniu PLS-00103:Napotkano symbol LOOP, oczekując jednej z następujących sytuacji:jeśli

  4. Pobieranie rzędów z bardzo dużą prędkością

  5. Lista elementów formatu daty i godziny w Oracle