Seite 3 von 3

Verfasst: 30.05.2007 10:23
von Kiffi
PureBasic4.0 hat geschrieben:Wenn ein Eintrag mit der ID 2 gelöscht wird, soll kein Eintrag, der sonst die ID 3 hat, auf die Position mit der ID 2 rutschen.
und genau dafür ist der Autowert da. Da rutscht nichts und jeder Eintrag
hat eine eindeutige und unveränderbare ID. Und das beste: Du brauchst
Dich um nix zu kümmern. Das Ermitteln und Eintragen der neuen ID
übernimmt die DB für Dich. Kann es sein, dass Du beim Lesen der vielen
Bücher über SQL dieses Kapitel immer übersprungen hast?

Bei Deinem Code vermute ich die Schwachstelle hier:

Code: Alles auswählen

_id = Anzahl
Das lässt darauf schließen, dass Du in Deiner ominösen Prozedur zum
ermitteln der neuen ID die Anzahl der Datensätze nimmst. Bei folgendem
Szenario ist das fatal:

1.) 10 Datensätze vorhanden
2.) Neuen Datensatz hinzufügen
3.) Neuer Datensatz hat die ID 11
4.) Fünften Datensatz löschen
5.) Neuen Datensatz hinzufügen
6.) Neuer Datensatz hat die ID 11

Und schon haben zwei Datensätze die selbe ID.

Grüße ... Kiffi

Verfasst: 30.05.2007 10:42
von PureBasic4.0
Habe jetzt mal den SQLBrowser runtergeladen, den mir Thorsten1867 gezeigt hat. Dort wird meine DB-Struktur so angezeigt:

http://antonwuerfel.an.ohost.de/PureBoa ... sql_ip.jpg

Wenn ich aber meine SQL Abfrage ausführe kommt folgender Fehler:

http://antonwuerfel.an.ohost.de/PureBoa ... sql_ip.jpg

Die DB meldet, dass es keine Spalte Namens Netzwerkgeraet in der DB Shortcuts gibt. Wie man aber an obiger Struktur erkennen kann, gibt es die Spalte Netzwerkgeraet. Was mache ich jetzt schon wieder falsch??? :oops: :cry:

@Kiffi: Hier ist nochmal der gesamte Code. Vom ElseIf bis zum abschließenden ElseIf. Da kann man gut sehen, wo die Variable Anzahl herkommt.

Code: Alles auswählen

    ElseIf GadgetID = #Verk_OK
      If verok = 1
        ClearList(Verknuepfungszahlen())
        DateiName$ = SaveFileRequester("","*.lnk","Verknüpfung|*.lnk",0)
        If DateiName$ <> ""
          If LCase(GetExtensionPart(DateiName$)) <> "lnk"
            DateiName$ + ".lnk"
          EndIf
          SqlString$ = "SELECT ID FROM Shortcuts"
          SQLiteGetTable(DBHandle,SqlString$,Table)
          If Table
            SQLiteNextCol(Table)
            While SQLiteNextRow(Table)
              Ergebnis$ = SQLiteValue(Table)
              AddElement(Verknuepfungszahlen())
              Verknuepfungszahlen() = Val(Ergebnis$)
            Wend
            ResetList(Verknuepfungszahlen())
            ok = 0
            Anzahl = -1
            Repeat
              Anzahl + 1
              ok = 1
              ForEach Verknuepfungszahlen()
                If Anzahl = Verknuepfungszahlen()
                  ok = 0
                  Break
                EndIf
              Next
            Until ok = 1
          EndIf 
          Profil$ = GetGadgetText(#Verk_Profil)
          Netzwerkg$ = GetGadgetText(#Verk_Netzwerkg)
          Warnung = GetGadgetState(#Verk_SWarnung)
          BestMld = GetGadgetState(#Verk_BestM)
          SqlString$ = "SELECT ID FROM Shortcuts WHERE Profil = '"+Profil$+"' AND Netzwerkgeraet = '"+Netzwerkg$+"' AND Warnung = "+Str(Warnung)+" AND Bestaetigung = "+Str(BestMld)
          Debug SqlString$ 
          SQLiteGetTable(DBHandle,SqlString$,Table)
          ok = 0
          _id = -1
;          SQLiteNextCol(Table)
          While SQLiteNextRow(Table)
            ok = 1
            Ergebnis$ = SQLiteValue(Table)
            ID = Val(Ergebnis$)
            Break
          Wend
          If ok = 0
            SqlString$ = "INSERT INTO Shortcuts VALUES("+Str(Anzahl)+",'"+Profil$+"','"+Netzwerkg$+"',"+Str(Warnung)+","+Str(BestMld)+")"            
            SQLiteExecute(DBHandle,SqlString$,0)
            _id = Anzahl
          Else
            _id = ID
          EndIf
          SqlString$ = "INSERT INTO SavedShortcuts VALUES('"+DateiName$+"',"+Str(_id)+")"
          SQLiteExecute(DBHandle,SqlString$,0)
          Program$ = ProgramFilename()
          CreateShortcut(Program$,DateiName$,GetPathPart(Program$),Str(_id),#SW_SHOWNORMAL,"",#Null,Program$,1)
          MessageRequester("Info","Die Verknüpfung wurde erfolgreich erstellt",#MB_ICONINFORMATION)
        EndIf
        verok = 0
        HideWindow(#Verknuepfung,1)
      EndIf
Und da ich die Erstellung meiner Datenbank heute Nacht nochmals aktualisiert habe, kommt hier nochmal der Code zum Erstellen:

Code: Alles auswählen

    SQLiteExecute(DBHandle,"CREATE TABLE Profile(Name,IP,Subnetmask,DefaultGateway,DNS1,DNS2,dhcp,autodns)",0)
    SQLiteExecute(DBHandle,"CREATE TABLE Shortcuts(ID,Profil,Netzwergeraet,Warnung,Bestaetigung)",0)
    SQLiteExecute(DBHandle,"CREATE TABLE SavedShortcuts(Pfad,ID)",0)
    SQLiteExecute(DBHandle,"CREATE TABLE Settings(LastDevice,LastProfile)",0)
Und nochmal @Kiffi: Wenn ich dann einen Autowert reinmache, wie muss ich dann die ID behandeln? Muss ich extra die ID im SqlString$ angeben, oder wird das automatisch gemacht? Und wie kann ich dann die ID auslesen, wenn ich sie brauche?

Verfasst: 30.05.2007 11:13
von Kaeru Gaman
nungut.. an dem "kompletteren" code ist zu erkennen, dass du den wert
von "Anzahl" korrekt ermittelst, die sollte die erste freie ID enthalten.
allerdings würde ich die Variable umbenennen, weil ja ja mit einer "Anzahl" nix zu tun hat.
bei mir würde das ding "FirstFreeID" heißen...

allerdings kann ich mit diesem codeabschnitt immer noch nichts anfangen:

Code: Alles auswählen

          ok = 0
          _id = -1
;          SQLiteNextCol(Table)
          While SQLiteNextRow(Table)
            ok = 1
            Ergebnis$ = SQLiteValue(Table)
            ID = Val(Ergebnis$)
            Break
          Wend 
was genau soll der denn tun?
ich kann den algo gedenklich nicht nachvollziehen.
erklärs mir mal bitte, dann kann ich dazu was sagen, ob der funktionell ist oder nen denkfehler drin hat.

Verfasst: 30.05.2007 11:13
von Kiffi
PureBasic4.0 hat geschrieben:Die DB meldet, dass es keine Spalte Namens Netzwerkgeraet in der DB
Shortcuts gibt. Wie man aber an obiger Struktur erkennen kann, gibt es
die Spalte Netzwerkgeraet. Was mache ich jetzt schon wieder falsch???

Code: Alles auswählen

SqlString$ = "INSERT INTO Shortcuts VALUES("+Str(Anzahl)+",'"+Profil$+"','"+Netzwerkg$+"',"+Str(Warnung)+","+Str(BestMld)+")"           
Da fehlt die Feldauflistung vor dem 'VALUES(...'

Syntax: Insert Into Tabellenname ([Feldnamen]) Values ([Feldwerte])

Du brauchst wirklich mal eine Pause...
PureBasic4.0 hat geschrieben:@Kaeru: Hier ist nochmal der gesamte Code. Vom ElseIf bis zum abschließenden ElseIf. Da kann man gut sehen, wo die Variable Anzahl herkommt.
Kiffi! Ich heiße Kiffi! Alternativ kannst Du mich auch Peter nennen.

Ich habe momentan keine Zeit, um mir Deinen Code genauer
anzuschauen (zumal das ja eigentlich nicht nötig wäre, wenn Du mit einem
Autowert arbeiten würdest).
PureBasic4.0 hat geschrieben:Und nochmal @Kiffi: Wenn ich dann einen Autowert reinmache, wie muss
ich dann die ID behandeln? Muss ich extra die ID im SqlString$
angeben
Nein
PureBasic4.0 hat geschrieben:oder wird das automatisch gemacht?
Ja
PureBasic4.0 hat geschrieben:Und wie kann ich dann die ID auslesen, wenn ich sie brauche?
so, wie Du jedes andere Feld auch ausliest: "Select ID From..."

Wenn Du die ID des gerade hinzugefügten Datensatzes benötigst, dann
machst Du das wie folgt.

Code: Alles auswählen

SQLiteExecute(DBHandle, "Insert Into ...")
ID = SQLiteLastInsertRowId(DBHandle)
Grüße ... Kiffi

Verfasst: 30.05.2007 11:42
von PureBasic4.0
OK. Sry für Kaeru statt Kiffi.

Nochmal danke an alle.

Verfasst: 30.05.2007 18:49
von hardfalcon
Ich hab mir jetzt nicht alles komplett durchgelesen, aber zum dem Problem, das du mit dem "Netzwerkgeraet" hast: Auf dem 1. Screenshot, den du gepostet hast, steht nicht "Netzwerkgerät", sondern "Netzwergerät". Nicht dass ich irgendeine Ahnung von Datenbanken, SQL oder deinem Code hätte (ich hab ihn mir mangels klarem Kopf nicht angeschaut), aber könnte das vll. die Ursache des Problems sein?

Verfasst: 30.05.2007 18:56
von PureBasic4.0
:oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops: :oops:


Wie peinlich! Danke. Das war's