Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Ein Problem mit PL/SQL lösen

Dieses Thema im Forum "Oracle" wurde erstellt von vogste, 20 August 2014.

  1. vogste

    vogste Benutzer

    Hallo Leute,

    ich brauche mal wieder Euren Fachverstand. Ich habe folgende Problematik.
    Es gibt eine Tabelle Maschinen, Maschinen-Produkte, Maschinen-Prozesse, Maschinen-Positionen, Maschinen-Einbauten.
    Jede Maschine kann aus x Maschinen-Produkten sowie y Maschinen-Prozessen und z Maschinen-Positionen bestehen.
    Zu einem bestimmten Zeitpunkt werden x Maschinen-Produkte * z Maschinen-Positionen = Maschinen-Einbauten.
    Jetzt muss zur Analyse zu jeder Maschine die Anzahl der Maschinen-Produkte, Maschinen-Prozesse, Maschinen-Positonen und Maschinen-Einbauten ermittelt werden.
    Anschliessen sollen die erwarteten Maschinen-Einbauten mit den tatsächlich vorhandenen Einbauten verglichen werden.
    Wenn die Anzahl der erwarteten und tatsächlichen Einbauten gleich ist, ist alles i.O. ansonsten soll die Maschine rausgeschrieben werden.
    Jetzt hatte ich mal vor vielen Jahren einen Crashkurs PL/SQL, muss aber zu meiner Schande gestehen, dass wohl nichts, nicht viel hängen geblieben ist.
    Hier meine kläglichen Versuche als Pseudocode:

    Code:
    -- hier sollen die benötigen Variablen deklariert werden
    DECLARE
      -- variable nimmt maschinennummer auf
       v_line_id VARCHAR2(40);
      -- variable nimmt maschinenversion auf
       v_line_ver VARCHAR2(40);
      -- variable nimmt maschinencid auf
      v_line_cid NUMBER(10,0);
      -- array nimmt alle maschinencids auf
      TYPE a_line_cid IS TABLE OF V_LINE_CID NOT NULL
      INDEX BY NUMBER(10,0);
      -- variable nimmt weggesicherte maschinencid auf
       v_line_cid_save NUMBER(10,0);
      -- variable die die anzahl aller maschinen aufnimmt
       v_cnt_line NUMBER(10,0);
      -- variable die die anzahl der maschinen-produkt beziehung aufnimmt
       v_cnt_prop NUMBER(10,0);
      -- variable die die anzahl der maschinen-prozess beziehung aufnimmt
       v_cnt_mprc NUMBER(10,0);
      -- variable die die anzahl der maschinen-position beziehung aufnimmt
       v_cnt_poat NUMBER(10,0);
      -- variable die die anzahl der einbauten ermittelt
       v_cnt_mnt NUMBER(10,0);
      -- variable die zur berechnung der summer aller erwarteten einbauten aufnimmt
       v_cnt_sum NUMBER(10,0);
      -- variale als zaehler für die while-schleife
       v_cnt NUMBER(10,0) := 1;
    -- hier beginnt die eigentliche Verabeitung
    BEGIN
      -- zuerst zählen der möglichen Maschinen für die while-Schleife
       SELECT COUNT(c_id) INTO v_cnt_line FROM t_line_dat;
      -- jetzt holen alle maschinencids in ein array zum anschliessenden arbeiten in schleife
      SELECT c_id INTO a_line_cid FROM t_line_dat ORDER BY a_line_cid;
      -- die while-Schleife soll jetzt für jede Zeile des Blocks ausgeführt werden
       WHILE v_cnt <= v_cnt_line LOOP
        -- jetzt für die erste maschinencid die maschinen-produkt menge ermitteln
         SELECT COUNT(c_id) INTO v_cnt_prop FROM t_line_prop where c_id_1 = a_line_cid;
        -- jetzt für die erste maschinencid die maschinen-prositions menge ermitteln
      SELECT COUNT(c_id) INTO v_cnt_poat FROM t_line_poat where c_id_1 = a_line_cid;
        -- jetzt für die erste maschinencid die maschinen-einbauten menge ermitteln
      SELECT COUNT(c_id) INTO v_cnt_mnt FROM t_line_mnt where c_id_1 = a_line_cid;
      -- berechnen der erwarteten maschinen-einbauten   
      v_cnt_sum := v_cnt_prop * v_cnt_poat;
      /* hier fehlerbehandlung, wenn die erwartete anzahl einbauten von der
      tatsächlichen anzahl abweicht soll die maschinencid ausgegeben werden
      am besten in eine csv Datei*/
      IF v_cnt_sum <> v_cnt_mnt
      THEN v_line_cid_save := v_line_cid;
      END IF;
       -- Ende der while-Schleife
       END LOOP;
    -- Ende der Logik...
    END;
    -- ich bin am Ende, irgendwann mal was gelernt nie mehr gebraucht jetzt nix mehr verstehen
    
    Ich hoffe Ihr könnt mir helfen und mich wieder auf Spur bringen.

    Danke und Gruss
    Stephan
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Möglicherweise geht der ganze Zauber auch ganz simpel via SQL und vielleicht Views.

    Kannst Du mal Dein Problem auf ganz simple Tabellen mit einigen wenigen Datensätzen beschreiben?
     
  3. vogste

    vogste Benutzer

    Hallo Andreas,

    danke schon mal dafür, dass Du versuchst mir bei einer möglichen Lösung behilflich zu sein.

    Es gibt die eine Haupttabelle T_LINE_DAT (Maschinen), T_PROP_DAT (Produkte), T_POAT_DAT (Positionen), T_MNT_DAT (Einbauten).
    Diese Tabelle hat als Primärschlüssel die Spalte C_ID in der eine eindeutige 10stellige Zahl steht.

    Die Tabelle T_LINE_DAT verfügt zusätzlich über die Spalten LINE_ID und LINE_VERSION.
    Beispiel in T_LINE_DAT gibt es
    1. LINE_ID: 190568 mit LINE_VERSION (NULL)
    2. LINE_ID: 190568 mit LINE_VERSION A
    3. LINE_ID: 190568 mit LINE_VERSION B


    Es gibt die drei Nebentabellen T_PROP_DAT (Produkte), T_POAT_DAT (Positionen), T_MNT_DAT (Einbauten).
    Jede dieser Tabellen hat als Primärschlüssel die Spalte C_ID in der eine eindeutige 10stellige Zahl steht.


    Die Tabelle T_PROP_DAT verfügt zusätzlich über die Spalten PROD_ID und OPERATION
    1. PROD_ID: 16188 mit OPERATION 0815
    2. PROD_ID: 12525 mit OPERATION 321

    Die Tabelle T_POAT_DAT verfügt zusätzlich über die Spalten MODUL_ID und ATTRIBUT
    1. MODUL_ID: 001 mit ATTRIBUT: A 1/2
    2. MODUL_ID: 002 mit ATTRIBUT: B 2/3

    Die Tabelle T_MNT_DAT verfügt über die Spalten MOUNT_ID, BM, DESCR und SETTINGS
    1. MOUNT_ID: MNT-000001 mit BM: 789123 mit DESCR: blalba und SETTINGS: 123-789
    2. MOUNT_ID: MNT-000002 mit BM: 789123 mit DESCR: tattüt und SETTINGS: 124-789
    3. MOUNT_ID: MNT-000003 mit BM: 789123 mit DESCR: blatüt und SETTINGS: 987-123
    4. MOUNT_ID: MNT-000004 mit BM: 789123 mit DESCR: tütbla und SETTINGS: 987-123


    Zwischen der Haupttabelle T_LINE_DAT und den Nebentabellen T_PROP_DAT, T_POAT_DAT und T_MNT_DAT gibt es
    die vier Tabellen zu Beziehungsauflösung:

    T_LINE_PROP, T_LINE_POAT, T_LINE_MNT

    Jede dieser vier Tabellen beinhaltet drei Spalten


    C_ID, C_ID_1 und C_ID_2

    Jede dieser Tabellen hat als Primärschlüssel die Spalte C_ID in der eine eindeutige 10stellige Zahl steht.
    Die Spalte C_ID_1 beinhaltet die C_ID einer Zeile der Tabelle T_LINE_DAT und die Spalte C_ID_2 beinhaltet
    die C_ID des jeweiligen PRODUKTS, der jeweiligen Position oder des jeweiligen Einbaus.

    Alle Tabellen haben untereinander eine n:m - Beziehung.


    Zu einem bestimmten Zeitpunkt wird aus den Maschinen, mit versionseindeutigen Masch-Prod-Beziehungen und den

    versionseindeutigen Masch-Pos-Beziehungen durch multiplizieren das Produkt (Masch-Einbau-Beziehungen) gebildet.

    Dies hat zur Folge, dass wenn die Maschine eine neue Version bekommt, die Anzahl der Masch-Prod-Beziehungen und die Anzahl der
    Masch-Pos-Beziehungen und somit die Anzahl der Masch-Einbau-beziehungen variieren kann.

    Um dies zu überprüfen soll jetzt zu jeder Maschine die Anzahl Produkte, Positionen und Einbauten ermittelt werden und wenn es
    zwischen den Einbauten und dem Produkt aus Produkt und Position einen Unterschied gibt soll die Maschine mit C_ID, LINE_ID und
    LINE_VERSION, sowie Anzahl Produkt, Position und Einbau rausgeschrieben werden.

    Ich hoffe das war verständlich.


    Meine Anforderung:
    Zuerst alle Maschinen zählen.
    Dann alle Maschinen-CIDs in ARRAY schreiben.
    Danach je Maschine die Produkte, die Positionen und die Einbauten zählen.
    Abschliessend die Produkte mit den Positionen je Maschine multiplizieren und das Ergebnis mit der tatsächlichen Anzahl der Einbauten vergleichen.
    Wenn gleich i.O. sonst Maschinen C_ID, LINE_ID, LINE_VERSION, CNT-PROD, CNT-POS und CNT-MNT in Textfile schreiben.


    Danke nochmals für die Bemühungen.

    Gruss
    Stephan
     
  4. vogste

    vogste Benutzer

    Hallo an alle, die sich das Gehirn verrenkt haben.

    Ich habe mal ein Wochenende darüber geschlafen und alte Unterlagen gesichtet siehe da, ich habe mir geholfen. :)

    Hier die passende Lösung meines Problems

    Code:
    SET SERVEROUTPUT ON;
    DECLARE
    a_linecid NUMBER(10) := 0;
    b_linecid NUMBER(10) :=0;
    b_lineid  VARCHAR(40);
    b_linever VARCHAR(10);
    c_cntprop NUMBER (10) :=0;
    d_cntpoat NUMBER (10) :=0;
    e_cntmnt NUMBER (10) :=0;
    f_sumgen NUMBER (10) :=0;
    CURSOR c_cid IS
    SELECT distinct c_id, line_id, line_version
    FROM t_line_dat
    WHERE LEV_IND = 730
    ORDER BY line_id;
    BEGIN
      OPEN c_cid;
      LOOP
      FETCH c_cid INTO b_linecid, b_lineid, b_linever;
      SELECT COUNT(*) INTO c_cntprop FROM t_line_prop WHERE t_line_prop.c_id_1 = b_linecid;
      SELECT COUNT(*) INTO d_cntpoat FROM t_line_poat WHERE t_line_poat.c_id_1 = b_linecid;
      SELECT COUNT(*) INTO e_cntmnt FROM t_line_mnt WHERE t_line_mnt.c_id_1 = b_linecid;
      f_sumgen := c_cntprop * d_cntpoat;
      EXIT WHEN c_cid%NOTFOUND;
      IF f_sumgen <> e_cntmnt THEN
      DBMS_OUTPUT.PUT_LINE(b_lineid || ' ' || b_linever || ' ' || b_linecid || ' CNTPROP: ' || c_cntprop || ' CNTPOAT: ' || d_cntpoat || ' CNTMNT: ' || e_cntmnt || ' SUMGEN: ' || f_sumgen);
      END IF;
      END LOOP;
      CLOSE c_cid;
    END;
    
    Danke und Gruss
    Stephan
     
    akretschmer und Walter gefällt das.
  5. akretschmer

    akretschmer Datenbank-Guru

    Prima.

    Ich hab versucht da reinzusteigen, aber nicht so wirklich mit Erfolg.
     
  6. vogste

    vogste Benutzer

    Hey Andreas,

    danke Dir. Ja war auch ein Sche.... Thema. Zumal wenn man das jemandem erklären soll um dann punktgenau geholfen zu bekommen.

    Gruss
    Stephan
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden