Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SetRange und SQL (https://www.delphipraxis.net/54385-setrange-und-sql.html)

TheSaint 3. Okt 2005 14:58

Datenbank: BDE • Zugriff über: TTable

SetRange und SQL
 
Hallo Datenbankspezis!

Kann man ein SetRange auch durch ein SQL-Statement abbilden?
Ich möchte von Paradox auf den SQL-Server umsteigen, aber ungern meine Zugriffsklasse umschreiben.

Danke
TheSaint

alzaimar 3. Okt 2005 15:01

Re: SetRange und SQL
 
Was verstehst du unter SetRange? Codeschnipsel? Etwas genauer?

TheSaint 3. Okt 2005 15:07

Re: SetRange und SQL
 
Z.B.:
Table1.Setrange([],[]);

Die Bedeutung von SetRange steht auch in der Hilfe. Code habe ich jetzt nicht zur Hand. Ist ja eigentlich auch keine Codingfrage, sondern eher eine Designfrage.

marabu 3. Okt 2005 15:42

Re: SetRange und SQL
 
Hallo,

sicher kannst du SetRange in SQL nachbilden. Hier am Beispiel eines compound key:

Delphi-Quellcode:
with Table do begin
  IndexName := 'BYNAME';
  SetRange([Nachname, VornameVon], [Nachname, VornameBis]);
end;
SQL-Code:
SELECT * FROM personen
WHERE nachname = :nachname AND vorname BETWEEN :von AND :bis
ORDER BY nachname, vorname
Grüße vom marabu

TheSaint 4. Okt 2005 08:34

Re: SetRange und SQL
 
Hallo,

danke für die Antwort. Vielleicht kannst Du mir nochmal helfen. Wie würde das SQL-Statement bei diesem SetRange ausschauen?

Delphi-Quellcode:
with Table do begin
  IndexName := 'BYNAME';
  SetRange([NachnameVon, VornameVon], [NachnameBis, VornameBis]);
end;
Danke
TheSaint

marabu 4. Okt 2005 09:01

Re: SetRange und SQL
 
Hallo,

das passende SQL Statement steht schon in meinem vorigen Beitrag. Bleibt die Frage, warum du das nicht erkennst. Ist dir die Parameterangabe fremd, oder SQL überhaupt? Wie kann ich dir helfen?

Freundliche Grüße vom marabu

TheSaint 4. Okt 2005 09:25

Re: SetRange und SQL
 
Hallo!

Nein, ist mir nicht fremd. Vielleicht mache ich mal ein konkretes Beispiel.
Ich habe eine Tabelle mit 2 Spalten und 2 Zeilen. Beide mit dem Datentyp int.

Tabelle:
Col1 Col2
----------
1 1
2 0

Jetzt mach ich darüber ein Setrange:
Delphi-Quellcode:
table1.SetRange([1,1],[2,1]);
Als Ergebnismenge bekomme ich zwei Datensätze, also die komplette Tabelle.

Nun mache ich das mit SQL:
Delphi-Quellcode:
SELECT * FROM Tabelle
WHERE (Col1 between 1 AND 2) AND (Col2 between 1 AND 1)
ORDER BY Col1, Col2
Hier bekomme ich eine Zeile als Ergebnis geliefert.

SetRange und das SQL-Statement liefern hier also unterschiedliche Ergebnisse.
Bleibt die Frage, ob ich einen Fehler in meiner Umsetzung habe, oder die SQL-Anweisung dafür nicht geeignet ist.

Danke
TheSaint

marabu 4. Okt 2005 10:09

Re: SetRange und SQL
 
Damit du einen Range in einer Paradox-Tabelle selektieren kannst, musst du einen Sekundärindex definieren. In deinem Beispiel benötigst du also einen compound key (COL1, COL2). Wenn du SetRange([1,1], [2,1]) ausführst, dann wird effektiv SetRange([1], [2]) ausgeführt, da sich der Start- und Endwert für das Indexfeld COL1 unterscheiden. Nach meiner Erinnerung akzeptiert SetRange() nur beim letzten angegebenen Indexfeld abweichende Werte, was an der Implementierung über einen Sekundärindex liegt. Insofern wäre die korrekte Umsetzung nach SQL diese:

SQL-Code:
SELECT * FROM Tabelle
WHERE Col1 BETWEEN 1 AND 2
ORDER BY Col1, Col2
Ich habe jetzt erst entdeckt, dass du mein Beispiel für SetRange() in deiner Frage abgewandelt hattest - meine hier gegebene Erklärung gilt natürlich analog.

marabu

TheSaint 4. Okt 2005 10:27

Re: SetRange und SQL
 
Es ist mir schon klar, dass man einen Index braucht, um Setrange aufrufen zu können.

Zitat:

Wenn du SetRange([1,1], [2,1]) ausführst, dann wird effektiv SetRange([1], [2]) ausgeführt, da sich der Start- und Endwert für das Indexfeld COL1 unterscheiden.
Nein, das kann nicht sein. Ändere mal die kleine Beispieltabelle wie folgt ab:
Col1 Col2
----------
1 0
2 1
Also, einfach nur 0 und 1 vertauschen und den Setrange ausführen
Delphi-Quellcode:
SetRange([1,1], [2,1])
Nun bekommst Du einen Datensatz in der Ergebnismenge. Also werden auch gleiche Werte im letzten Indexfeld ausgewertet. Irgendwie schein die Sortierung eine Rolle zu spielen.

TheSaint

marabu 4. Okt 2005 11:35

Re: SetRange und SQL
 
Deine Beispiele haben mich überzeugt. Wenn also bei der Auswertung der Indexfelder durch SetRange() keine Abhängigkeiten existieren, dann musst du bei der Übertragung der einzelnen Ranges nach SQL nur darauf achten, dass die BETWEEN Ausdrücke disjunktiv (OR) verkettet werden. Dein letztes Beispiel sieht dann so aus:

SQL-Code:
SELECT * FROM Tabelle
WHERE (Col1 between 1 AND 2)  OR  (Col2 between 1 AND 1)
ORDER BY Col1, Col2

/* oder besser so: */

SELECT * FROM Tabelle
WHERE (Col1 between 1 AND 2)  OR  (Col2 = 1)
ORDER BY Col1, Col2
Gut, dass du bei meiner falschen Erinnerung hartnäckig geblieben bist.

marabu

TheSaint 4. Okt 2005 13:51

Re: SetRange und SQL
 
Hallo!

Mit dem between Operator habe ich schon einige Test gefahren und dieser scheint nicht geeignet zu sein. Dein letztes Beispiel würde zwar mit dieser Tabelle funktionieren:

Col1 Col2
----------
1 0
2 1

Mit der hier aber nicht mehr:
Col1 Col2
----------
1 1
2 0

Wie ich schon erwähnt habe, liegt es wohl an der Sortierung. Eine Umsetzung mit SQL ist wohl nicht so einfach möglich. :(

marabu 4. Okt 2005 16:46

Re: SetRange und SQL
 
Meine Erinnerung war vielleicht doch nicht so falsch. Ich habe einer Eingebung folgend das Handbuch zu ObjectPAL Version 7 konsultiert und den Beleg für meine Erinnerung gefunden:

Zitat:

Zitat von Borland
setRange

Beschreibung: setRange definiert Bedingungen zur Auswahl zusammenhängender Datensätze ... Sie können auch einen Bereich definieren, der auf mehreren Feldern beruht. Dazu definieren Sie eine exakte Übereinstimmung außer für das letzte Element in der Liste.

Das von dir beobachtete Phänomen, bei dem du je nach Wertfolge in Spalte 2 mal einen, mal zwei Sätze als Ergebnis von SetRange erhältst, beruht auf einem falschen Umgang mit dieser Methode. Während das Ergebnis eines SQL-Statements wohl definiert ist, musst du bei Methoden der BDE spezielle Randbedingungen beachten.

Grundsätzlich solltest du dich nicht von einem Wechsel zu einem SQL Server abhalten lassen. Du kannst mit SQL jedes gewünschte Ergebnis produzieren - das garantiert alleine die implementierte Relationen-Algebra. Die von mir angegebenen SQL statements produzieren das Ergebnis, welches ich haben wollte. Das inkonsistente Ergebnis von SetRange kann kein Maßstab für die Leistungsfähigkeit von SQL sein.

marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz