2009-06-15 7 views
6

Desidero scrivere un tipo di oggetto simile alla mappa in PL/SQL. Quello che intendo è un elenco di coppie chiave-valore, in cui un valore può essere un altro elenco di coppie chiave-valore. Semplice, o almeno così pensavo. Ecco i due semplificataTipo di oggetto simile alla mappa in PL/SQL?

CREATE OR REPLACE TYPE TKey AS OBJECT 
(
    name varchar2(240), 
    value_text varchar2(2000), 
    value_map TMap 
) 

CREATE OR REPLACE TYPE TMap AS TABLE OF TKey 

Forse non è così semplice, perché ora ho un "uovo o la gallina" -problema. Se inserisco TKey per primo, si lamenterà che TMap non è definito. Se inserisco per primo TMap, si lamenterà che TKey non è definito. Se inserisco TKey e ometto la riga value_map, quindi aggiungo il tipo TMap, quindi provo a sostituire il tipo TKey, non lo consentirà.

Sono sfortunato? Un tale costrutto non è possibile in PL/SQL?

Grazie in anticipo

Chiarimento: Quello che voglio è una cosa, che mi può dare a questo: Una mappa contenente i tasti A, B, e C. Il valore di a è il varchar "ciao", il valore di b è il "mondo" varchar, e il valore di c è un'altra mappa, con le chiavi x e y, e il valore di x è "ciò che è" e il valore di te è "su".

Questo è quello che sarebbe simile a Java:

Map<String, Object> map = new HashMap<String, Object>(); 
map.set("a", "Hello"); 
map.set("b", "World"); 
Map<String, Object> child = new HashMap<String, Object>(); 
child.set("x", "What's"); 
child.set("y", "up"); 
map.set("c", child); 

Ora so che qualcosa come "oggetto", come essere in grado di memorizzare qualsiasi cosa non è possibile. Quello di cui ho bisogno è un oggetto in grado di memorizzare un elenco di oggetti dello stesso tipo di questo oggetto. Quindi fondamentalmente, un albero, sì.

risposta

4

Forse è necessario pensare più relazionalmente :)

Invece di memorizzare una TMap (value_map) all'interno del tipo TKey, è sufficiente memorizzare value_map_name, che può quindi essere utilizzato per cercare un'altra voce nella tabella.

CREATE OR REPLACE TYPE TKey AS OBJECT(
name varchar2(240), 
value_text varchar2(2000), 
value_map_name varchar2(240)); 

Quindi è possibile utilizzare gli array associativi (come per la risposta di mamboking) per memorizzarli.

+0

Penso che tu abbia ragione, sono probabilmente sulla strada sbagliata qui, tutto insieme. –

11

È possibile utilizzare gli array associativi. Dal/SQL guida utente PL:

Understanding Associative Array (N-By Tables)

array associativi sono insiemi di coppie di valori-chiave, dove ogni tasto è unico ed è utilizzato per individuare un valore corrispondente nella array. La chiave può essere un numero intero o una stringa.

Assegnare un valore utilizzando un tasto per la prima volta aggiunge quella chiave all'array associativo. Le assegnazioni successive utilizzando la stessa chiave aggiornano la stessa voce. È importante scegliere una chiave che sia unica. Ad esempio, i valori chiave potrebbero provenire dalla chiave primaria di una tabella di database, da una funzione di hash numerica o dalla concatenazione di stringhe per formare un valore di stringa univoco.

Per esempio, qui è la dichiarazione di un tipo di array associativo, e due array di quel tipo, utilizzando le chiavi che sono stringhe:

Esempio 5-1 Tipi Collection Dichiarare

DECLARE TYPE population_type IS TABLE OF NUMBER INDEX BY VARCHAR2(64); 
    country_population population_type; 
    continent_population population_type; 
    howmany NUMBER; 
    which VARCHAR2(64); 
BEGIN 
    country_population('Greenland') := 100000; -- Creates new entry 
    country_population('Iceland') := 750000; -- Creates new entry 
-- Looks up value associated with a string 
    howmany := country_population('Greenland'); 
    continent_population('Australia') := 30000000; 
    continent_population('Antarctica') := 1000; -- Creates new entry 
    continent_population('Antarctica') := 1001; -- Replaces previous value 
-- Returns 'Antarctica' as that comes first alphabetically. 
    which := continent_population.FIRST; 
-- Returns 'Australia' as that comes last alphabetically. which := continent_population.LAST; 
-- Returns the value corresponding to the last key, in this 
-- case the population of Australia. 
    howmany := continent_population(continent_population.LAST); 
END; 
/
+0

Questo non è lo stesso problema. Il mio problema è la struttura gerarchica. Quello che mi serve è una mappa con un tipo di valore fisso ma due, uno dei quali è una mappa figlio. In altre parole, voglio memorizzare una mappa in una mappa. –

+1

@Callash, vuoi un albero? – tuinstoel

+0

@tuinstoel vedi chiarimenti sopra. –

1

Si sta provando a spremere un paradigma valore-chiave in un DBMS relazionale che non ha senso logico.Sarebbe molto più semplice diventare puro relazionale:

CREATE TABLE key_value AS 
(
    key varchar2(240),  -- PRIMARY KEY 
    value_text varchar2(2000) 
); 

CREATE TABLE key_hierarchy AS 
(
    child_key varchar2(240), -- PRIMARY KEY, FOREIGN KEY to key_value.key 
    parent_key varchar2(240) -- FOREIGN KEY to key_value.key 
); 

E questo è tutto! Se vuoi cambiare in seguito che un bambino può avere molti genitori, basta modificare il vincolo PK (bellezza dei DBMS relazionali)

+1

Non hai ottenuto il pb, vuole un tipo, non le tabelle. Poteva usare questa struttura per chiamare un SP, per esempio. –