SQLExpress: skip() mit Select ersetzen?

SQL Express von Boris Borzic

Moderator: Moderatoren

Antworten
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

SQLExpress: skip() mit Select ersetzen?

Beitrag von satmax »

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
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: SQLExpress: skip() mit Select ersetzen?

Beitrag von georg »

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 S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: SQLExpress: skip() mit Select ersetzen?

Beitrag von satmax »

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
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: SQLExpress: skip() mit Select ersetzen?

Beitrag von georg »

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 S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: SQLExpress: skip() mit Select ersetzen?

Beitrag von AUGE_OHR »

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
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: SQLExpress: skip() mit Select ersetzen?

Beitrag von brandelh »

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
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: SQLExpress: skip() mit Select ersetzen?

Beitrag von satmax »

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
Antworten