Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi InterBase-SQL ,SELECT -Anweisung (https://www.delphipraxis.net/16958-interbase-sql-select-anweisung.html)

jokriege 26. Feb 2004 11:12


InterBase-SQL ,SELECT -Anweisung
 
Hallo,

ich möchte folgende SQL-Abfrage (MS-SQL) mit InterBase umsetzen:
Suche (blockanfang und kennung) in der Tabelle nach dem ersten Wert in der Spalte
blockende, der größer als eine Nummer (z. B. 421890763500000) ist.
Das geht beim MS-SQL-Server so:

select top 1 blockanfang, kennung from [tabelle] where blockende >= 421890763500000

Leider habe ich bisher keine Möglichkeit beim IB-Server gefunden.
Kennt jemand eine Lösung?

Vielen Dank vorab für eine Antwort.

Robert_G 26. Feb 2004 11:17

Re: InterBase-SQL ,SELECT -Anweisung
 
Das Einschränken der Datensätze in der Ergebnismenge ist für jede DB anders (ist auch nicht Teil vom ANSI-SQL-Standard)
In Oracle wär's:
SQL-Code:
SELECT BlockAnfang,
       Kennung
FROM  tabelle
WHERE BlockEnde >= 421890763500000 And
       RowNum = 1
Der MS SQL Svr hat sein Top und ich habe auch schon solche Sachen gesehen:
SQL-Code:
SELECT BlockAnfang,
       Kennung
FROM  tabelle
WHERE BlockEnde >= 421890763500000
LIMIT 1

Leuselator 26. Feb 2004 12:15

Re: InterBase-SQL ,SELECT -Anweisung
 
Hmm - so:
SQL-Code:
SELECT * 
  FROM tabelle
 WHERE BlockEnde = ( SELECT min(BlockEnde)
                       FROM tabelle
                      WHERE BlockEnde >= 421890763500000)
?

DelphiDeveloper 26. Feb 2004 12:35

Re: InterBase-SQL ,SELECT -Anweisung
 
interbase kennt von hause aus sowas nicht,
muesste man in einer SP dort machen

die SP in interbase wuerde etwa so aussehen
Code:
CREATE PROCEDURE GET_FIRST_VALUE_BLOCKENDE (
    INPUT_VALUE INTEGER
   )
RETURNS (
    OUT_BLOCKANFANG INTEGER,
    OUT_KENNUNG VARCHAR(10))
AS
DECLARE VARIABLE HA INTEGER;
DECLARE VARIABLE HB VARCHAR(10);
BEGIN
  HA = -1;
  HB = '';
  OUT_BLOCKANFANG = -1;
  OUT_KENNUNG = '';
  FOR SELECT B.BLOCKANFANG, B.KENNUNG FROM
  BLOCK B
  WHERE (B.BLOCKENDE >= :INPUT_VALUE)
  ORDER BY B.BLOCKANFANG
  INTO :HA, :HB
  DO
  BEGIN
    IF (:HA <> -1) THEN
       OUT_BLOCKANFANG = :HA;
    IF (:HB <> '') THEN
       OUT_KENNUNG = :HB;

    SUSPEND;
    EXIT;   // HIERDURCH NACH ERSTEN SATZ SP BEENDET
  END
  SUSPEND; // FUER DEN FALL DASS NICHTS GEFUNDEN WIRD
END
aber muss es unbedingt interbase sein, bei firebird wuerde es so gehen

select first 1 * from tabellenname
where ...

Robert_G 26. Feb 2004 12:37

Re: InterBase-SQL ,SELECT -Anweisung
 
@Leuselator
Man sollte für eine solche Einschränkungen neien StopKey verwenden (bei mir RowNum...)
Da bei deiner Variante ein zweiter kompletter Table access nötig war:


SQL-Code:
SELECT *
FROM  XXXXXXXXX.sent_queries t
WHERE t.error_id >= 3000 And
       RowNum    = 1
Optimizer plan:
Delphi-Quellcode:
SELECT STATEMENT, GOAL = CHOOSE          CHOOSE                   SELECT STATEMENT
 COUNT STOPKEY                                            STOPKEY  COUNT
  TABLE ACCESS FULL   XXXXXXXXX  SENT_QUERIES          FULL     TABLE ACCESS

SQL-Code:
SELECT *
FROM  XXXXXXXXX.sent_queries t
WHERE t.error_id = (SELECT Min(sq.error_id)
                     FROM  XXXXXXXXX.sent_queries sq
                     WHERE sq.error_id >= 3000)
Optimizer plan:
Delphi-Quellcode:
SELECT STATEMENT, GOAL = CHOOSE          CHOOSE                   SELECT STATEMENT
 FILTER                                                             FILTER
  TABLE ACCESS FULL   XXXXXXXXX  SENT_QUERIES          FULL     TABLE ACCESS
  SORT AGGREGATE                                         AGGREGATE SORT
   TABLE ACCESS FULL  XXXXXXXXX  SENT_QUERIES          FULL     TABLE ACCESS

jokriege 26. Feb 2004 15:48

Re: InterBase-SQL ,SELECT -Anweisung
 
Vielen Dank für die schnellen Antworten.

Ich hab's.

Gruß
jokriege

Leuselator 26. Feb 2004 20:32

Re: InterBase-SQL ,SELECT -Anweisung
 
@Robert_G:
Das mein Vorschlag nicht gerade blitzschnell ist, war mir klar :-) - allerdings ging ich 1. davon aus, das die ZielDB eben nichts derartiges anbietet und 2. (klammheimlich), dass die Werte in dem Feld BlockEnde unique sind

@jokriege:
Es ist mehr als recht und billig, die Forengemeinde an einer gefundenen Lösung teilhaben zu lassen - so können andere, die später mal ein ähnliches Problem wie Du haben, diese Lösung nachvollziehen und ev. für ihr Problem übernehmen. Also bitte: klär uns über Deine Lösung auf!

jokriege 27. Feb 2004 07:11

Re: InterBase-SQL ,SELECT -Anweisung
 
Hallo, ich habe die Lösungsvorschläge von Leuselator und DelphiDeveloper getestet:

Der Vorschlag von DelphiDeveloper liefert zwar das richtige Ergebnis ist aber wesentlich langsamer als die SELECT-Abfrage von Leuselator. Deshalb habe ich mich für die Lösung von Leuselator entschieden.

@Leuselator:
Sorry, dass ich es versäumt habe, die von mir verwendete Lösung mitzuteilen.

Zur allg. Info:
Meine DB enthält z. Zt. ca. 500.000 Datensätze und ich habe es mit bis zu 50 Anfragen pro Sekunde (TCP/IP -> Delphi-Applikation -> InterBase -> Delphi-Applikation -> TCP/IP) getestet. Es funktioniert zu meiner vollsten Zufiedenhheit.

Danke und Gruß
jokriege


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:49 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