Ein Problem mit PL/SQL lösen

vogste

Benutzer
Beiträge
23
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
 
Werbung:
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.

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?
 
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
 
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
 
Werbung:
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
 
Zurück
Oben