Seite 1 von 1

Anspringen eines Datensatzes innerhalb einer SQLite-Tabelle

Verfasst: 31.07.2009 12:55
von dysti
Hallo,
ich möchte einen bestimmten Datensatz innerhalb einer SQLite-Tabelle anspringen, möchte aber die Blätterfunktion innerhalb der Tabeller behalten.
Aus dem untenstehenden Code kann man meine derzeitige Lösung ersehen.

Gibt es eine einfachere elegante Lösung, die ich bisher nicht gefunden habe?

Code: Alles auswählen

#db0=0
dbzaehler=0
UseSQLiteDatabase()
DatabaseFile$ = "i:\purebasic\forumexamples\bestand.sqlite"
;DatabaseFile$ = GetTemporaryDirectory()+"\Database.sqlite"
Debug DatabaseFile$
If CreateFile(#db0, DatabaseFile$)
   CloseFile(#db0)
   
   If OpenDatabase(#db0, DatabaseFile$, "", "")
      DatabaseUpdate(#db0, "CREATE TABLE bestand (Dsnr  INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE  Not NULL, Name VARCHAR(40) , Stueck NUMERIC(10) , Preis NUMERIC(10,2))")
      DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('"+Name$+"', '"+Stueck$+"', '"+Str(Preis)+"')")
      DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('Tastatur', '5', '25.55')")
      DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('DVD-Laufwerk', '20', '33.00')")
      DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('Festplatte 160GB', '23', '133.00')")
      DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('USB-Stick 2GB', '44', '3.00')")
      If DatabaseQuery(#db0, "SELECT * FROM bestand")
         While NextDatabaseRow(#db0)
            Debug "Datensatznummer:  "+ GetDatabaseString(#db0, 0)
            Debug "Artikel        :  "+ GetDatabaseString(#db0, 1)
            Debug "Stück        :  "  + GetDatabaseString(#db0, 2)
            Debug "Preis          :  "+ GetDatabaseString(#db0, 3)
            dbzaehler=dbzaehler+1
         Wend
       EndIf
       
       ;letzten Datensatz ermitteln
       
       Result = DatabaseQuery(#db0, "SELECT max(Dsnr) from bestand");"SHOW TABLE STATUS FROM bestand LIKE 'Dsnr'")
         If Result = 0
         Debug DatabaseError()
         EndIf
         NextDatabaseRow(#db0)
         Debug "Dies ist die letzte Datensatznummer dieser Tabelle: "
         Debug GetDatabaseString(#db0, 0)
         Debug "oder so: " + Str(dbzaehler)
         
         
        ;zur Ausgangslage zurück
        DatabaseQuery(#db0, "SELECT * FROM bestand")
        
       
       
        ; wir wollen ein Datensatz anspringen, aber das blättern innerhalb der Tabelle soll erhalten bleiben
        ; in diesem Beispiel wollen wir den 3.Datensatz anspringen
            dbs=3 
            For i=1 To dbs
            NextDatabaseRow(#db0)
            Next
       
            Debug "_______________________"
            Debug ""
            Debug "Datensatznummer:  "+ GetDatabaseString(#db0, 0)
            Debug "Artikel        :  "+ GetDatabaseString(#db0, 1)
            Debug "Stück        :  "  + GetDatabaseString(#db0, 2)
            Debug "Preis          :  "+ GetDatabaseString(#db0, 3)
       
       FinishDatabaseQuery(#db0)
       
   Else
      Debug "Can't open database !"
   EndIf
Else
   Debug "Can't create the database file !"
EndIf 

Verfasst: 31.07.2009 13:04
von marco2007
Ich weiß jetzt nicht was Du mit Blättern meinst, aber wenn ich ein bestimmte Zeile benötige, dann nehme ich einfach where...

Code: Alles auswählen

dbs=3
DatabaseQuery(#db0, "SELECT * FROM bestand where Dsnr="+Str(dbs))
FirstDatabaseRow(#db0)
  Debug "_______________________" 
  Debug "" 
  Debug "Datensatznummer:  "+ GetDatabaseString(#db0, 0) 
  Debug "Artikel        :  "+ GetDatabaseString(#db0, 1) 
  Debug "Stück        :  "  + GetDatabaseString(#db0, 2) 
  Debug "Preis          :  "+ GetDatabaseString(#db0, 3)  
Meinst Du das?

Verfasst: 31.07.2009 13:22
von dysti
@marco2007,
das ist ansich normal richtig. Aber...
wenn du ab hier den nächsten Datensatz anspringen willst z.B. mit NextDatabaseRow(#db0), dann erleidest zu Schiffbruch.
Er hat dem dem Selectbefehl ja nur diesen Datensatz herausgefiltert
und somit erreiche ich Datensatz 5 nicht.
Ich könnte jetzt dbs=5 machen und die Query jedesmal wiederholen,
aber ich glaube nicht, das das professionell ist.
Jedesmal kommt durch den Befehl wieder Traffic auf, z. B. bei 20000 Datensätzen. Zumindest hat meine Festplatte ganz schön gerappelt.
Genau das soll verringert, wenn nicht sogar vermieden werden.
Bei 1000 Datensätzen merkt man nichts, da könnte man das vernachlässigen.

Verfasst: 31.07.2009 13:27
von Kiffi
einfach nach Dsnr absteigend sortieren. Der erste Datensatz ist dann der
mit der höchsten Dsnr:

Code: Alles auswählen

#db0=0 
UseSQLiteDatabase() 
DatabaseFile$ = ":memory:" 
  
If OpenDatabase(#db0, DatabaseFile$, "", "") 

  DatabaseUpdate(#db0, "CREATE TABLE bestand (Dsnr  INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE  Not NULL, Name VARCHAR(40) , Stueck NUMERIC(10) , Preis NUMERIC(10,2))") 
  DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('"+Name$+"', '"+Stueck$+"', '"+Str(Preis)+"')") 
  DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('Tastatur', '5', '25.55')") 
  DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('DVD-Laufwerk', '20', '33.00')") 
  DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('Festplatte 160GB', '23', '133.00')") 
  DatabaseUpdate(#db0, "INSERT INTO bestand (Name, Stueck, Preis) VALUES ('USB-Stick 2GB', '44', '3.00')") 
  
  If DatabaseQuery(#db0, "SELECT * FROM bestand Order By Dsnr Desc Limit 1") 
    
    While NextDatabaseRow(#db0) 
      Debug "Datensatznummer:  "+ GetDatabaseString(#db0, 0) 
      Debug "Artikel        :  "+ GetDatabaseString(#db0, 1) 
      Debug "Stück        :  "  + GetDatabaseString(#db0, 2) 
      Debug "Preis          :  "+ GetDatabaseString(#db0, 3) 
      Break
    Wend 
    
    FinishDatabaseQuery(#db0)
    
  EndIf 
  
Else 
  Debug "Can't open database !" 
EndIf
Grüße ... Kiffi

// Ups! Habe übersehen, dass Du einzelne DS direkt anspringen willst;
nicht den letzten (war noch im Gedanken in Deinem letzten Thread).

Verfasst: 31.07.2009 13:29
von marco2007
Achso...
Wenn dsnr eine fortlaufende Nummer ist, könntest Du

Code: Alles auswählen

SELECT * FROM bestand where Dsnr>="+Str(dbs) +" order by Dsnr"
nehmen.

Verfasst: 31.07.2009 15:57
von dysti
@marco2007,
und was ist, wenn der User sich überlegt, ich will nicht den nächsten sondern den vorherigen. Die Gedanken des Users kann man nicht vorhersehen.

Vielleicht sollte man sich überlegen, einen bestimmten Bereich der Tabelle
in einer Structure/Array/Linkedlist einzulesen.
Dann ist auch ein Listicongadget besser zu händeln, denn so eine große Datenbank kann man nicht in ein Listicongadget einlesen, oder bin ich auf ein Holzweg?

Verfasst: 31.07.2009 16:15
von marco2007
ok, hätte ja sein können, dass Du die vorherigen nicht mehr brauchst.
Mach ich zum Beispiel -> Bei Vertriebsbelege lese ich nur Werte ab einem bestimmten Datum, da mich ältere nicht interessieren.

Repeat: Nextdatabaserow(): until Getdatabase...()=#true...sowas in der Art würde ich dann machen (anstatt for:next), obwohl ich mach`s eigentlich immer mit where...Wenn die Datenbank mal offen ist, sind die Abfragen eh immens schnell.