2009-11-11 13 views
7

ODP.Net udostępnia zdolność do przekazywania tablic asocjacyjnych jako parametrów do procedury składowanej Oracle z C#. Jest to dobra funkcja, chyba że próbujesz użyć danych zawartych w tej tablicy asocjacyjnej w zapytaniu sql.Jak korzystać z tablicy asocjacyjnej Oracle w zapytaniu SQL?

Powodem tego jest konieczność przełączenia kontekstu - instrukcje SQL wymagają typów SQL i tablic asocjacyjnych przekazanych do PL/SQL, tak jak jest to faktycznie zdefiniowane jako typ PL/SQL. Wierzę, że wszystkie typy zdefiniowane w pakiecie/procedurze/funkcji PL/SQL są typami PL/SQL, a typ tworzony poza tymi obiektami jest typem SQL (jeśli możesz zapewnić większą jasność, proszę, ale nie jest to celem tego pytanie).

Więc pytanie jest, jakie są metody należy użyć do konwersji PL/SQL asocjacyjna param do czegoś, co w ramach procedury mogą być stosowane w instrukcji SQL tak:

OPEN refCursor FOR 
SELECT T.* 
FROM SOME_TABLE T, 
     (SELECT COLUMN_VALUE V 
     FROM TABLE(associativeArray) 
     ) T2 
WHERE T.NAME = T2.V; 

Dla dla celów tego przykładu "asocjacyjna tablica" jest prostą tabelą varchar2 (200) indeksowaną przez PLS_INTEGER. W języku C# parametr associativeArry jest wypełniany ciągiem znaków [].

Zapraszam do dyskusji na temat innych sposobów na to, oprócz korzystania z tablicy asocjacyjnej, ale wiem z wyprzedzeniem, że te rozwiązania nie zostaną zaakceptowane. Nadal jestem zainteresowany widząc inne opcje.

+0

Zobacz tutaj podobny problem + podobnego rozwiązania: http://stackoverflow.com/questions/1625649/oracle- Parametry-w-wyciągu/1655743 # 1655743 – tuinstoel

Odpowiedz

11

Chciałbym utworzyć bazę danych tak:

create type v2t as table of varchar2(30); 
/

A potem w procedurze:

FOR i IN 1..associativeArray.COUNT LOOP 
    databaseArray.extend(1); 
    databaseArray(i) := associativeArray(i); 
END LOOP; 

OPEN refCursor FOR 
SELECT T.* 
FROM SOME_TABLE T, 
     (SELECT COLUMN_VALUE V 
     FROM TABLE(databaseArray) 
     ) T2 
WHERE T.NAME = T2.V; 

+0

Tak, to działa. – ScottCher

+4

Zdumiewające, ile jest przykładów użycia tablic asocjacyjnych w pętlach w celu uruchamiania wstawek i takich, ale nie, które dyskutują lub dostarczają przykładów bliższego przejścia problemu z przełączaniem kontekstu. Mam nadzieję, że będzie to pomocne także dla innych. – ScottCher

+0

Nie tworzy to tablicy asocjacyjnej - tworzy kolekcję. Zauważ również: 'asscoiativeArray.FIRST' może nie być' 1', a 'associativeArray.COUNT' i' associativeArray.LAST' mogą nie być równe (szczególnie jeśli tablica asocjacyjna jest rzadka). – MT0

1

(gdzie databaseArray jest uznane być typu V2T). Nie można używać tablic asocjacyjnych w zakresie SQL - są one użyteczne tylko w zakresie PL/SQL.

Jedną z metod jest mapowanie tablicy asocjacyjnej do kolekcji (która może być używana w zakresie SQL, jeśli typ kolekcji został zdefiniowany w zakresie SQL, a nie w zakresie PL/SQL).

SQL:

CREATE TYPE VARCHAR2_200_Array_Type AS TABLE OF VARCHAR2(200); 
/

PL/SQL

DECLARE 
    TYPE associativeArrayType IS TABLE OF VARCHAR2(200) INDEX BY PLS_INTEGER; 
    i    PLS_INTEGER; 
    associativeArray associativeArrayType; 
    array   VARCHAR2_200_Array_Type; 
    cur    SYS_REFCURSOR; 
BEGIN 
    -- Sample data in the (sparse) associative array 
    associativeArray(-2) := 'Test 1'; 
    associativeArray(0) := 'Test 2'; 
    associativeArray(7) := 'Test 3'; 

    -- Initialise the collection 
    array := VARCHAR2_200_Array_Type(); 

    -- Loop through the associative array 
    i := associativeArray.FIRST; 
    WHILE i IS NOT NULL LOOP 
    array.EXTEND(1); 
    array(array.COUNT) := associativeArray(i); 
    i := associativeArray.NEXT(i); 
    END LOOP; 

    -- Use the collection in a query 
    OPEN cur FOR 
    SELECT * 
    FROM your_table 
    WHERE your_column MEMBER OF array; 
END; 
/
Powiązane problemy