Fehlendes Semikolon am Ende der SQL-Anweisung ?

  • SQL

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Fehlendes Semikolon am Ende der SQL-Anweisung ?

    Hallo liebes Forum !

    Ich würde gerne einige Werte in meiner Datenbank updaten und benutze dazu WHERE sowie ORDER BY. Das ganze schaut so aus:

    Quellcode

    1. SQLstr = String.Format("UPDATE Tabelle1 SET Wert3 = '" & Wert3.Text & "', Datum2 = '" & Datum2.Text & "', Zeit2 = '" & Zeit2.Text & "', Wert4 = '" & Wert4.Text & "' WHERE Wert1 = '" & Wert1.Text & "' AND Wert2 = '" & Wert2.Text & "' AND Datum1 = '" & Datum1.Text & "' AND Wert5 = '" & Wert5.Text & "' ORDER BY Zeit1 DESC")


    Als Fehlermeldung bekomme ich "Fehlendes Semikolon am Ende der SQL-Anweisung" bekommen. Najo, hab dann hinten bei ... BY Zeit1 DESC;") ... das Semikolon angefügt, aber die Fehlermeldung bleibt die gleiche :(
    Wenn ich das ORDER BY Zeit1 DESC rausnehme funktioniert es. Nur kann es dann sein, dass der falsche Eintrag mit dem Update versehen wird, da viele Einträge identisch sind und sich nur anhand der Zeitwerte unterscheiden.
    Ist das eigl soweit richtig gedacht ? Oder ist ORDER BY hier komplett falsch am Platz ? Gäbe es eine andere Möglichkeit wie ich Filtern kann ? ?(

    LG,
    DDD
    Zunächst:

    Ziel ist es, jeden Datensatz mit einem eindeutigen KEY zu versehen. -> PRIMARY KEY.
    Somit kannst du immer, auch ohne den Zeit1-Wert des jeweiligen Datensatzes zu kennen, dein Update ausführen.
    bspw:
    Primary KeyValueZeit
    1TestVal2017-01-01 12:00:00
    2WeitererTestVal2017-01-01 12:00:00


    So, nun siehst du, wenn der Zeit-Wert von dir mit eingetragen wird per update oder so, kann er doppelt vorhanden sein. D.h.: Dein Update where Zeit=<wert> hat beim sortieren die Qual der wahl welchen er updaten soll.

    Besser: Geh über die ID, die ist eindeutig für jeden Datensatz und du weißt immer, ob du 1 oder 2 Updaten willst.

    Zum anlegen in der DB schau dir die Schlüsselworte Primary Key sowie Autoincrement an, damit kommst du erstmal weiter. Da ist dann auch dein Problem mit dem ORDER BY erledigt.


    LG Acr0most

    PS: So als Richtlinie:
    Bei einem UPDATE sollte immer der Range explizit eingegrenzt sein. (genaue ID, ID-Range). In einem UPDATE wird (selten bis) gar nicht mit ORDER BY gearbeitet.
    Bei einem SELECT ist das anders. Hier holst du dir Daten und es könnte relevant sein in welcher Reihenfolge die bei dir ankommt. Deshalb macht da ORDER BY Sinn.
    Wenn das Leben wirklich nur aus Nullen und Einsen besteht, dann laufen sicherlich genügen Nullen frei herum. :D
    Signature-Move 8o
    kein Problem mit privaten Konversationen zu Thema XY :thumbup:

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Acr0most“ ()

    Order by gibt es im Update nicht. Order By macht nur Sinn wenn dein SQl-Befehl auch Treffer zurück liefert.

    Meines Wissens müsste das ungefähr so gehen:

    Quellcode

    1. ​SQLstr = String.Format("UPDATE Tabelle1 SET Wert3 = '" & Wert3.Text & "', Datum2 = '" & Datum2.Text & "', Zeit2 = '" & Zeit2.Text & "', Wert4 = '" & Wert4.Text & "' WHERE (SELECT * FROM Tabelle1 WHERE Wert1 = '" & Wert1.Text & "' AND Wert2 = '" & Wert2.Text & "' AND Datum1 = '" & Datum1.Text & "' AND Wert5 = '" & Wert5.Text & "' ORDER BY Zeit1 DESC"))


    Allerdings ist die Lösung von @Acr0most mit der eindeutigen ID besser und sollte bevorzugbehandelt werden.
    There is no CLOUD - just other people's computers

    Q: Why do JAVA developers wear glasses?
    A: Because they can't C#

    Daily prayer:
    "Dear Lord, grand me the strength not to kill any stupid people today and please grant me the ability to punch them in the face over standard TCP/IP."

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Schamash“ ()

    @DingDangDong dein String.Format() macht Nichts. Entweder lass es weg, oder benutz es richtig:

    VB.NET-Quellcode

    1. String.Format("UPDATE Tabelle1 SET Wert3='{0}',Datum2='{1}',Zeit2='{2}',Wert4='{3}' WHERE Wert1='{4}' AND Wert2='{5}' AND Datum1='{6}' AND Wert5='{7}'", Wert3.Text, Datum2.Text, Zeit2.Text, Wert4.Text, Wert1.Text, Wert2.Text, Datum1.Text, Wert5.Text)
    2. 'Ich gehe mal davon aus, dass Wert3 und co. Controls sind, was wiederum eine ziemlich blöde Idee ist.
    SQL-Injection und so.

    Edit:
    Achja, der Code ist keine Problemlösung, sondern nur Beispiel für die Benutzung von String.Format()

    Edit2:
    Seit VS15 gibt es sogar String Interpolation:

    VB.NET-Quellcode

    1. SQLstr = $"UPDATE Tabelle1 SET Wert3 = '{Wert3.Text}', Datum2 = '{Datum2.Text}', Zeit2 = '{Zeit2.Text}', Wert4 = '{Wert4.Text}' WHERE Wert1 = '{Wert1.Text}' AND Wert2 = '{Wert2.Text}' AND Datum1 = '{Datum1.Text}' AND Wert5 = '{Wert5.Text}'"

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „EaranMaleasi“ ()

    DingDangDong schrieb:

    Wenn ich das ORDER BY Zeit1 DESC rausnehme funktioniert es. Nur kann es dann sein, dass der falsche Eintrag mit dem Update versehen wird, da viele Einträge identisch sind und sich nur anhand der Zeitwerte unterscheiden.


    Das ist zu kurz gedacht. Denn dein Update aktualisiert nicht einen bzw. den "ersten" gefundenen Datensatz. UPDATE aktualisiert IMMER ALLE Datensätze, auf die die WHERE-Bedingung zutrifft.

    Wenn du definitiv nur den Datensatz mit dem niedrigsten Zeitwert aktualisieren willst, bleiben dir nur zwei Möglichkeiten:

    a) Wie beschrieben einen ordentlichen Primary Key etablieren und den Datensatz anhand dieses Keys selektieren.

    b) Das UPDATE Statement mit einer Unterabfrage erweitern, die zunächst den niedrigsten Zeitwert bei den gegebenen anderen Parametern ermittelt und diesen in das WHERE vom UPDATE mit aufnehmen. Das ist aber sehr aufwändig und ich mache mir jetzt ehrlich gesagt nicht die Mühe, das ordentlich als SQL-Befehl auszuformulieren.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Huiui Danke euch vieren für euren Input - da werd ich ein bissl dran zu knabbern haben ^^

    @Acr0most
    Stimmt - so hätte ich dann zwei Datensätze mit dem gleichen Zeitwert.
    Vielleicht hole ich ein bissl weiter aus und erkläre kurz worum es bei dieser Datenbank geht, bzw wie sie sich füllt:
    Mit VS2017 habe ich eine simple GUI erstellt und das ganze soll eine einfache Zeiterfassung werden, die nur auf einem Rechner läuft. Von dem her kann es den Zeitwert nur einmal geben, weil das "einstempeln" auf einen Auftrag länger als 1 Sekunde dauert :D

    Beim erstmaligen einstempeln wird dann ein Eintrag mit Auftragsnummer, Mitarbeiter, Datum & Zeit erstellt.
    Beim ausstempeln suche ich nach Auftragsnummer, Mitarbeiter, Datum und vorallem Zeit um dann den Datensatz zu vollenden.
    Wie stelle ich es denn an, dass sich die ID gemerkt wird bis man wieder ausstempelt ?
    Bei mehreren Personen wird ja auch quer ein und ausgestempelt, also kann ich mich nicht nur auf die letzte aktuelle ID beziehen :huh:

    @Schamash
    Aaah das erklärts natürlich :)
    Ich versuche mal ein wenig mit deinem SQL-String rumzuspielen. Ist das dann sowas wie eine Sub Abfrage ?

    @EaranMaleasi
    Oh, ich hatte das mal irgendwo in einem Tutorial gelesen, dass es besser wäre eine SQL-Abfrage so zu beginnen.
    Wahrscheinlich habe ich nur die Hälfte gelesen :rolleyes: :D
    Aber Danke für das Beispiel, immer wieder interessant auf welch unterschieldiche Arten man eine Abfrage gestalten kann =O wahrscheinlich jede mit ihren individuellen Vor- und Nachteilen, oder ?
    Die String Interpolation ist dann die aktuellste Variante ?

    @Arby
    Wäre Option (B) dann in der Art von Schamash's Beispiel ?

    LG,
    DDD
    das beste wäre (m.m.n) wenn du für jede Aktion einen Datensatz erstellst.

    Sprich einstempeln:



    IDMitarbeiter-IdTimestampType
    122017-01-01 08:00:00S
    222017-01-01 16:00:00E


    Hier hast du dann Zeitpaare. Start-Stempel (S) , End-Stempel (E)

    Dadurch ersparst du dir Updates & musst dir nichts merken.

    Zur Auswertung:

    Dann hast du die effektive Arbeitszeit indem du dann die Timespan zwischen Start und End-stempel berechnest.
    Minus eben Pausen-Zeiten oder Zwischenstempel (Raucherpause etc.)

    Sprich du holst dir alle Stempel zu MA-ID 2 und berechnest dann die Differenzen zwischen allen Start/End-Pärchen


    LG Acr0most
    Wenn das Leben wirklich nur aus Nullen und Einsen besteht, dann laufen sicherlich genügen Nullen frei herum. :D
    Signature-Move 8o
    kein Problem mit privaten Konversationen zu Thema XY :thumbup:
    Au Klasse, an eine Variante mit Pärchen hab ich garnicht gedacht.
    Da war ich wohl zu sehr darauf fixiert alles in einen Datensatz zu packen, aber stimmt - so spare ich mir das Updaten und kann eigl auch zu keinem Konflikt kommen :)


    Die Idee find ich Super - Danke 8-)

    DingDangDong schrieb:

    jede mit ihren individuellen Vor- und Nachteilen, oder ?
    Die String Interpolation ist dann die aktuellste Variante ?
    Das Verketten von Strings mit &, string.Format(), und String Interpolation sind alles Kompromisse zwischen Verständlichkeit und Programmierbarkeit. Hast du nur 2 Sachen zum Verbinden kann man schon mal nen & setzen, wird aber relativ schnell schwer verständlich, sobald es mehr als nur 2 Strings sind. Dafür gibt es dann String.Format(), mit dem man dann schon ziemlich viele Sachen gut leserlich verbinden kann. Man darf sich nur nicht verzählen, oder anfangen die Zahlen kreuz und quer in den String einzubauen, dann kann es auch schnell chaotisch werden. Diese beide Sachen sind fest ins Framework eingebaut, von 2.0 bis was auch immer noch kommen mag, und wird von jeder VS Version verstanden. String Interpolation hingegen ist ein reines "Compilerfeature". Dies bedeutet, dass der Compiler das was du da schreibst hernimmt, und es Bspw. in ein String.Format() umbaut (Nur meine Vermutung, vllt. macht er auch was völlig anderes). Jedoch wissen die Compiler von VS13 und abwärts nichts davon und so kann ein Projekt, dass für .NET 2.0 ausgelegt ist, jedoch mit VS15 und aufwärts programmiert wurde, nicht von älteren VS Versionen compiliert werden, wenn solche compilerfeatures benutzt wurden. Der größte Vorteil von String Interpolation ist die IntelliSense Hilfe mitten im String, wodurch man um einiges Schneller seine verketteten Strings aufbauen kann. Größter Nachteil (nur meine Meinung) ist, dass dies sehr schnell unleserlich wird, wenn man noch Funktionsaufrufe macht, oder die verschiedenen Null-Operatoren bzw. Inline-If-Else benutzt.

    DingDangDong schrieb:

    da hab ich wohl noch guten Lernbedar
    Jo.

    Mein Punkt ist, du solltest dir diesen Stil Sql einzusetzen garnet erst angewöhnen.
    Deine Vorgehensweise öffnet nämlich jedem Nutzer ein Riesen-Sicherheitsloch: SqlInjection.
    gugge Sql-Injection

    Natürlich bist du momentan der einzige User, aber wenn du jemals was zur Veröffentlichung bestimmtes coden willst, dann ist diese Vorgehensweise fast kriminell fahlässig.

    Wie gesagt: Gewöhn dir den Sch... gar nicht erst an, sondern lerns gleich richtig, nämlich mit parametrisierten DbCommands.