• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

SQL Insert - Frage

RedlightX

Bekannter NGBler

Registriert
18 Juli 2013
Beiträge
1.185
Hallo zusammen,

schon meine Mutter sagte immer, dass es keine blöden Fragen gibt, deshalb wage ich es mal:

Ich möchte: Einen Datensatz in eine Datenbank schreiben.

Ich habe: 2 Tabellen (Kategorie und Snippet)

Kategorie: kategorie_ID (Primary Key), bezeichnung

Snippet: snippet_ID (Primary Key), bezeichnung, code, kategorie_ID (Foreign Key) und tags


Das Problem ist folgendes:

Ich habe ein Formular, das mittels POST die Daten an ein PHP-Script übergibt, welches dann den Datensatz in die Datenbank schreibt. Meine SQL-Abfrage sieht momentan so aus:

[src=mysql] $sql = "INSERT INTO Snippet(titel, bezeichnung, code, kategorie_ID, tags) VALUES (:inputTitle, :inputDescription, :inputSnippet, (SELECT kategorie_ID FROM Kategorie WHERE Kategorie.bezeichnung = :inputCategory JOIN Kategorie ON (Katgorie.kategorie_ID = Snippet.kategorie_ID), :inputTags)";[/src]

Er soll natürlich beim Snippet anhand der im Formular ausgewählten Kategorie, die sich schon in der Datenbank befindet, den entsprechenden Fremdschlüssel in der Tabelle Snippet (kategorie_ID) einsetzen.


Mag mir jemand sagen, was an meiner Abfrage falsch ist? :/


Danke :T
 

KaPiTN

♪♪♫ wild at heart ♪♫♫♪

Registriert
14 Juli 2013
Beiträge
29.138
Müßte das nicht "JOIN Snippet" heißen, statt "JOIN Kategorie"?
 

RedlightX

Bekannter NGBler

Registriert
18 Juli 2013
Beiträge
1.185
  • Thread Starter Thread Starter
  • #3
Auch damit geht es leider nicht - folgende Meldung kommt:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'JOIN Snippet ON (Katgorie.kategorie_ID = Snippet.kategorie_ID), 'sql')' at line 1

Ich fürchte ja, dass der Fehler wahrscheinlich hier irgendwo liegt: WHERE Kategorie.bezeichnung = :inputCategory, da ich nicht weiß, ob man diesen POST-"Platzhalter" da einsetzen kann. Generell bin ich mir unsicher, ob ich da einfach eine Select-Abfrage im Insert einbauen kann/darf :/
 

werner

Suchtspielmacher (ehm.)

Registriert
20 Juli 2014
Beiträge
743
Ort
Mannheim
Wofür brauchst du dort den Doppelpunkt? Ist das überhaupt korrekte Syntax? Habe ich so noch nie gesehen
 

RedlightX

Bekannter NGBler

Registriert
18 Juli 2013
Beiträge
1.185
  • Thread Starter Thread Starter
  • #6
Ja, ich nutze PDO, danke für die bisherigen Antworten. Ich hätte nicht gedacht, dass man da diese Umwege gehen muss. Ist sowas nicht alltäglich?

--- [2016-05-14 02:23 CEST] Automatisch zusammengeführter Beitrag ---

Für die Nachwelt:

Ich habe es mit 2 SQl-Statements gemacht.

Kategorie_ID der mittels POST übertragenen Kategorie zurückgeben lassen, diese gespeichert und im 2. Query als Value angegeben...
Das Leben könnte ja so einfach sein - wenn man weiß, wie es funktioniert.


Es hat gedauert, aber ich werde mit einem Lächeln einschlafen können :D
 

X-Coder

Aktiver NGBler

Registriert
14 Juli 2013
Beiträge
149
Da der Join oben 1. unnötig und 2. an der falschen Stelle war, hätte es mit dem Subselect von oben so ausgesehen:
[src=mysql]INSERT INTO Snippet(titel, bezeichnung, code, kategorie_ID, tags)
VALUES (:inputTitle, :inputDescription, :inputSnippet,
(SELECT kategorie_ID FROM Kategorie WHERE Kategorie.bezeichnung = :inputCategory), :inputTags)
[/src]

Probleme bekommst du so nur wenn die Kategoriebezeichnung mehrfach oder gar nicht vorkommen sollte.
 

Shodan

runs on biochips

Registriert
14 Juli 2013
Beiträge
661
Ort
Citadel Station
Ich rate dir davon ab in den Klammern von VALUES diese Form von Subquery zu verwenden! Erlaubt sind dort nur scalare Werte (bzw Ausdrücke, die solche ergeben), ein Subquery ist aber eine Liste von Listen von Werten:
Beipiel: SELECT a,b,c,.. FROM X;
(
(1, 2, 4, ...),
(n, g, b, ...),
...
)

Ok, du hast exakt ein Attribut im SELECT, also ist es eine Liste von Listen der Länge 1:
((1), (n), ...)
und du weißt, dass, wegen dem WHERE, nur eine solche Liste ausgegeben werden wird, also ((1)).
Man nennt das einen "Scalaren Subquery", also einen Subquery der einen Scalar zurückgibt.
Syntaktisch darfst du diesen also in VALUES verwenden. Aber es ist keine gute Idee. Wenn es nun doch mal passiert, dass es mehr als einen Eintrag für die Bezeichnung in Kategorie gibt, dann crasht es.
Mit einem LIMIT kannst du forcieren, dass er Scalar bleibt, aber es sollte klar sein, dass um Dateninkonsistenzen "herumzucoden" irgendwie der falsche Ansatz ist.

Praktischerweise gibt es noch INSERT ... SELECT:
[src=mysql]INSERT INTO Snippet (titel, bezeichnung, code, kategorie_ID, tags)
SELECT :inputTitle, :inputDescription, :inputSnippet, kategorie_ID, :inputTags FROM Kategorie WHERE Kategorie.bezeichnung = :inputCategory;[/src]

Das Subquery ergibt nun eine Liste von Listen der Länge fünf.
Und wir wissen, dass mit dem WHERE daraus eine Liste mit exakt einer Liste der Länge 5 erzeugt wird.
Wenn die selbe Bezeichnung in deiner Kategorie Tabelle nun zwei mal vorkommen würde, dann ergibt das Subquery eine Liste mit zwei Listen mit fünf Werten. Und INSERT fügt dann fröhlich zwei Datensätze in Snippet ein: Einen für jeden der zwei kategorie_ID Werte der Bezeichnung.
Ob dieser Umgang mit der theoretischen Dateninkonsistenzen besser ist als ein Crash sei mal dahingestellt ;-)

Aber genug der Theorie. ("Das Leben könnte ja so einfach sein - wenn man weiß, wie es funktioniert." - once said by a wise man) kommen wir nun zur Praxis:
Ich vermute einfach mal, dass dein Formular keine Freitext-Eingabe für die Kategorie hat (sonst müsstest du ja sowieso erst einmal nach sehen, ob es diese schon gibt und, wenn nicht, eine neue Kategorie erstellen), sondern dass es sich um eine select-Tag (Drop-Down Auswahl) handelt, in dem du die Kategorien aus der Datenbank aufführst. Ist dies der Fall, dann schreib doch in das value-Attribut der option-Tags lieber die ID rein, statt die Bezeichnung. Denn dann sendet dir der Client per POST direkt die ID ;-)


Achja: Wie X-Coder schon sagte: Der JOIN steht an der falschen Stelle, daher der Syntax-Error. Korrekt wäre FROM Kategorie JOIN ... Aber das nur nebenbei
 
Zuletzt bearbeitet:

RedlightX

Bekannter NGBler

Registriert
18 Juli 2013
Beiträge
1.185
  • Thread Starter Thread Starter
  • #9
Danke euch beiden für eure Antworten - es klappt und ich habe wieder was gelernt :T

Die Idee mit der ID im Value-Tag klingt einleuchtend, das werde ich mal einbauen!
Und ja, die Kategorien werden direkt aus der Datenbank geholt und können separat über ein Modal angelegt werden
 
Oben