PHP und SQL - Keine Ahnung, aber davon jede Menge

  • Ich bastle grade anner Datenbank und einer dazugehörigen Seite rum.

    Jede Farbnummer wird noch unterteilt in 20 Farbtiefen.
    SH 100-20 ist schwarz.
    SH 100-19 ist nicht ganz so schwarz.
    SH 100-1 ist hellgrau.

    Ich habe ein Formular, in dem ich Werte eingebe: ID (Primary), Farbnummer, Farbtiefe, Hex-Wert der Farbe (Nach html-Schema: #AABBCC) und noch anderes mehr.
    Dann wird das in der DB gespeichert (Funktioniert)

    Dann habe ich eine Ausgabe:
    Da sollen mir die Daten zu der ID angezeigt werden. (Funktioniert)

    Jetzt habe ich eine Anzeige, in der ich alle Farbnummern und wichtigen Daten, sowie die dazugehörigen Farbtiefen anzeigen lassen will.

    [ATTACH=JSON]{"alt":"Klicke auf die Grafik f\u00fcr eine vergr\u00f6\u00dferte Ansicht Name: farbanzeige.PNG Ansichten: 0 Gr\u00f6\u00dfe: 32,3 KB ID: 123924","data-align":"none","data-attachmentid":"123924","data-size":"large"}[/ATTACH]

    Und nu habe ich das Problem, das ich keinen Schimmer habe, wie ich das machen soll, daß ich beim absenden des Formulares den Hex-Wert in die entsprechenden Farbtiefen-Felder derselben Farbnummer übergeben kann.

    Die DB sieht derzeit so aus:

    [ATTACH=JSON]{"alt":"Klicke auf die Grafik f\u00fcr eine vergr\u00f6\u00dferte Ansicht Name: farbanzeige2.PNG Ansichten: 0 Gr\u00f6\u00dfe: 151,3 KB ID: 123925","data-align":"none","data-attachmentid":"123925","data-size":"large"}[/ATTACH]

    Die übergabe der Formularwert in die DB sieht grade so aus:

    Aber... wenn ich eine Farbe update. DIe hat meinetwegen die Farbnummer SH100 und die Farbtiefe 10.
    Dann müssen alle Farbtiefe_10-Felder, wenn sie die Farbnummer SH 100 haben, in der DB mit dem gesendeten Hex_Wert auch upgedatet werden.

    Ich bräuche also eine magische funktion, die mir macht:
    Stecke mir die Farbtiefe der grade abgesendeten ID in eine variable und stecke den Wert dieser Variablen dann in genau das Feldtiefe_xx-Feld, das zu dieser Farbnummer passt.

    Und wie das dann mit prepare und execute funktionieren soll, hab ich natürlich auch keinen Schimmer.

  • Beschreibe das mal bitte etwas weniger technisch, also eher in Beispielen, was Du genau willst.

    z.B.

    "Jetzt habe ich eine Anzeige, in der ich alle Farbnummern und wichtigen Daten, sowie die dazugehörigen Farbtiefen anzeigen lassen will."

    Bedeutet das laut dem DB-Auszug oben, dass Du z.B. alle mit der Nummer "SH 200" haben willst, und von denen dann alle Farbtiefen 1-20 ? Das Ergebnis wären also 20 Datensätze? 200-01 bis 200-20 ??

    "daß ich beim absenden des Formulares den Hex-Wert in die entsprechenden Farbtiefen-Felder derselben Farbnummer übergeben kann."

    ^^ hier liegt gerade mein primären Problem, denn ich habe keinen Schimmer, was nun der HEX-Wert mit der Nummer oder Tiefe zu tun hat, zumal Du ja ein Select willst, aber von "übergeben" schreibst und Dein PHP-Code nur aus Updates besteht, aber eben nicht aus einem Select.

    Wegen Deinem Update, also dem zweiten Problem. Das geht so mit der Update-Query natürlich nicht, denn die ändert ja nur einen Datensatz, den, dessen ID (Primary) übergeben wird. Da musst Du die Bedingung ändern und eben sagen "WHERE Farbnummer = xx AND Tiefe = yy".

    Und lass Dich von dem Prepare / Execute nicht fertig machen. Das ist im Grunde auch nix anderes als eine ganz normale SQL-Query ohne das ganze Zeug, nur dass Du damit eben quasi auch auf SQL-Ebene mit Variablen arbeitest und Sicherheitsfunktionen automatisch durchgeführt werden, die Du ohne das vorher in PHP händisch machen müsstest.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • Ja ich weiß, das ich das bekackt beschrieben habe :(
    Ich mach da jetzt seit nem Monat rum und hab total den Faden und den Bezug zur Realität verloren.

    Allo:
    Ich hab da 900 "Grund"farben. Von jeder Grundfarbe gibt es 20 Farbtiefen (20= ganz dunkel, 19 = "Grund"farbe, 1 = hellpastell). Das sind dann also 18.000 Farbtöne.
    Jeder Farbton hat eine eigene ID (Primärschlüssel), eine Farbnummer (SH 100-SH 999) und eine Farbiefe (1-20) einen Farbnamen und einen Hex-Wert (#AABBCC), damit ich den Farbton auf dem Monitor darstellen kann.

    Ich hab ein Formular gefrickelt.
    Die ID, Farbnummer und Tiefe stehen schon in der DB und dürfen weder geändert, noch gelöscht werden. (Die sind da im blauen Feld)
    Bei einer Änderung/Ergänzung oder Löschung werden die auch nicht berührt.
    [ATTACH=JSON]{"data-align":"none","data-size":"full","data-tempid":"temp_2132_1571834056275_64","title":"Formular"}[/ATTACH][IMG2=JSON]{"data-align":"none","data-size":"full","src":"https:\/\/seo-nw.de\/image\/gif;base64,R0lGODlhAQABAPABAP\/\/\/wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="}[/IMG2]
    Das macht der PHP-Code vom obigen Posting.
    Zum löschen hab ich einfach die $Post-Werte leer gelassen.

    Das klappt auch alles wunderbar.

    --------------
    ABER :)

    Ich weiß nicht, wie ich den Wert "Hex_Wert" (s. im Bild als 1 markiert) in alle anderen Farbtiefe_19-Felder (ist als 2 markiert) der Farbnummer SH 200 reinschreiben kann.
    [ATTACH=JSON]{"data-align":"none","data-size":"full","data-tempid":"temp_2133_1571835001289_713","title":"db-farbtiefe.PNG"}[/ATTACH][IMG2=JSON]{"data-align":"none","data-size":"full","src":"https:\/\/seo-nw.de\/image\/gif;base64,R0lGODlhAQABAPABAP\/\/\/wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="}[/IMG2]

    Denn diese Werte brauche ich, damit ich die Farbfelder hier darstellen kann:
    [ATTACH=JSON]{"data-align":"none","data-size":"full","data-tempid":"temp_2134_1571835154687_658","title":"db-farbfelder.PNG"}[/ATTACH][IMG2=JSON]{"data-align":"none","data-size":"full","src":"https:\/\/seo-nw.de\/image\/gif;base64,R0lGODlhAQABAPABAP\/\/\/wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="}[/IMG2]

    Die erzeuge ich mit folgendem stümperhaftem Code:

    Ich verfolge gerade folgenden Gedankengang, aber ich hab keine Ahnung, ob ich mich da nicht wieder total verrannt habe:

    Aber ich bin mir sicher, da gibt es irgendeinen Haken^^ Kann man die updates nicht irgendwie verschachteln? Oder eleganter schreiben?
    Und arbeitet der die updates dann tatsächlich nacheinander ab?
    Und wie gestalte ich dann das execute?

    Wer zuerst "Datenschutz" sagt, hat verloren.

  • Also ich komme noch nicht wirklich weiter, weil ich die Zusammenhänge noch nicht sehe.

    "in alle anderen Farbtiefe_19-Felder (ist als 2 markiert) der Farbnummer SH 200 reinschreiben kann."

    Da gibt es doch nur eines, laut Deinem DB-Bild. (mit 2 ist hier nix markiert).

    Du hast die Tiefe 19 pro Farbwert doch nur einmal, oder? Also SH200-19, dann SH201-19, SH202-19 uns. Also einmal die Tiefe 19 pro Farbe.

    Deine Query oben mit den vielen "SET Farbtiefe_XX" wird nicht funktionieren, denn es gibt im Bereich "SET" kein OR in dem Sinne. Da kommt nur eine Liste, was ersetzt werden soll und mit was. Also so wie Deine zweite Query am Ende.

    Achso, jetzt komme ich etwas weiter. Da gibt es ja noch mehr Felder. Das Bild ist leider winzig. Da ist die "SH_Farbnummer", die "Farbtiefe" und dann noch die 20 "Farbtiefe_01 bis Farbtiefe_20". Dachte die ganze Zeit, Du redest mit den 1-12 von den 20 Datensätzen im Sinne vom Feld "Farbtiefe".

    Aber so ganz schlau werde ich immer noch nicht....

    damit "WHERE `SH_Farbnummer` = :sh_farbnummer AND `Farbtiefe` = :farbtiefe"" Sprichts Du ja quasi nur einen Datensatz an.

    Das Problem ist ja, man sieht nicht alles. Mache das doch bitte mit reellen Beispielen, also auch mit echten Farbwerten und nicht mit "Variablen". Deine Query oben, die wo nicht gehen kann, würde, wenn die gehen würde, genau einen Datensatz ändern, nämlich limitiert durch "WHERE `SH_Farbnummer` = :sh_farbnummer AND `Farbtiefe` = :farbtiefe"". Klar würde die letztendlich mehr ändern, wenn die in einer Schleife läuft und die WHERE_Bedingung bzw. deren Variablen sich in der Schleife ändern. Das sieht man aus dem Code aber nicht.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • Hm... also ich sehe die Bilder aus meinem letzten Posting gar nicht.
    Das ist sicher wieder Alex Schuld. In der Vorschau waren die noch da.
    Also hier das Bild der DB mit den Markierten Positionen 1 und 2.
    Der wert in Spalte Hex_Wert, also #005e73, sollte auch in allen Feldern der Spalte Farbtiefe_19 (bei Position 2) reingeschrieben werden, WENN die Farbnummer (SH 200) dieselbe ist UND WENN der Wert in der Spalte Farbtiefe (19) ist.

    Ändere ich den Eintrag darunter, dann soll der Hex_wert #007289 in der Spalte Farbtiefe_18 reingeschrieben werden, WENN die Farbnummer SH 200 ist UND WENN der Wert in Spalte Farbtiefe 18 ist.
    [ATTACH=JSON]{"data-align":"none","data-size":"full","data-attachmentid":123956}[/ATTACH]

    Und ich hoffe, man kann das scheiss Bild jetzt sehen^^ Mehr als 800px kann ich hier nicht reinstellen.

  • Ok, also lag ich doch gar nicht so schlecht.

    Du merkst, dass an dieser Bedingung was nicht passen kann: "Der wert in Spalte Hex_Wert, also #005e73, sollte auch in allen Feldern der Spalte Farbtiefe_19 (bei Position 2) reingeschrieben werden, WENN die Farbnummer (SH 200) dieselbe ist UND WENN der Wert in der Spalte Farbtiefe (19) ist."

    Du sagst wenn "SH200 und Farttiefe 19"..... "Dann ändere diesen Datensatz und alle anderen im Feld Farbtiefe_19. Das geht nicht, das ist ein WENN zu viel.

    Denn wenn Du mit WENN "SH200 und Farbtiefe 19" arbeitest, dann ist das ja quasi nur ein Datensatz, eben die ID 2002 (Die Kombi SH200 + 19 ist ja quasi auch ein Index, auch wenn der nicht definiert sein mag, gibt es aber nur EIN MAL). Da kannste dann nix updaten, das in einem anderen ist, denn die anderen sind ja gar nicht von der Bedingung erfasst und stehen somit nicht zur Verfügung.

    So, aber nun habe ich es verstanden. Du willst also den HEX_Wert aus dem Datensatz von "SH200 + 19" in alle anderen "Farbtiefe_19" schreiben, die als Bedingung nur "SH200" haben.

    Ehrlich gesagt ist dafür das Datenbankschema etwas schlecht gewählt. Da hätteste die Farbtiefe_01 bis Farbtiefe_20 in eine eigene DB schreiben sollen und dann eben einfach per "Farbtiefe_ID" kombinieren. Dann würden die da auch nicht doppelt und dreifach, oder eben 20-fach per SH-Farbnummer drinnen stehen, sondern nur einmal. Gut, aber auch so möglich.

    So, aber an Deinem Bild sieht man ja sehr gut, dass das so nicht geht, nicht mit einer einzelnen Query. Grund: Du hast da Bedingungen markiert, die einmal vertikal und einmal horizontal sind. Das geht schlicht nicht so einfach, denn die Datenbank arbeitet ja "zeilenweise" ab.

    Zwei Möglichkeiten als Ansatz. Aber wirklich nur als Ansatz für den weiteren Gedankengang:

    1. Mit Sub-Selects. Vorteil: Eleganter, Performanter. Nachteil: Kompliziert und fehleranfällig
    2. Mit einer zweiten Query, einem Select davor. Nachteil: weniger elegant, eine Query extra, also langsamer. Vorteil: Übersichtlich und pflegeleicht

    Ich würde prinzipiell, wenn es nicht auf die letzte Millisekunde ankommt, Weg 2 gehen, also in etwa so:

    Erst mal Deine erste Bedingung erfüllen bzw. ermitteln. Also Deinen Hex-Wert aus der Zeile SH200_19

    SELECT Hex_Wert FROM Datenbank WHERE SH_Farbnummer = 'SH 200' AND Farbtiefe = 19

    ^^ das ist also Deine erste Bedingungen. Den Hex-Wert von diesem einen Row, der dann später in alle anderen Farbtiefe_19 soll

    Also den SELECT entsprechend ausführen (als PDO umbauen) und den zurückgegebenen Wert (Hex_Wert) in einer Variable speichern.

    Dann Deine zweite Bedingung, nämlich das Update von allen Farbtiefe_19 mit der Farbnummer "SH 200".

    Also ein

    Update DATENBANK SET Farbtiefe_19 = 'hier der vorher abgerufene Hexwert aus dem SELECT' WHERE SH_Farbnummer = 'SH 200'

    ^^ hier ist die Bedingung also nur noch "alle mit Farbnummer SH200".

    Das sind im Grunde zwei ganz einfache Queries. Einmal den Wert aus einem bestimmten Datensatz abfragen und dann diesen Wert in mehrere andere Datensätze reinschreiben.

    Das mit dem Subselect wäre ähnlich. Bei dem müsste der Subselect dann an die Stelle wo bei mir oben "hier der vorher abgerufene Hexwert aus dem SELECT" steht eingefügt werden. Der würde dann anhand seiner eigenen Bedingung den Wert aus einer anderen Zeile lesen. Der ist also in der Lage, Row-übergreifend zu agieren. Aber wie gesagt, der geht anders. Einfach die Select-Query da einfügen ist nicht, schon gar nicht mit Prepare und PDO.

    Bei diesem Gebilde muss die Datenbank immer zwei Selects ausführen. Per Subselect schickst Du nur eine Query per PHP, die aber aus zwei besteht. Ohne Subselect schickst Du quasi zwei einzelne per PHP.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • OK. Danke erstmal. Jetzt hab ich was zu probieren :)

    Das mit der einen Tabelle kam irgendwie so zustande, weil ich vorher gar nicht mit Farbtiefen gerechnet hatte.
    Ich war mit der Seite eigentlich schon fertig, da kam dann Jojo an und meinte, sie will da noch 20 Farbtiefen haben.

    Und in meinem jugendlichen Leichtsinn dachte ich, ich kann das einfach so reindengeln...

    Wer zuerst "Datenschutz" sagt, hat verloren.

  • Also sollte so gehen, auch mit PDO. Da haste schon kompliziertere Abfragen bei FB gehabt. Hier sind es nun zwei mit je 1 oder 3 "Platzhaltern" fürs Prepare.

    Aber mal so am Rande. Den Sinn dahinter verstehe ich noch nicht ganz, auch wenn das so gehen mag und Jojo das wollte. Aber Du hast für die z.B. SH_200 ja 20 Datensätze. Eben mit Farbtiefe 01 bis 20. Bei jeden ist der hier angesprochene HEX-Wert, den Du nun in die anderen Felder Updaten willst.

    Warum gehst Du dann nicht einfach für die Darstellung her und selektierst von allen 20 Datensätzen von z.B. SH_200 die Werte Farbtiefe und HEX? Das sind dann 20 Ergebnisse und die kannste in einer Schleife ganz normal anzeigen. Per "Farbtiefe" notfalls sortieren.

    Du hast nun ja im Grunde bei allen SH_200-xx in den Spalten Farbtiefe_01 bis Farbtiefe_20 das gleiche stehen, wobei genau diese Werte schon als "Hex-Wert" im eigentlich Row stehen.

    Du könntest also einfach sagen:

    Eine Query, die das Produkt an sich anzeigt, also einen bestimmten Artikel und dann als zweite Query alle Hex-Werte der Datensätze mit dieser speziellen Farbnummer.

    Das ist dann beim Produkt eine Query mehr, für die Farbwerte, aber dafür ist die Datenbank ausgelegt. Das erspart aber das mehrfach redundante vorhalten und updaten der Farbtiefe_xx.

    Und als Anmerkung, hat damit nix zu tun, sondern mit einem Post bei FB. Weiß da nur nicht, wie ich antworten soll, denn da sind schon "komische Vögel" mit dabei zu kommentieren. Du sagtest mal was, dass Dein Error.log voll läuft mit "undefind Index" oder so ähnlich. Das ist vollkommen klar, denn Du hattest in der Update-Query ein $_POST[""] als Variable. Das gibt es natürlich nicht. Es gibt keinen Index [""] bei einem POST-Array. Warum nimmst Du da als Variable nicht einfach einen leeren String im Sinne von "" oder notfalls, wenn PDO eine Variable will und keinen String, eine Variable die vorher einfach als $leere_var = '', definiert wurde.

    Du greifst mit dem $_POST[""] quasi immer auf das globale Array zurück, was schon langsamer ist und dann auch noch auf einen Index, der nicht existieren kann, nämlich keinen. Und "keinen" ist hier eben nicht "gibt es nicht" oder "null", sondern ein leerer Index.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • Um es bildlich zu sagen, was ich sagen wollte.

    [ATTACH=JSON]{"alt":"Klicke auf die Grafik f\u00fcr eine vergr\u00f6\u00dferte Ansicht Name: catcat-2.jpg Ansichten: 0 Gr\u00f6\u00dfe: 70,2 KB ID: 123980","data-align":"none","data-attachmentid":"123980","data-size":"full","title":"catcat-2.jpg"}[/ATTACH]

    Du hast also schon alle Hex-Werte in der Datenbank (im Bild Bereich Nr. 1). Dann gehst Du her und nimmst z.B. die Tiefe 14 (Bild Datensatz Nr. 2) und kopierst die in alle anderen SH_200_xx ins Feld Farbtiefe_14 (Nr. 3).

    Das muss nicht sein, denn die Daten sind ja schon da, eben bei den einzelnen SH-Farbnummern. Die musst Du nur abfragen und sortiert ausgeben, z.B. sortiert von Farbtiefe 1 bis 20. Und wenn die Rückgabe "leer" ist, dann einfach scharz anzeigen, ansonsten den Wert, der aus der DB kommt.

    Das aber nur als Überlegung. Wenn Du natürlich hunderte von Farbabstufungen gleichzeitig abfragst, dann wäre das jeweils eine Query mehr. Da macht dann Redundanz eventuell schon Sinn. Aber es kommt eben auf den Anwendungsfall an. Wollte also damit nur sagen. Die Daten sind schon da. Von dem, was man hier aus den Posts weiß, macht es nicht viel Sinn, kann es aber.