[gelöst] Tabelle befüllen

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

[gelöst] Tabelle befüllen

Beitrag von fliegermichl »

Guten morgen zusammen,

meine aktuelle Frage hat zwar nichts mit Lazarus zu tun aber ich weiß, daß hier einige Datenbankspezialisten mitlesen.
Ich habe eine Tabelle "produkte" und eine "module". Bislang konnte man für jedes Produkt auch jedes Modul hinzubuchen.
Nun hat der Kunde ein völlig neues Produkt bei dem es keinen Sinn macht, eines der bislang verfügbaren Module hinzu zu buchen.

Also habe ich mir überlegt, ich definiere eine Tabelle "produktmodule" mit den Feldern "produktid" und "modulid". Wenn jetzt für ein Produkt
mit der id 5 die verfügbaren Module abgefragt werden, kann ich diese Tabelle dafür heranziehen indem ich alle Module abfrage für welche die produktid = 5 ist.

Meine Frage bezieht sich auf die initiale Befüllung der Tabelle produktmodule. Wie kann ich einen insert Befehl erzeugen, der für jedes aktuell vorhandene Produkt und jedes aktuell vorhandene Modul einen Eintrag in der Tabelle produktmodule erstellt?

Vielen Dank Michael
Zuletzt geändert von fliegermichl am Fr 23. Dez 2022, 11:55, insgesamt 1-mal geändert.

Benutzeravatar
six1
Beiträge: 782
Registriert: Do 1. Jul 2010, 19:01

Re: Tabelle befüllen

Beitrag von six1 »

Ich würde in der Produkttabelle einfach ein weiteres Feld erstellen: modul_buchbar mit int-1 (0,1)
Wenn ein Produkt kein zubuchbares Modul hat, dann einfach das Feld auf "0" stellen
Gruß, Michael

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Tabelle befüllen

Beitrag von theo »

@fliegermichl: Die Beschreibung ist nicht ganz klar.
Wird es künftig zu dem neuen Produkt auch "Module" geben? Können diese neuen Module auch von den alten Produkten verwendet werden?
Falls nicht, reicht die Antwort von six1.
Falls ja, könnte man z.B. Modulkategorien einführen.
Auf jeden Fall bräuchte man mehr Informationen.

Zum "technischen" Teil: Muss das wirklich EIN Insert Statement sein?
Ich zermartere mir bei solchen einmaligen Sachen (Import etc.) meistens nicht das Hirn mit SQL-Zauberei, sondern mache zwei Abfragen und loope durch die Resultsets.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Tabelle befüllen

Beitrag von fliegermichl »

Genau das ist das Problem. Ich will die Modulverwaltung nicht komplett neu machen. Auch das neue Produkt soll Module buchbar bekommen aber nicht die von den anderen Produkten.

Die bislang verwalteten Produkte sind Varianten des CAD Programmes. Neu hinzugekommen ist jetzt eine Webanwendung Project-Organizer, die absolut nichts mit dem CAD Programm zu tun hat. Für diese Webanwendung soll es aber auch mehrere zubuchbare Module geben.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Tabelle befüllen

Beitrag von fliegermichl »

Die gesuchte insert Anweisung soll also für jedes aktuell vorhandene Produkt und für jedes aktuell vorhandene Modul einen Datensatz mit der jeweiligen Produkt Id und der jeweiligen Modul Id anlegen.

Für das neu hinzukommende Produkt werden diese Zuordnungen dann manuell gemacht.

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Tabelle befüllen

Beitrag von charlytango »

fliegermichl hat geschrieben:
Fr 23. Dez 2022, 08:55
Guten morgen zusammen,

meine aktuelle Frage hat zwar nichts mit Lazarus zu tun aber ich weiß, daß hier einige Datenbankspezialisten mitlesen.
Ich habe eine Tabelle "produkte" und eine "module". Bislang konnte man für jedes Produkt auch jedes Modul hinzubuchen.
Nun hat der Kunde ein völlig neues Produkt bei dem es keinen Sinn macht, eines der bislang verfügbaren Module hinzu zu buchen.

Also habe ich mir überlegt, ich definiere eine Tabelle "produktmodule" mit den Feldern "produktid" und "modulid". Wenn jetzt für ein Produkt
mit der id 5 die verfügbaren Module abgefragt werden, kann ich diese Tabelle dafür heranziehen indem ich alle Module abfrage für welche die produktid = 5 ist.

Meine Frage bezieht sich auf die initiale Befüllung der Tabelle produktmodule. Wie kann ich einen insert Befehl erzeugen, der für jedes aktuell vorhandene Produkt und jedes aktuell vorhandene Modul einen Eintrag in der Tabelle produktmodule erstellt?

Vielen Dank Michael
Wenn ich dich richtig verstanden habe suchst du nach einer Möglichkeit Eingabefehler zu vermeiden. Der Benutzer soll also nur die Module "hinzubuchen" können die Sinn machen bzw erlaubt sind.

-- das kann man einerseits erreichen indem du für jedes Produkt einen Modulkatalog hinterlegst. Da hast du bei bestehenden Produkten schon erkannt wo das Problem liegt. Das können viele sein. ist aber auch recht präzise und flexibel. Deine Idee eine Tabelle tproduktmodule zu erstellen ist absolut richtig, ich würde nur noch einen Primary Key dazu nehmen (zb PMID, integer). Das ist zwar aus der Datenbanklogik nicht nötig, du tust dir aber oft leichter wenn du zb einen bestimmten Datensatz löschen willst, dann hast du einen eindeutigen Key.

-- du kannst es aber auch andersrum machen indem du nur jene Module in tproduktmodule schreibst die NICHT zu einem Produkt zugebucht weden dürfen.

die erste Methode ist flexibler aber aufwendiger wenn es viele Produkte und Module sind.

Das SQL zur befüllung ist:

Code: Alles auswählen

INSERT INTO tproduktmodule(produktid, modulid)
SELECT produktid, modulid  FROM tmodule, tprodukte 
Ein INSERT auf einem natural join basierend (Je nach Datenbank bzw Tabellengröße kann man damit schonmal einen ganzen Server lahmlegen denn der "multipliziert " ja die eine Tabelle mit der anderen.). Natural Joins sind daher ein NoGo. Nur wirst du beim Befüllen nicht drum rum kommen. Bei großen Datenbeständen kannst du das zb auch in Teilen machen indem du zb die ProduktID einschränkst oder das Statement nachts laufen lässt.

Also Vorsicht beim Einsatz

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Tabelle befüllen

Beitrag von fliegermichl »

charlytango hat geschrieben:
Fr 23. Dez 2022, 11:13
fliegermichl hat geschrieben:
Fr 23. Dez 2022, 08:55
Guten morgen zusammen,

meine aktuelle Frage hat zwar nichts mit Lazarus zu tun aber ich weiß, daß hier einige Datenbankspezialisten mitlesen.
Ich habe eine Tabelle "produkte" und eine "module". Bislang konnte man für jedes Produkt auch jedes Modul hinzubuchen.
Nun hat der Kunde ein völlig neues Produkt bei dem es keinen Sinn macht, eines der bislang verfügbaren Module hinzu zu buchen.

Also habe ich mir überlegt, ich definiere eine Tabelle "produktmodule" mit den Feldern "produktid" und "modulid". Wenn jetzt für ein Produkt
mit der id 5 die verfügbaren Module abgefragt werden, kann ich diese Tabelle dafür heranziehen indem ich alle Module abfrage für welche die produktid = 5 ist.

Meine Frage bezieht sich auf die initiale Befüllung der Tabelle produktmodule. Wie kann ich einen insert Befehl erzeugen, der für jedes aktuell vorhandene Produkt und jedes aktuell vorhandene Modul einen Eintrag in der Tabelle produktmodule erstellt?

Vielen Dank Michael
Wenn ich dich richtig verstanden habe suchst du nach einer Möglichkeit Eingabefehler zu vermeiden. Der Benutzer soll also nur die Module "hinzubuchen" können die Sinn machen bzw erlaubt sind.

-- das kann man einerseits erreichen indem du für jedes Produkt einen Modulkatalog hinterlegst. Da hast du bei bestehenden Produkten schon erkannt wo das Problem liegt. Das können viele sein. ist aber auch recht präzise und flexibel. Deine Idee eine Tabelle tproduktmodule zu erstellen ist absolut richtig, ich würde nur noch einen Primary Key dazu nehmen (zb PMID, integer). Das ist zwar aus der Datenbanklogik nicht nötig, du tust dir aber oft leichter wenn du zb einen bestimmten Datensatz löschen willst, dann hast du einen eindeutigen Key.

-- du kannst es aber auch andersrum machen indem du nur jene Module in tproduktmodule schreibst die NICHT zu einem Produkt zugebucht weden dürfen.

die erste Methode ist flexibler aber aufwendiger wenn es viele Produkte und Module sind.

Das SQL zur befüllung ist:

Code: Alles auswählen

INSERT INTO tproduktmodule(produktid, modulid)
SELECT produktid, modulid  FROM tmodule, tprodukte 
Ein INSERT auf einem natural join basierend (Je nach Datenbank bzw Tabellengröße kann man damit schonmal einen ganzen Server lahmlegen denn der "multipliziert " ja die eine Tabelle mit der anderen.). Natural Joins sind daher ein NoGo. Nur wirst du beim Befüllen nicht drum rum kommen. Bei großen Datenbeständen kannst du das zb auch in Teilen machen indem du zb die ProduktID einschränkst oder das Statement nachts laufen lässt.

Also Vorsicht beim Einsatz
Genau das ist der gesuchte Befehl. Das neue Produkt und die neuen Module gibt es aktuell noch nicht.
Ich habe die Tabelle produktmodule mit den Feldern id, produktid und modulid angelegt. id soll der Primärindex sein und die Kombination aus produktid und modulid soll unique sein.

Wie ihr seht, sind meine Datenbankkenntnisse bescheiden. Wie kann ich den unique Index über die Verbindung von den 2 Feldern erstellen?
Es ist eine Mysql Datenbank.

LG Michael

Edit: Hab's gefunden. phpMyAdmin bietet eine Funktion an, einen unique Index über mehrere Felder zu erstellen.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Tabelle befüllen

Beitrag von fliegermichl »

Hab es noch etwas abändern müssen.
Der Befehl lautete jetzt

Code: Alles auswählen

INSERT INTO produktmodule(produktid, modulid) SELECT p.id as produktid, m.id as modulid FROM module m, produkt p;
345 Datensätze eingefügt.

Danke für Eure Hilfe und frohe Weihnachten
Michael

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: [gelöst] Tabelle befüllen

Beitrag von charlytango »

Kleiner Tip: Verwende aussagekräftige und eindeutige Bezeichnungen für Primary Keys.
Damit kann man die Datenbankstruktur auch später noch besser verstehen. Einige male "ID" als Feldbezeichnung wirst du spätestens dann verfluchen wenn du in ein paar Jahren etwas ändern musst. Den anderen Grund hast du eh selber erlebt weil du eine Verbindungstabelle brauchtest.

Auch einige DB-Tools funktionieren besser wenn sie dadurch verstehen können wie Tabellen zusammen spielen.

Empfehle HeidiSQL als Werkzeug, klingt blöd, kann viel und ist übersichlich ;)

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: [gelöst] Tabelle befüllen

Beitrag von fliegermichl »

Danke für den Hinweis. Ich war der Meinung, wenn jede Tabelle ein Feld "Id" hat, die autoincrement und der Primärindex ist, dann wäre das eine gute Idee.
Im Nachhinwein kann ich es nicht mehr ändern, weil jede Menge bestehender Code damit arbeitet.

Für neue Projekte werde ich den Tip im Hinterkopf behalten.

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: [gelöst] Tabelle befüllen

Beitrag von charlytango »

ich benutze grundsätzlich (auch wenns vom DB-Design her nicht wirklich nötig ist) Primary Keys in jeder Tabelle. Und deren Bezeichnungen folgen einem einheitlichen Muster um die Nachverfolgbarkeit zu ermöglichen und meine Schreibfaulheit zu unterstützen.
Also irgendwas wie PersID, ProdID, ModID. Zudem benenne ich wenn möglich Tabellen mit t (also tprodukt, tkunden) im Gegensatz zu v in Views damit ich auch im Code immer weiß welches Element ich gerade in der Hand habe (aber das ist nur individuel für mich -- andere machen das sicher auch anders)

Wie viele Tabellen hast du denn im DB-Modell?

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: [gelöst] Tabelle befüllen

Beitrag von fliegermichl »

66 Tabellen insgesamt. Das ist eine Onlineverwaltung für Produktlizenzen, Wartung usw.

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: [gelöst] Tabelle befüllen

Beitrag von charlytango »

das ist dann auch nix mehr für den Hausgebrauch.
Verwendest du ein Designtool ?

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: [gelöst] Tabelle befüllen

Beitrag von af0815 »

Ich kenne das mit den guten Tipps. An der aktuell Situation kann man ja fast nichts mehr ändern, ABER bei einem neuen Design kann man da viel machen :-)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: [gelöst] Tabelle befüllen

Beitrag von fliegermichl »

Ja das ist am Ende ja tatsächlich so. Man hat was dahingewurschtelt, was auch einigermassen funktioniert. Wenn was geändert werden muß, dann wird das dazwischen gewurschtelt was dann auch einigermassen funktioniert und man ist sich gleichzeitig absolut sicher, wenn ich das nochmal machen müsste, dann würde ich das von Anfang an ganz anders aufziehen. Am Anfang wußte man von dem Problem aber noch nix :-)

Also im nächsten Leben werde ich ein besserer Programmierer, wobei ich hatte mir vorgenommen ein Finanzamt aufzumachen. Da bekommst du jede Menge Kohle ohne jegliche Gegenleistung.

In diesem Sinne Euch allen ein frohes Weihnachtsfest.

Antworten