Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   SQL Vereinfachen (https://www.delphipraxis.net/166523-sql-vereinfachen.html)

Medium 16. Feb 2012 15:06

Datenbank: MySQL • Version: 4.1.9 • Zugriff über: UnIDAC

SQL Vereinfachen
 
Spätmahlzeit.

Ich habe folgendes Szenario:
In meiner DB habe ich eine Produktionsanlage abgebildet, von der der hier wesentliche Teil eine Menge von Behältern ist. Diese Behälter können Quellen und/oder Ziele für andere Behälter sein, was durch die Verrohrung vorbestimmt ist. Einige Behälter beinhalten Rohstoffe.
Der Anlagenbediener kann sich aus diesen Rohstoffen ein Rezept nach Belieben anfertigen, und der Anlage dann zur vollautomatischen Produktion vorgeben. Ich möchte bei der Vorgabe eines Rezeptes einen Auswahldialog haben, der mir anzeigt, welche Zielbehälter von allen Quellbehältern erreicht werden können, die die dort angegebenen Rohstoffe beinhalten.

Tabellen (nur die relevanten Felder):
beh (Behälterdaten)
- id (autoinc)
- Behälternummer
- Behältername
- Rohstoff (im Behälter)

qundz (Quellen und Ziele - Kreuztabelle der Behälternummern aus "beh" untereinander, gibt an wer wen wie direkt erreichen kann)
- id (autoinc)
- Quelle
- Ziel

rezpos (Rezeptpositionen aller Rezepte. Die mit typ=1 sind Dosier-Angaben (es gibt noch andere, die hier aber keine Rolle spielen sollen))
- id (autoinc)
- Rezeptnummer
- Typ
- Rohstoff

Es gibt also z.B. ein Rezept, in das soll Wasser, Wein und Orangensaft. Ich möchte nun alle Zielbehälter ermitteln, die Quellbehälter direkt angeschlossen haben, in denen alle 3 Rohstoffe vorhanden sind. Sprich die Behälter, in denen das Rezept angefertigt werden kann. Behälternummer und Behältername.

Im Moment mache ich das so:
Code:
SELECT k.ziel, e.name FROM
  (SELECT COUNT(z.id) qcount, z.ziel FROM                                                                // Zähle die erfüllbaren Dosierpositionen für alle Ziele, die von den beteiligten Quellbehältern erreicht werden können
    (SELECT p.id, q.ziel FROM beh b
     JOIN (SELECT id, rohstoff FROM rezpos WHERE rezeptnummer=:rn AND typ=1) p ON b.rohstoff = p.rohstoff // aus dem gewünschten Rezept "rezeptnummer"
     JOIN qundz q ON b.behaelternummer = q.quelle) z
   GROUP BY z.ziel) k
JOIN (SELECT COUNT(id) mcount FROM rezpos WHERE rezeptnummer=:rn AND typ=1) m                            // Zähle alle Dosierpositionen im Rezept
JOIN beh e ON k.ziel=e.behaelternummer                                                                   // Zielbehälternamen anflanschen
WHERE mcount=qcount                                                                                      // Nur die anzeigen, wo "möchliche Anzahl zu bedienender Positionen" der "gewünschten Anzahl zu bedienender Positionen" entspricht
Das tut was es soll, ist aber ein Monster :shock: (und ein wenig von hinten durch die Brust irgendwie). Da meine Hirnverknotung aber gerade recht hoch ist, komme ich nicht ganz auf den einfachen Weg, den es vermutlich dafür gibt. Mag mir da wer auf die Sprünge helfen? :)

shmia 16. Feb 2012 16:10

AW: SQL Vereinfachen
 
Deine Tabelle qundz sollte übrigens so aussehen:
Code:
- Quelle (1. Primärschlüsselfeld)
- Ziel  (2. Primärschlüsselfeld)
Dies hat 3 Vorteile:
* Tabelle ist kleiner, Abfragen sind schneller
* es wird verhindert dass gleiche Behälter-Verbindungen mehrfach vorhanden sein können
* Abfragen profitieren davon, dass die Felder Quelle und Ziel schon durch den Primärschlüssel indiziert sind.

Blup 16. Feb 2012 16:48

AW: SQL Vereinfachen
 
Ungetestet im Prinzip so:
SQL-Code:
select distinct a.nr, a.name
from     beh  a
left join qundz b on (b.ziel = a.nr)
left join beh  c on (c.nr = b.quelle) and (c.rohstoff = :rohstoff1)
left join beh  d on (d.nr = b.quelle) and (d.rohstoff = :rohstoff2)
left join beh  e on (e.nr = b.quelle) and (e.rohstoff = :rohstoff3)
where (c.nr is not null) and (d.nr is not null) and (e.nr is not null)

p80286 16. Feb 2012 16:56

AW: SQL Vereinfachen
 
Meiner Meinung nach kann das nicht so richti funktionieren, da zu jeder Rezeptur auch mehrere Rohstoffe gehören. Du solltest also Deine Tabellen erweitern:

Rezept
RezeptID

RezeptRohstoff
RezeptID
RohstoffID
RohstoffMenge

Behälter(Rohstoff)
BehälterID(RohstoffID)

dann sollte auch die gesuchte zusamenstellung kein Problem sein:

Code:
select ...
from Rezept,rezeptrohstoff,behälter as rohstoff,qundz,behalter produkt
where Rezept.RezeptID=RezeptRohstoff.RezeptID
  and Rohstoff.BehälterID=RezeptRohstoff.RohstoffID
  and Rohstoff.BehälterID=qundz.Quelle
  and produkt.BehälterID=qundz.Ziel
Ich hoffe ich habe da nichts falsch verstanden

Gruß
K-H

omata 16. Feb 2012 17:29

AW: SQL Vereinfachen
 
Vielleicht so...

SQL-Code:
SELECT q.ziel, e.Behaeltername
FROM beh b
INNER JOIN rezpos p
  ON b.rohstoff = p.rohstoff
INNER JOIN qundz q
  ON b.behaelternummer = q.quelle
INNER JOIN beh e
  ON q.ziel = e.behaelternummer
WHERE rezeptnummer = :rn
  AND typ = 1
GROUP BY p.id, q.ziel, e.Behaeltername, p.rezeptnummer, p.typ
HAVING COUNT(*) = (SELECT COUNT(*)
                   FROM rezpos
                   WHERE rezeptnummer = p.rezeptnummer
                     AND typ = p.typ)

jobo 16. Feb 2012 20:46

AW: SQL Vereinfachen
 
Vielleicht hab ich das falsch verstanden, mir ist nicht klar, wozu die counts alle gut sein sollen, wenn Du eine Liste der möglichen Quell- und oder Zielbehälter haben möchtest. Also gebe ich einfach alles aus, was in Frage kommt.

SQL-Code:
Select r.rohstoff,
       q.id, q.behaelternummer, q.behaeltername,
       z.id, z.behaelternummer, z.behaeltername, z.rohstoff as Produkt
  from rezpos r
  join beh   q on r.rohstoff = q.rohstoff
  join qundz u on q.behaelternummer = u.quelle
  join beh   z on u.ziel = z.behaelternummer
 where r.rezeptnummer = :rn
   and r.typ = 1
P.S.: Ich habe die IDs nicht genutzt, auch wenn sie vermutlich teilweise irgendwo die Keys bzw Fk sind. Die anderen Spalten schienen mir "sprechender", Prinzip ist ja eh das gleiche.

BUG 16. Feb 2012 23:24

AW: SQL Vereinfachen
 
Die Division wäre vielleicht was für dich.

Du konstruierst eine Relation R1(Zielbehälter, Quellbehälterinhalt), die alle vorhanden Tupel (Zielbehälter, Quellbehälterinhalt) enthält (Projektion von Verbund aus beh, qundz und beh). Dann konstruierst du eine Relation R2(Zutat), die alle für das gewünschte Rezept nötigen Zutaten enthält (Select auf rezpos).

Wenn du nun R1/R2 rechnest, kommen genau die Behälter heraus, die die nötigen Zuflüsse haben.
Das Berechnen der Division ist leider nicht mit einem SQL-Befehl erschlagen, so dass die Lösung evtl. auch lang wird.

Wie man die uA. nötige Mengen-Differenz erhält, ist zB. hier beschrieben.

Medium 17. Feb 2012 09:36

AW: SQL Vereinfachen
 
Danke für die rege Beteiligung!

Das Problem scheint wohl doch komplexer zu sein als ich gestern noch im guten Glauben annahm. Fast alle Lösungen leiden unter dem selben Problem: Ich erhalte eine Liste aller Zielbehälter, die von jedem Rohstoff einzeln erreicht werden können, wobei ich gerne wüsste welche Ziele von allen Rohstoffen gleichsam erreicht werden können. Was ich leicht bekomme ist also:
Code:
rohstoff  zielbehälter
------------------------
   1           101
   1           130
   1           140
   2            50
   2           130
   3            50
   3           101
   3           130
   3           140
Das sind schon nur die Rohstoffe aus einem konkreten Rezept, so dass das schon recht nah an der Lösung ist, wobei ich dies letztlich im Grunde mit einer Mischung eurer Vorschläge erreicht habe:
SQL-Code:
SELECT a.rohstoff, a.behnr FROM
  (SELECT b1.rohstoff, b2.behnr FROM qundz qz
   JOIN beh b1 ON b1.behnr=qz.quelle
   JOIN rohstoffe rs ON b1.rohstoff=rs.rnummer
   JOIN beh b2 ON b2.behnr=qz.ziel) a
INNER JOIN
  (SELECT rohstoff FROM rezpos
   WHERE reznr=:rn AND typ=1) b
USING (rohstoff)
Im Ergebnis sieht man, dass Behälter 130 als einziger von allen Rohstoffen erreicht werden kann, und genau diesen suche ich! (Es kann generell durchaus mehrere Ziele geben bei manchen Rezepturen.)
Im Grunde lande ich, der noch keinen Kaffee hatte, wieder bei etwas ähnlichem von gestern: Rohstoffe pro Ziel zählen, und mit der Anzahl Rohstoffe im Rezept vergleichen. Das geht doch sicherlich hübscher :)

@shima: Ich habe den Primärindex nur auf der (an sich hier eher unbeteiligten) Spalte "id" liegen, aber einen UNIQUE-Index auf (quelle, ziel). Beraube ich mich da ggf. Vorteile, die ich im Primärindex hätte wie du ihn vorschlägst?

Danke euch schon mal!

DeddyH 17. Feb 2012 09:47

AW: SQL Vereinfachen
 
Die Lösung von omata bringt auch nicht das gewünschte Ergebnis? Etwas Ähnliches hatte ich nämlich auch im Sinn: zuerst alle passenden per INNER JOIN ermitteln und dann die Anzahl mit der der Rezeptpositionen vergleichen.

jobo 17. Feb 2012 09:53

AW: SQL Vereinfachen
 
Zitat:

Zitat von Medium (Beitrag 1151566)
Das Problem scheint wohl doch komplexer zu sein als ich gestern noch im guten Glauben annahm. Fast alle Lösungen leiden unter dem selben Problem: Ich erhalte eine Liste aller Zielbehälter, die von jedem Rohstoff einzeln erreicht werden können, wobei ich gerne wüsste welche Ziele von allen Rohstoffen gleichsam erreicht werden können. Was ich leicht bekomme ist also..


Im Ergebnis sieht man, dass Behälter 130 als einziger von allen Rohstoffen erreicht werden kann, und genau diesen suche ich! (Es kann generell durchaus mehrere Ziele geben bei manchen Rezepturen.)

Das Problem ist vielleicht auch, dass Du die Aufgabenstellung nicht präzise formulierst- bis jetzt. Was bedeutet denn "kann auch mehrere"? Kann sein, dass es die gibt, interessiert mich aber nicht?
Ich will jeden einzelnen Zielbehälter, der geht (Sonst wird es ja keine Liste)?
..

Medium 17. Feb 2012 10:10

AW: SQL Vereinfachen
 
@DeddyH: Da habe ich ein recht ähnliches Problem: Ich bekomme ohne das HAVING dort alle Ziele, die ebenfalls einzeln pro Rohstoff erreicht werden (allerdings ohne Dopplungen). Obiges Beispiel sähe hier also so aus:
Code:
zielbehälter
--------------
     50
    101
    130
    140
Mit der HAVING Klausel ist das Ergebnis leer, auch wenn es mindestens ein mögliches Ziel sicher gibt (so konstruiert).

@jobo: Sorry, ja es soll eine Liste werden, die alle Zielbehälter führt, in denen ein gewähltes Rezept angefertigt werden kann. Am Ende geht es darum, dem Anlagenfahrer eine Combobox mit diesen anzuzeigen, wenn er ein Rezept zur Produktion vorgeben möchte. Dies können 0-N Ergebnisse sein, wobei Rezepte mit 0 Zielen wohl als ungültig interpretiert werden müssen :)

Jumpy 17. Feb 2012 10:34

AW: SQL Vereinfachen
 
Ausgehend von deiner Ergebnismenge in #8:


Select zielbehaelter, count(zielbehaelter)
From (DerSelectDerDeineErgebnismengeLiefert)
Group By zielbehaelter
Having count(zielbehaelter) = (SelectDerDieAnzahlAnZutatenLiefert)

Ist arg konstruiert und wenig elegant, aber sollte die Ergebnisliste liefern.

Medium 17. Feb 2012 11:45

AW: SQL Vereinfachen
 
Das war auch mein Gedanke. Letztlich von meiner ersten Lösung gestern nicht allzuweit entfernt, jedoch sind die Sub-Selects in dieser Variante nun erheblich leichter nachvollziehbar, so dass man da ggf. auch nach ein paar Monaten noch heruasfinden kann, was da überbaupt gemacht wird. Das war letzlich auch das Ziel meiner Frage: Funktionierende Lösung, die etwas weniger verworren ist, als das was ich da produziert hab :)

Stand:
SQL-Code:
SELECT x.behnr, x.name FROM
  (SELECT a.rohstoff, a.behnr, a.name FROM
    (SELECT b1.rohstoff, b2.behnr, b2.name FROM qundz qz
    JOIN beh b1 ON b1.behnr=qz.quelle
    JOIN beh b2 ON b2.behnr=qz.ziel
    JOIN rohstoffe rs ON b1.rohstoff=rs.rnummer) a
  INNER JOIN
    (SELECT rohstoff FROM rezpos WHERE reznr=:rn AND typ=1) b
  USING (rohstoff)) x
GROUP BY
  x.behnr
HAVING
  COUNT(x.behnr) >= (SELECT COUNT(*) FROM rezpos WHERE reznr=:rn AND typ=1)
">=", weil ich noch nicht weiss, ob ggf. später mehrere Quellbehälter auf ein und dem selben Ziel den selben Rohstoff beinhalten können. Es kann also auch mehr Quellen als Rohstoffe im Rezept geben, was denke ich durch das >= (statt =) behandelt sein sollte.

Zu vormals:
SQL-Code:
SELECT k.ziel, e.name FROM
  (SELECT COUNT(*) qcount, z.ziel FROM
    (SELECT p.id, q.ziel FROM beh b
    JOIN (SELECT id, rohstoff FROM rezpos WHERE reznr=:rn AND typ=1) p ON b.rohstoff = p.rohstoff
    JOIN qundz q ON b.behnr = q.quelle) z
    GROUP BY z.ziel) k
  JOIN (SELECT COUNT(id) mcount FROM rezpos WHERE reznr=:rn AND typ=1) m
JOIN beh e ON k.ziel=e.behnr
WHERE mcount<=qcount
Das Ergebnis scheint gleich zu sein, und auch wenn die neue Variante länger ist, finde ich sie doch weit eingängiger. Die Mechanismen dürften bei beidem aber am Ende doch recht ähnlich sein, und wenn auch ihr intuitiv nicht zu einem Einzeiler kommt, bin ich jetzt zumindest davon überzeugt, dass ich das Problem deutlich unterschätzt habe :)

Besten Dank! :dp:

haentschman 17. Feb 2012 11:51

AW: SQL Vereinfachen
 
[OT]
nur so aus Interesse...

Ist die Komplexität der SQL Abfrage vergleichbar mit dem Design der DB ? Sprich je komplexer das SQL um so bescheidener das DB Design... und umgekehrt ? :gruebel:
[/OT]

Jumpy 17. Feb 2012 11:55

AW: SQL Vereinfachen
 
Zitat:

Zitat von Medium (Beitrag 1151614)
">=", weil ich noch nicht weiss, ob ggf. später mehrere Quellbehälter auf ein und dem selben Ziel den selben Rohstoff beinhalten können. Es kann also auch mehr Quellen als Rohstoffe im Rezept geben, was denke ich durch das >= (statt =) behandelt sein sollte.

Da bitte Vorsicht walten lassen! In der zukünftigen Mehrbehältervariante könnten bei z.B. 4 benötigten Rohstoffe jeweils 2 der Rohstoffe aus mehreren Quell-Behältern kommen und im Zielbehäter landen Somit ist der count >= Anz. Rohstoffe, obwohl ggf. noch nichtmal alle Rohstoffe im Behälter landen sondern nur zwei, diese dafür aber mehrmals.

Dies wird verhindert, indem in dem "Zwischenselekt" irgendwie ein Distinct auf die Rohstoff+Ziel gemacht wird, so dass mehrere Quellen eines Rohstoffes die auf das selbe Ziel kommen nicht mehrfach berücksichtigt werden. Dann würde auch das "=" ausreichen.

Je mehr ich aber darüber nachdenke und das hier schreibe, kommen mir aber Zweifel, das die Lösung 100% wasserdicht ist. Es kann ja für einen Zielbehälter mehrere passende Kombis aus Quellbehältern geben, um das Ziel zu erreichen.

Medium 17. Feb 2012 12:02

AW: SQL Vereinfachen
 
@haentschman: Die DB ist nicht perfekt, aber durchaus gut strukturiert. Das ist auch das erste Mal, dass ich in dem Projekt so etwas großes an SQL brauchte. Ehemals wurde diese Funktionalität in einer grausigen Delphi-Routine gemacht, die in 3 Queries zigfach rumgeschleift ist. Das wollte ich eigentlich nur aufhübschen :)
Das knifflige hier ist wohl vor allem, dass in den Rezepten Rohstoffe stehen, und nicht direkt die Quellbehälter. Die sind zwar meistens 1:1 zugeordnet, aber ich musste Rohstoffe und Behälter jetzt entkoppeln, da jetzt teilweise wechselnde Rohstoffe in den gleichen Quellen gelagert werden.

Die Struktur der Tabellen ist in #1 angedeutet.

@Jumpy: In der Tat! Ui, danke für den Hinweis.
Die unterschiedlichen Kombis sind möglich, jedoch brauche ich diese hier nicht konkret. Ich muss nur wissen "es geht". Ich guck mal, wo das Distinct hin müsste, das sollte aber so gehen. Danke!
\\Edit: Ein DISTINCT im 2. Subselect (SELECT DISTINCT b1.rohstoff, b2.behnr, b2.name FROM qundz qz) tut das richtige. Es ist damit sogar richtig behandelt, wenn ich in einem Rezept mehr als eine Position mit dem selben Rohstoff habe! Ich glaube, das ist schon ganz okay so.

BUG 17. Feb 2012 12:09

AW: SQL Vereinfachen
 
Zitat:

Zitat von BUG (Beitrag 1151525)
Die Division wäre vielleicht was für dich.

Ich habe mal versucht, das in SQL umzusetzen:
SQL-Code:
SELECT DISTINCT Behälternummer, Behältername FROM beh WHERE (Behälternummer, Behältername) not in
   (SELECT
      Behälternummer, Behältername
   FROM
      beh, rezpos
   WHERE
      Rezeptnummer = :rn
      and Typ = 1
      and (Behälternummer, Behältername, Rohstoff) not in
         (SELECT
            a.Behälternummer, a.Behältername, c.Rohstoff
         FROM
            beh as a, qundz as b, beh as c
         WHERE
            a.Behältername = b.Ziel
            and b.Quelle = c.Behälternummer)
   )

haentschman 17. Feb 2012 12:52

AW: SQL Vereinfachen
 
@Medium:
Zitat:

@haentschman: Die DB ist nicht perfekt, aber durchaus gut strukturiert.
Die Frage war allgemeiner Natur und keinesfalls gegen dich gerichtet. In der DP sind ja schon manchmal SQL Verrenkungen aufgetaucht die mit einem geänderten Design (sofern möglich) durchaus einfacher würden.

Tschuldigung wenn das falsch rüber gekommen ist...:oops:

p80286 17. Feb 2012 13:04

AW: SQL Vereinfachen
 
Zitat:

Zitat von Medium (Beitrag 1151621)
@haentschman: Die DB ist nicht perfekt, aber durchaus gut strukturiert. Das ist auch das erste Mal, dass ich in dem Projekt so etwas großes an SQL brauchte. Ehemals wurde diese Funktionalität in einer grausigen Delphi-Routine gemacht, die in 3 Queries zigfach rumgeschleift ist. Das wollte ich eigentlich nur aufhübschen :)

Bitte versuch es doch "richtig" zu machen. Ich habe den Eindruck, daß in Deiner DB noch die Zettelkastenmentalität vorherrscht. Was man sehen kann ist auch so.
Wenn dann die Darstellung verändert wird, sind auf einmal alle so offensichtlichen Informationen weg.
Ist nicht gegen Dich gerichtet, nur als gut gemeinter Rat zu verstehen.

Gruß
K-H

Medium 17. Feb 2012 14:46

AW: SQL Vereinfachen
 
Ich würde es durchaus "richtig" machen, jedoch bin ich nicht sicher an welcher Stelle da angefasst werden sollte. Eventuell könnt ihr mir da einen Rat geben, wie sich die Struktur vereinfachen würde.

Bislang schaut es so aus:

Tabelle "beh" - Behälterdaten (beinhaltet alle Quell- und Zielbehälter, manche treten auch als beides auf)
- id
- behnr (eindeutig, nicht fortlaufend, vom Kunden vorgegeben)
- name (Klartext, der im Programm statt der Nummer verwendet wird)
- min (Produktmindestfüllstand, ab dem die Pumpe unter dem Behälter gefährdet wäre trocken zu laufen, in Liter)
- max (Produktmaximalfüllstand, darüber sprechen die Überfüllsichrungen an. Sicherer Maximalstand, in Liter)
- ist (Aktueller Produktfüllstand in Liter)
- ziel (aktuell angeschaltetes Ziel, versorgt von der zugehörigen SPS, es kann immer nur genau ein aktuelles Ziel geben.)
- rohstoff (Rohstoffnummer des im Behälter befindlichen Materials, eingepflegt vom Anlagenbediener nach Anlieferung und Befüllung. Fremdschlüssel auf rohstoffe.rnummer)
- kenn1
- kenn2 (ein und der selbe Rohstoff kann in unterschiedlichen Qualitäten geliefert werden, die sich auch nicht in je eigene Rohstoffe untergliedern lassen weil Abweichungen zu divers. Hat nachher Einfluss auf die Dosiermengen. Die betroffenen Quellbehälter sind aber immer "Lieferrein", d.h. Qualitäten mischen sich niemals.)

Tabelle "Rohstoffe"
- id
- rnummer (eindeutig, nicht fortlaufend, vom Kunden vorgegeben)
- rname (Klartext zum Rohstoff)
- comment (Freies Kommentarfeld)

Tabelle "qundz"
- id
- quelle (Fremdschlüssel auf beh.behnr)
- ziel (Fremdschlüssel auf beh.behnr)

Tabelle "rezepte"
- id
- reznr (Rezeptnummer eindeutig, vom Kunden vorgegeben, nicht fortlaufend)
- rezname (Klartext des Produktes)

Tabelle "rezpos" (Die einzelnen Rezeptpositionen)
- id
- reznr (Fremdschlüssel auf rezepte.reznr)
- posid (ID einer Position innerhalb eines Rezeptes. Fortlaufend, programmintern vergeben und verwaltet)
- typ (Positionstyp. Kann sein "Dosieren, Rührwerk ein, Rührwerk aus, Probenahme, Heizen, Kühlen, etc. pp)
- soll1 (Sollwert 1, Interpretation über "typ")
- soll2 (Sollwert 2, Interpretation über "typ")
- rohstoff (nur für Dosierpositionen relevant, Fremdschlüssel zu rohstoffe.rnummer)
- formula (Mengenberechnungsformel für Dosierpositionen, deren Menge nicht absolut ist, sondern sich entweder auf zuvor dosierte Positionen oder Bedienereingaben beim Einwiegen oder Kennzahlen aus der Behältertabelle für den jeweiligen Quelltank bezieht)
- refIDA (Fremdschlüssel auf rezpos.id, Referenzdosierposition für in Formel verwendete Variable A)
- refIDB (Fremdschlüssel auf rezpos.id, Referenzdosierposition für in Formel verwendete Variable B)

Die "id" Felder werden für das Programm zwingend benötigt, dass die Kommunikation zwischen SPS und Datenbank herstellt. Nicht alle Tabellen sind an dieser beteiligt, aber ich fand es nur konsequent dieses Feld so dann überall zu führen. (Und im Nachhinein ist man meiner Erfahrung nach hier und da ja doch glücklich, einen einheitlichen Mechanismus zur eindeutigen Satzidentifikation zu haben.)

Die beiden Rezepttabellen sind Stammrezeptdaten. Diese Tabellen gibt es nochmals mit Suffix "_proz" für gestartete Rezepturen, die gerade in der Anlage bearbeitet werden. Dort kommt noch in "rezepte_proz" ein Feld "ziel" hinzu (Fremdschlüssel auf beh.behnummer, Mischbehälter für Rezept - das ist der, der vom Bediener über die Combobox auswählen können soll, um die es hier die ganze Zeit geht), und ein "status", der aus der SPS versorgt wird. Die Rezeptpositionen werden ebenfalls um einen Status, sowie "ist1" und "ist2" ergänzt, die ebenfalls aus der SPS kommen. In der "rezpos_proz" können beliebige Positionen "Nachdosieren" nachträglich an ein Rezept angehängt werden, sie unterscheiden sich also potenziell nach Fertigstellung auch strukturell vom Stammrezept.
Es gibt noch ein drittes ähnlich strukturiertes Tabellenpaar mit ein paar mehr Randdaten vom Bediener, in die fertig hergestellte Rezepturen zur späteren Statistik archiviert werden.

An der "rezpos" kann ich nicht viel drehen, da sie strukturell stark an einen Kommunikationsdatenbaustein in der SPS gekoppelt ist. Änderungen dort sind deutlich zu aufwendig, dann lieber 1-2 "interessante" SQL-Statements im Programm :) Was sollte ich hier idealerweise umstellen, um flexibler zu werden, bzw. mit einfacheren Statements auszukommen? Ernste Frage, keine rethorische - ich fühl mich nicht angegriffen, bräuchte aber konkretere Klappse auf den Hinterkopf als "machs halt besser", weil ich wohl zu sehr im Saft eingesickert bin gerade, als dass ich spontan benennen könnte was überhaupt besser ist =) (Die Rezeptbearbeitung ist ja nur ein kleiner Teil des Ganzen, und so Kunden sind ja immer ungeduldig :)) Da ich aber gerade die Chance habe das Altsystem anzufassen, würde ich es schon ganz gerne gleich vernünftig machen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz