2017-08-08 1 views
1

Ich habe versucht, mit assoziativer Arrays einen Tisch auf der Karte, aber ich kann nicht herausfinden, wie esWie eine Matrix in plsql initialisieren

hier zu initialisieren ist ein Beispiel:

TYPE RecType IS RECORD 
(
    value1 NUMBER, 
    value2 NUMBER, 
    value3 NUMBER 
); 
TYPE TblType IS TABLE OF RecType INDEX BY PLS_INTEGER; 
TYPE TblOfTblType IS TABLE OF TblType INDEX BY PLS_INTEGER; 
matrix TblOfTblType; 

Jetzt als ich versuchte, die Matrix so zu initialisieren:

FOR i IN matrix.FIRST .. matrix.LAST LOOP 
    FOR j IN matrix (i).FIRST .. matrix (i).LAST LOOP 
     matrix(i)(j) := NULL; 
    END LOOP; 
END LOOP; 

Es funktioniert nicht, ich auch versucht

matrix := TblOfTblType()(); 

es zeigt die folgenden Fehler:

PLS-00363 Ausdruck 'Matrix' nicht als Zuweisungsziel verwendet werden kann.

+0

Dank für Ihre Antwort, können Sie mir bitte helfen, wie kann ich eine Matrix erstellen in Wie sollte meine Prozedur aussehen? – maryam

Antwort

4

Sie müssen kein assoziatives Array verwenden - eine Sammlung funktioniert.

DECLARE 
    TYPE RecType IS RECORD 
    (
    value1 NUMBER, 
    value2 NUMBER, 
    value3 NUMBER 
); 
    TYPE TblType IS TABLE OF RecType; 
    TYPE TblOfTblType IS TABLE OF TblType; 
    matrix TblOfTblType := TblOfTblType(); 
BEGIN 
    matrix.EXTEND(3); 
    FOR i IN 1 .. matrix.COUNT LOOP 
    matrix(i) := TblType(); 
    matrix(i).EXTEND(4); 
    FOR j IN 1 .. matrix(i).COUNT LOOP 
     matrix(i)(j).value1 := i; 
     matrix(i)(j).value2 := j; 
     matrix(i)(j).value3 := DBMS_RANDOM.VALUE; 
    END LOOP; 
    END LOOP; 

    FOR i IN 1 .. matrix.COUNT LOOP 
    FOR j IN 1 .. matrix(i).COUNT LOOP 
     DBMS_OUTPUT.PUT('[' || matrix(i)(j).value1 
        || ',' || matrix(i)(j).value2 
        || ',' || matrix(i)(j).value3 || ']' || CHR(11)); 
    END LOOP; 
    DBMS_OUTPUT.NEW_LINE; 
    END LOOP; 
END; 
/
+0

Können Sie bitte die Matrix drucken? – XING

+3

@XING Das OP fragt nur nach der Initialisierung der Matrix. Es ist jedoch einfach, DBMS_OUTPUT.PUT (matrix (i) (j) .value1) 'oder' DBMS_OUTPUT.PUT_LINE (matrix (i) (j) .value3) innerhalb eines anderen Satzes von Schleifen zu verwenden. – MT0

+0

Können Sie bitte versuchen, denn bevor ich meine Frage gestellt habe, habe ich Folgendes versucht: Für rec in 1..matrix.count Schleife für dbms_output.put_line (Matrix (rec) .value); Endschleife; – XING

3

Obwohl ich mit @ MTO Ansatz zustimmen, ist der Fehler aus der Schleife Ansatz, weil Sie FIRST und LAST auf eine leere Tabelle zu beziehen versuchen, und sie beide zu bewerten an diesem Punkt auf Null. Sie versuchen, effektiv zu tun:

FOR i IN null .. null LOOP 

, die die gleiche ORA-06502: PL/SQL: numeric or value error wie Ihre ursprüngliche FOR Schleife bekommt.

Sie haben nirgendwo definiert, wie groß die Matrix sein soll. Sie müssen das irgendwo tun, um es "initialisieren" zu können, z.B. mit festen Werten MTO zusammenzubringen und Ihre Art Erklärungen:

DECLARE 
    TYPE RecType IS RECORD 
    (
    value1 NUMBER, 
    value2 NUMBER, 
    value3 NUMBER 
); 
    TYPE TblType IS TABLE OF RecType INDEX BY PLS_INTEGER; 
    TYPE TblOfTblType IS TABLE OF TblType INDEX BY PLS_INTEGER; 
    matrix TblOfTblType; 
BEGIN 
    FOR i IN 1 .. 3 LOOP 
    FOR j IN 1 .. 4 LOOP 
     matrix(i)(j) := null; 
    END LOOP; 
    END LOOP; 
END; 
/

PL/SQL procedure successfully completed. 

mit Nicht-Null-Werte So zu füllen woudl benötigen Sie einen separaten Datensatz Variable, die Sie füllen und dann zuweisen tot er Position Matrix:

FOR i IN 1 .. 3 LOOP 
    FOR j IN 1 .. 4 LOOP 
     rec.value1 := i; 
     rec.value2 := j; 
     rec.value3 := DBMS_RANDOM.VALUE; 
     matrix(i)(j) := rec; 
    END LOOP; 
    END LOOP; 

Oder Sie können bestimmte Matrixelemente ohne Schleife gezielt ansprechen, wenn Sie diese Form woanders bekommen. Und Sie können es auf die gleiche Weise MTO auch zeigte, ausdrucken oder mit FIRST und LAST, die jetzt gültig:

FOR i IN matrix.FIRST .. matrix.LAST LOOP 
    FOR j IN matrix(i).FIRST .. matrix(i).LAST LOOP 
     DBMS_OUTPUT.PUT('[' || matrix(i)(j).value1 
        || ',' || matrix(i)(j).value2 
        || ',' || matrix(i)(j).value3 || ']' || CHR(11)); 
    END LOOP; 
    DBMS_OUTPUT.NEW_LINE; 
    END LOOP; 
+2

Wenn Sie 'FIRST' und' LAST' mit dem assoziativen Array verwenden, ist es besser, ein Sparse-Array anzunehmen und 'i: = matrix.FIRST; Während i ist nicht NULL LOOP 'Inhalt der Schleife' i: = Matrix.NEXT (i); END LOOP; 'anstelle einer 'FOR'-Schleife. – MT0

+1

Ja, ich gehe davon aus, dass es als OP initialisiert wurde, also ist es effektiv dicht. Wenn ein Element außerhalb der ursprünglichen 3x4-Bereiche hinzugefügt werden kann, ist etwas robusteres erforderlich. Die Ausgangsschleife, die Sie zu Ihrer Antwort hinzugefügt haben, funktioniert auch, aber Sie müssen prüfen, ob an jedem Punkt etwas vorhanden ist, wenn es spärlich sein kann. –

1
CREATE OR REPLACE TYPE RecType AS OBJECT (
    value1 NUMBER, 
    value2 NUMBER, 
    value3 NUMBER 
); 
/ 

CREATE OR REPLACE TYPE TblType IS TABLE OF RecType; 
/

CREATE OR REPLACE TYPE TblOfTblType IS TABLE OF TblType; 
/

DECLARE 
    matrix TblOfTblType; 
     rec1 RecType; 
     rec2 TblType; 
BEGIN 
    rec1 := RecType(1,2,3); 
    rec2 := TblType(rec1); 
    matrix := TblOfTblType(rec2); 
    dbms_output.put_line(matrix(1)(1).value2); 
END;