Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Lücken in fortlaufender Nummerierung finden (https://www.delphipraxis.net/188280-luecken-fortlaufender-nummerierung-finden.html)

noisy_master 16. Feb 2016 12:31

Datenbank: Paradox • Version: xx • Zugriff über: BDE

Lücken in fortlaufender Nummerierung finden
 
Hallo Gemeinde,

wie kann ich per Query herausfinden, ob ich Lücken in meiner Nummerierung habe?

Folgender Hintergrund: ich transferiere eine Tabelle, die ein Autoinc Feld hat in eine weitere Tabelle, die an der Stelle, wo in der ursprünglichen Tabelle das Autoinc Feld hat ein Integer Feld hat.
Dabei geht manchmal was schief(oder ist zumindest in der Vergangenheit). Die ursprüngliche Tabelle wird nach dem BatchMove auch geleert, so dass ich in dieser nicht mehr kontrollieren kann.

Daher die Frage kann ich(und wenn ja wie) per SQL die Datensätze herausfinden, wo in dieser Nummerierung Lücken auftauchen?

Danke im Voraus...

P.S.: bitte keinen Kommentar zur BDE... ich weiss schon : alt, blöd, instabil,....

Union 16. Feb 2016 12:45

AW: Lücken in fortlaufender Nummerierung finden
 
Z.b. in etwa so. Hauptsache es gibt einen Index auf das Feld und nicht zu viele Datensätze.
Code:
select a.nummer-1 as fehlt from tabelle a
where not exists (select b.nummer
                  from tabelle b
                  where b.nummer = a.nummer-1)

mkinzler 16. Feb 2016 12:45

AW: Lücken in fortlaufender Nummerierung finden
 
Es ist die Frage ob LocalSQL so mächtig ist aber man könnte es mit

SQL-Code:
select
  <Feldliste>
from
  <Tabelle> t
where
  not exists ( select <pk> from <Tabelle> t2 where t2.<pk> = t.<pk> + 1);

noisy_master 16. Feb 2016 12:59

AW: Lücken in fortlaufender Nummerierung finden
 
Soweit, so gut, aber es gibt nur 1 Tabelle....und dort soll geprüft werden ob das Feld "NUMMER" Lücken aufweist...daher dürften eure Ansätze nicht funktionieren, oder habe ich da jetzt was falsch verstanden?

Neutral General 16. Feb 2016 13:02

AW: Lücken in fortlaufender Nummerierung finden
 
Du hast was falsch verstanden.
Die SQLs der anderen waren auch nur für eine Tabelle gedacht.
Eine Tabelle kann durchaus mehrmals und unter mehreren Bezeichnungen in einer Query vorkommen

EDIT: Allerdings finden die bisher geposteten SQLs keine Lücken die größer als 1 Datensatz sind.
Kenn mich nicht mit Paradox aus aber am einfachsten ist es wahrscheinlich über eine Stored Procedure oder einen Execute Block (falls es sowas in Paradox gibt)

noisy_master 16. Feb 2016 13:05

AW: Lücken in fortlaufender Nummerierung finden
 
aaahhh okay, dann sorry, dass ich gemeckert habe... darum ja auch die Frage, ob ich was falsch verstanden habe.....

<knie_nieder> Schön, dass es hier so viele schlaue Leute gibt! </knie_nieder>

Neutral General 16. Feb 2016 13:06

AW: Lücken in fortlaufender Nummerierung finden
 
Zitat:

Zitat von noisy_master (Beitrag 1330498)
aaahhh okay, dann sorry, dass ich gemeckert habe... darum ja auch die Frage, ob ich was falsch verstanden habe.....

<knie_nieder> Schön, dass es hier so viele schlaue Leute gibt! </knie_nieder>

Habe meinen Beitrag grad nochmal ergänzt. Der Code von oben findet keine Lücken die größer 1 sind.

himitsu 16. Feb 2016 13:12

AW: Lücken in fortlaufender Nummerierung finden
 
Mit einem Generator alle "IDs" im gewünschten Bereich (z.B. 1 bis greatest oder besser noch bis NextAutoInc-1) erstellen und dann im WHERE alles rausfiltern, was es gibt.
Übrig bleiben die Lücken.

p80286 16. Feb 2016 13:18

AW: Lücken in fortlaufender Nummerierung finden
 
oder mit Hilfe von Delphi.
erst alle IDs holen, die es gibt, dann Liste mit IDs generieren die es geben sollte. Aus der Sollliste alles löschen was in der IstListe ist. Übrig bleiben die Lücken.

Gruß
K-H

frankyboy1974 16. Feb 2016 13:30

AW: Lücken in fortlaufender Nummerierung finden
 
hallo,

Zitat:

oder mit Hilfe von Delphi.
erst alle IDs holen, die es gibt, dann Liste mit IDs generieren die es geben sollte. Aus der Sollliste alles löschen was in der IstListe ist. Übrig bleiben die Lücken.
Also ich würde auch behaupten, mit reinem deskriptiven SQL ist das nicht möglich. Das wäre so, als würde ich zum Bäcker gehen und sagen "Geben Sie mir mal bitte alle Brotsorten, die Sie nicht führen". Ich müsste ja zumindestens in einer anderen Tabelle definieren, welche Schlüssel vorhanden sein müssten.

Falls jemand doch noch eine SQL-Lösung findet, wäre ich sehr gespannt.

mfg

Neutral General 16. Feb 2016 13:50

AW: Lücken in fortlaufender Nummerierung finden
 
Zitat:

Zitat von frankyboy1974 (Beitrag 1330506)
Ich müsste ja zumindestens in einer anderen Tabelle definieren, welche Schlüssel vorhanden sein müssten.

Falls jemand doch noch eine SQL-Lösung findet, wäre ich sehr gespannt.

mfg

Wieso das? Wenn du in einer Tabelle die IDs (PKs):

1,2,4,7,8,9,12,15

hast ist doch ziemlich eindeutig wo die Lücken sind.

In einer Stored Procedure ist es auch kein Problem. Eine while-Schleife von 1 bis Max(Tabelle.ID) und schauen ob PK[i] existiert.
Falls es in Paradox Stored Procedures gibt, dann ist das wahrscheinlich die einfachste Lösung.

jobo 16. Feb 2016 13:54

AW: Lücken in fortlaufender Nummerierung finden
 
Hier noch eine outer join Variante statt not exists:
Code:
select a.<id>, a. <irgendeinanderesKontrollfeld>,
       b.<id> as bid,
       b.<..> as b<kontrollfeld>
  from <mytable> a
  left join <mytable> b
    on a.ID = b.ID + 1
 where b.<kontrollfeld> is null
Könnte flotter sein, bin ich mir bei dieser Art der ISAM(?) Datenhaltung auch nicht sicher.
Auch hier gibt es das 1er Problem.

Ich denke aber als Indikator für "1 oder mehrere Datensätze fehlen ab hier" reicht es schon.
Besser geht es wahrscheinlich nur mit Delphi, TQuery, alles abfragen und durchsteppen und mitzählen.

@geben Sie mir alle Brötchen, die..
Ich kann in der Variante oben durchaus alle nicht vorhanden Brötchen einbinden. Dazu müsste ich eine Tabelle ergänzen, die alle Lückengrößen beinhaltet, die ich prüfen möchte. Also mit einer Tabelle 10 Datensätze und den Werten 1-10 finde ich alle Lücken bis Größe 10, usw.

Die Stored Procedures in Paradox sind "Delphi" oder andere Clients.

jobo 16. Feb 2016 13:55

AW: Lücken in fortlaufender Nummerierung finden
 
Zitat:

Zitat von Neutral General (Beitrag 1330509)
Wieso das? Wenn du in einer Tabelle die IDs (PKs):

1,2,4,7,8,9,12,15

hast ist doch ziemlich eindeutig wo die Lücken sind.

Ich denke es ging ihm um eine Lösung per SQL.

mkinzler 16. Feb 2016 14:05

AW: Lücken in fortlaufender Nummerierung finden
 
Zitat:

Zitat von jobo (Beitrag 1330511)
Zitat:

Zitat von Neutral General (Beitrag 1330509)
Wieso das? Wenn du in einer Tabelle die IDs (PKs):

1,2,4,7,8,9,12,15

hast ist doch ziemlich eindeutig wo die Lücken sind.

Ich denke es ging ihm um eine Lösung per SQL.

Bei einem anderen DBMS könnte man u.U. hierfür eine temporäre Tabelle nehmen ( von kleinsten Wert + 1 bis höchsten Wert -1)

Bei Paradox wird es am Einfachsten sein mit dieser Schleife auf leere Ergebnismengen zu Überprüfen.

himitsu 16. Feb 2016 14:12

AW: Lücken in fortlaufender Nummerierung finden
 
Zitat:

Zitat von frankyboy1974 (Beitrag 1330506)
Falls jemand doch noch eine SQL-Lösung findet, wäre ich sehr gespannt.

Generator, oder wie man das nochmal nannte.
http://www.postgresql.org/docs/9.1/s...tions-srf.html

Das generiert dir eine Reihe von Datensätzen, nach einem bestimmten Muster.

Kann man selber bauen (stored procedure) und gibt es auch oftmals fertig.

jobo 16. Feb 2016 14:13

AW: Lücken in fortlaufender Nummerierung finden
 
Das gibt's alles nicht in local sql.
In Postgres generate_series(), in mysql einfach mit variablen in SQL, usw.

ah, steht ja in deinem Link :oops:
:)

Uwe Raabe 16. Feb 2016 14:18

AW: Lücken in fortlaufender Nummerierung finden
 
Da hier ja sowieso kein potenter SQL-Server zum qualmen gebracht werden soll, würde ich hier den Heimvorteil der BDE/Paradox-Kombination ausnutzen: Was spricht denn gegen ein sequentiuelles Durchlaufen der Tabelle. Dabei kannst du doch die Lücken direkt erkennen und auflisten. Das hier unbeding mit SQL zu vergewaltigen ist doch gar nicht zielführend.

Delphi-Quellcode:
procedure FindGaps(DataSet: TDataSet; FieldName: string; Target: TStrings; CheckFirst: Boolean);

  procedure AddGap(von, bis: Integer);
  var
    S: string;
  begin
    if von < bis then begin
      S := Format('%d-%d', [von, bis]);
    end
    else begin
      S := Format('%d', [von]);
    end;
    Target.Add(S);
  end;

var
  fld: TField;
  id: Integer;
  nextId: Integer;
  S: string;
begin
  Target.BeginUpdate;
  try
    DataSet.Active := true;
    if DataSet.IsEmpty then
      Exit;
    { DataSet muss nach FieldName sortiert sein }
    fld := DataSet.FieldByName(FieldName);
    DataSet.First;
    if CheckFirst then begin
      nextId := 1;
    end
    else begin
      nextId := fld.AsInteger;
    end;
    repeat
      id := fld.AsInteger;
      if nextId < id then begin
        AddGap(nextId, id - 1);
      end;
      nextId := id + 1;
      DataSet.Next;
    until DataSet.Eof;
  finally
    Target.EndUpdate;
  end;
end;

jobo 16. Feb 2016 14:21

AW: Lücken in fortlaufender Nummerierung finden
 
Genau, der TE wollte zwar SQL, aber Dein Vorschlag finde ich hier auch am sinnvollsten!

Neutral General 16. Feb 2016 14:26

AW: Lücken in fortlaufender Nummerierung finden
 
Würde es für Paradox ne SQL-Lösung geben wäre die auch sehr wahrscheinlich schneller als eine in Delphi.
War also keine schlechte Idee nach SQL zu fragen bzw. es mit SQL zu versuchen.

noisy_master 16. Feb 2016 14:35

AW: Lücken in fortlaufender Nummerierung finden
 
Mann oh mann, ich hätte nicht gedacht, dass dazu SO viele Antworten kommen... Danke erst mal an alle

Dass das Ganze "von Hand" geht(durchgehen nach Uwe's Vorschlag) war mir auch klar, und ist definitiv die übersichtlichste und "flexibelste" Variante, da dort auch größere Lücken auffindbar sind. Ich hatte halt nur auf eine "einfache elegante" Variante per SQL gehofft....

Aber ich habe alles an Antworten bekommen, was man sich so wünschen kann...

Werde es mal mit Uwe's "durchgehen" versuchen...wird zwar nicht schnell sein, aber erstmal egal

jobo 16. Feb 2016 14:36

AW: Lücken in fortlaufender Nummerierung finden
 
ot
Zitat:

Zitat von Neutral General (Beitrag 1330525)
Würde es für Paradox ne SQL-Lösung geben wäre die auch sehr wahrscheinlich schneller als eine in Delphi.
War also keine schlechte Idee nach SQL zu fragen bzw. es mit SQL zu versuchen.

Ich denke, das ist genau das Problem, auf das Uwe hinweisen wollte. Der "Server" von Paradox ist immer(!) der eigene PC. Idealerweise liegt das Datenfile lokal und es gibt keinen Netzwerkzugriff /-transport.
Das SQL wird vermutlich eh von der BDE in sequentielle Zugriffe umgebaut, mein eigener Hinweis bezüglich not exists versus outer join ist ja auch fragwürdig bei dieser Art File DB.

SQL=schneller als per Clientprogrammierung finde ich auch immer eine gute Idee, gilt m.E. nur wenn tatsächlich ein echter Server im Spiel ist.
/ot

Uwe Raabe 16. Feb 2016 15:11

AW: Lücken in fortlaufender Nummerierung finden
 
Ich habe den Code nochmal etwas umgebaut, da der erste Datensatz überflüssigerweise zweimal überprüft wurde. Zusätzlich habe ich noch ein Begin/Endupdate auf Target eingebaut.

Leider habe ich gerade keine richtig große Paradox-Tabelle da, aber auf meinem System schafft diese Methode die 4500 Sätze in 5 ms.

hoika 16. Feb 2016 16:56

AW: Lücken in fortlaufender Nummerierung finden
 
Hallo,
wenn es nur eine Tabelle ist, dann wirklich lokal machen mit 2 String-Listen.

LocalSQL auf eine Paradox-Tabelle (Achtung, also keine Generatoren möglich)
würde ich sein lassen, das ist furchtbar langsam (naja, kommt auf die Tabelle und die SQL-Anweisung an).

Noch eine Frage zu den Lücken:
Auch das AutoInc erzeugt doch Lücken beim Löschen,
oder hast du standardmäßig keine Datensätze gelöscht?

Paradox:
index out of date
blob has been modified

Gott sei dank ich bin da weg ;)


Heiko


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:24 Uhr.

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