SQLExpress: skip() mit Select ersetzen?

SQL Express von Boris Borzic

Moderator: Moderatoren

SQLExpress: skip() mit Select ersetzen?

Beitragvon satmax » Mo, 11. Nov 2013 17:01

Hallo,

ich will ja nicht einfach mit einem Select * from Auftrag alle Aufträge über die Leitung ziehen und dann skippen. Daher wäre mein Ansatz für ein dbSkip(-1):

Code: Alles auswählen
oCursor := SQLSelect():new("SELECT TOP 1 * FROM Auftrag ORDER BY AuftragNr DESC") // Findet den letzten Auftrag
oCursor:Execute()

// Dann ein skip(-1)
:oCursor:= SQLSelect():new("select count(*) FROM AUFTRAG WHERE AuftragNr < (?)")  //  zähle Aufträge davor
oCursor:Execute(oCursor:fieldGet("AuftragNr"))

nGoTo:=oCursorBack:FieldGet(1)    // Wahrscheinlich fehlt hier ein neues "SELECT * from Auftrag where row=nGoTo"  oder so ähnlich.....
oCursor:GoTo(nGoTo)


Habe ich mich da jetzt total verrannt oder sollte das so ähnlich funktionieren? Ich hätte auch in jeden Datensatz ein eindeutiges Feld ID (autoincrement)

Eigentlich will ich also nur ein skip nachbilden und dabei aber immer nur einen Record lesen.

Gruß
Markus
Gruß
Markus
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
 
Beiträge: 776
Registriert: Do, 02. Dez 2010 20:34
Wohnort: Biberbach in Österreich

Re: SQLExpress: skip() mit Select ersetzen?

Beitragvon georg » Mo, 11. Nov 2013 19:34

Hallo, Markus -


ja und nein.

Es ist immer (!) von der Implementierung des SQL-Servers UND der ODBC-Schnittstelle abhängig, wie Daten geliefert werden. In vielen Fällen ist die Angabe, dass Du einen speziellen Cursors willst (der z.B. Satz für Satz die Daten abruft) eben nur eine Empfehlung, und der Treiber sammelt fleissig alles ein.

Um den letzten Auftrag zu finden:

Code: Alles auswählen
SELECT Max(AuftragNR) FROM Auftrag
oder
SELECT * FROM Auftrag ORDER BY AuftragNr DESC LIMIT 1


Ansonsten entspricht die Satzanzahl vor dem letzten Auftrag der Anzahl Sätze in der Datei. Da in Deiner Anweisung

Code: Alles auswählen
select count(*) FROM AUFTRAG WHERE AuftragNr < (?)


die ORDER BY Clause fehlt, kann es sein, dass Deine Ergebnisse abweichen.


Versuchen wir eine andere gedankliche Annäherung. Angenommen, Du brauchst folgende Felder:

Auftragsnummer
Datum
Kundennummer
Kundenname
Status

Code: Alles auswählen
SELECT AuftragNr, AufDatum, AufKundenNr, Kundenname, Aufstatus FROM Auftrag AS T1 LEFT JOIN Kunden AS T2 ON T1.AufKundenNr = T2.Kundennummer ORDER BY AuftragNr DESC


Vorteil: Du rufst nur die Felder ab, die gebraucht werden - verringert den Traffic. Du hat in einer Anweisung direkt den Kundennamen mit drin, macht es übersichtlicher. Pack das Ganze in ein SQLDataSet(), und Du kannst viel damit machen.

Ein SELECT * würde Daten über die Leitung ziehen, die zu dem Zeitpunkt nicht benötigt werden. Willst Du nur einen bestimmten Zeitraum, grenze die SELECT-Anweisung durch ein entsprechendes WHERE ein.
Liebe Grüsse aus der Eifel,

Georg
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 1814
Registriert: Fr, 08. Feb 2008 22:29

Re: SQLExpress: skip() mit Select ersetzen?

Beitragvon satmax » Mo, 11. Nov 2013 19:49

Danke für Deine Erklärungen.

Klar gebe ich nur die Felder an die ich brauche ;) , das ist hier nur der Einfachheit halber so geschrieben.

In diesem Fall stehen ich einfach auf den letzten von ein paar hunderttausend Aufträgen und will einfach manuell ein paar zurückblättern. Ich denke mit dem SQL Statement

Code: Alles auswählen
xSeek:= ::oCursor:fieldGet("AuftragNr")
::oCursor := SQLSelect():new("select top 1 AuftragNr FROM AUFTRAG WHERE AuftragNr < (?) order by AuftragNr desc")
::oCursor:Execute(xSeek)

bin ich schon nahe dran.

in der MMC liefert mir das folgende Statement bereits das richtige Ergebnis

Code: Alles auswählen
select top 1 AuftragNr FROM AUFTRAG WHERE AuftragNr < 184867 order by AuftragNr desc

nur im Programm noch nicht....
Gruß
Markus
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
 
Beiträge: 776
Registriert: Do, 02. Dez 2010 20:34
Wohnort: Biberbach in Österreich

Re: SQLExpress: skip() mit Select ersetzen?

Beitragvon georg » Mo, 11. Nov 2013 20:01

Hallo, Markus -


hier verwende ich MySQL, und die Anweisung "TOP 1" mag MySQL nicht - scheint also ein "Sonderweg" zu sein.

Ansonsten gibt es noch andere Wege. Ich schicke Dir mal eine PN, weil mir jetzt die Zeit fehlt, das hier auszuführen.
Liebe Grüsse aus der Eifel,

Georg
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 1814
Registriert: Fr, 08. Feb 2008 22:29

Re: SQLExpress: skip() mit Select ersetzen?

Beitragvon AUGE_OHR » Fr, 15. Nov 2013 5:14

satmax hat geschrieben:Eigentlich will ich also nur ein skip nachbilden und dabei aber immer nur einen Record lesen.
diese Methoden sind IMHO beim DataSet() von Boris enthalten.
satmax hat geschrieben:In diesem Fall stehen ich einfach auf den letzten von ein paar hunderttausend Aufträgen und will einfach manuell ein paar zurückblättern.
das ist man von DBF so gewohnt ...
angenommen du hast ein Browse dann hast du auch nur eine begrenzte Anzahl von Zeilen für 1 Seite zu darstellen.
ich verwende mit PostgreSQL dafür einen CURSOR der mir ein aktuelles Result Set mit genau der Anzahl von Zeilen liefert.
Code: Alles auswählen
\\ Note : die PostgreSQL (!) Function row_number() gibt es erst ab der Version v9.x

   cVar1 := "BEGIN WORK;"
   cVar2 := "DECLARE MyCursor CURSOR FOR SELECT " + cField +;
               ", row_number() OVER (ORDER BY " + cOrder + ")"+;
               " FROM " + cTable + ;
               IF( EMPTY( cWhere ), "", " WHERE " + cWhere ) + ;
               " ORDER BY " + cOrder
   cVar3 := "MOVE  FORWARD " + cOffset + " IN MyCursor"
   cVar4 := "FETCH FORWARD " + cLimit  + " FROM MyCursor"
   cVar5 := "CLOSE MyCursor;"
   cVar6 := "COMMIT WORK;"
jede cVarX wird als Query per ::oPG:exec( cVarX ) abgeschickt.

innerhalb eines Result Set Object hat man gewöhnlich Methoden zum navigieren (skip,goto) die mit Tuple die Positionen bestimmen.
gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
 
Beiträge: 10276
Registriert: Do, 16. Mär 2006 8:55
Wohnort: Hamburg

Re: SQLExpress: skip() mit Select ersetzen?

Beitragvon brandelh » Fr, 15. Nov 2013 9:49

ich bin nicht so drin bei den "cursorn" und was der jeweilige ODBC Treiber kann, daher habe ich es bei mir so gelöst, dass ich mit SELECT ID,name FROM xyz WHERE ... (readonly forward cursor kostet am wenigsten) genau die Datensätze mit primary Key und Text für die Anzeige (Baum, Browser etc.) hole und in ein Array umschaufle die ich jetzt brauche ! Nun Skippe ich im Array und fordere jeden einzelnen Satz dann an, wenn ich seine Daten benötige. Geänderte Daten sende ich per UPDATE ... WHERE ID = sID (Syntax aus dem Kopf, kann Fehler enthalten ;-) ...
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13379
Registriert: Mo, 23. Jan 2006 21:54
Wohnort: Germersheim

Re: SQLExpress: skip() mit Select ersetzen?

Beitragvon satmax » Fr, 15. Nov 2013 11:27

Mein Ansatz geht jetzt in die Richtung, bei Select auf keinen Fall Select * zu benutzen. Ich mache 2 Cursor, einen

Code: Alles auswählen
Pseudocode:
oCursorSkip := SELECT auftragnummer FROM auftrag


mit dem kann ich auch problemlos arbeiten wenn mehr all 300000 Aufträge in der DB sind und kann alle Funktionen benutzen (skip, reccount,...)

Dann einen zweiten Cursor

Code: Alles auswählen
Pseudocode:
oCursor := SELECT VieleFelder from Auftrag where auftragsnummer == oCursorSkip

der beinhaltet alle Daten und wird bei jedem skip neu eingelesen und die Daten angezeigt bzw. zum Bearbeiten bereit gestellt. Das ganze ist sehr einfach und effizient.

Gruß
Markus
Gruß
Markus
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
 
Beiträge: 776
Registriert: Do, 02. Dez 2010 20:34
Wohnort: Biberbach in Österreich


Zurück zu SQLExpress

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast