Seite 1 von 1

Sql-Abfrage flexibel gestalten

Verfasst: Mittwoch 21. Oktober 2020, 13:00
von 16_Bit
Hallo,

ich habe mehrere Tabellen die unter anderem eine Spalte mit der Bezeichnung 'dateinummer' enthalten. Nun möchte ich bei genannter Spalte feststellen, ob es Lücken bei den Nummern gibt. Zum Beispiel:

Code: Alles auswählen

1001
1002
1005
1006
1008
Hier muss dann 1003, 1004 und 1007 gefunden werden.

Diese Aufgabe erfüllt diese Abfrage bereits.

Code: Alles auswählen

SELECT A.X FROM (
WITH RECURSIVE
     cnt(X) AS (VALUES(28491) UNION ALL SELECT X+1 FROM cnt WHERE X < (32709)) 
SELECT X FROM cnt ) A LEFT JOIN ( SELECT CAST( dateinummer AS NUMBER ) AS dateinummer FROM tabellenname_platzhalter WHERE dateinummer >= 28491 and dateinummer <= 32709 ) B
ON A.X = B.DATEINUMMER
WHERE B.DATEINUMMER IS NULL
LIMIT ( 32709 - 28491 + 1 )
Wenn ihr eine andere elegantere Variante für SQLite kennt, könnt ihr diese gerne mitteilen.

Mein Problem ist jetzt jedoch ein anderes. Die Zahlen 32709 und 28491 und der Tabellenname (tabellenname_platzhalter) sollen veränderbar sein. Ich habe leider keinen blassen Schimmer, wie ich das nach Python 3 übersetze.

Wie kann ich diese drei Variablen in das SQL einbauen?

Code: Alles auswählen

number_from
number_to
tablename

Re: Sql-Abfrage flexibel gestalten

Verfasst: Mittwoch 21. Oktober 2020, 13:19
von Sirius3
Nein, Tabellennamen sollen nicht veränderbar sein, alles andere geht über Platzhalter. Welche hängt von der verwendeten Datenbankanbindung ab.

Re: Sql-Abfrage flexibel gestalten

Verfasst: Mittwoch 21. Oktober 2020, 17:16
von DasIch
Dazu müsstest du string formatting nutzen, wobei du natürlich schauen musst wie du SQL Injection verhinderst.

@Sirius3: Ich glaub man kann davon ausgehen dass jemand von recursive CTEs nicht nur gehört hat sondern sie auch einsetzen kann auch schon mal von SQL Injection gehört hat und sich den Risiken bewusst ist.

Re: Sql-Abfrage flexibel gestalten

Verfasst: Mittwoch 21. Oktober 2020, 17:36
von Sirius3
@DasIch: Stringformatierung ist ja nur nötig, wenn tatsächlich jemand den Tabellennamen variabel machen will. Aber dann ist das Datenbank-Design schon kaputt.

Ich denke, den SQL-Ausdruck kann man sich irgendwoher ergoogeln,

Re: Sql-Abfrage flexibel gestalten

Verfasst: Mittwoch 21. Oktober 2020, 18:01
von DasIch
Variable Tabellennamen sind sicherlich eine red flag aber es gibt dafür durchaus legitime Gründe. Partitioning wäre so ein Grund.

Ich hab übrigens festgestellt dass SQLAlchemy nicht nur Variable Spaltennamen unterstützt sondern auch Variable Tabellennamen: https://docs.sqlalchemy.org/en/13/core/ ... ion-column

Re: Sql-Abfrage flexibel gestalten

Verfasst: Donnerstag 22. Oktober 2020, 13:59
von 16_Bit
Zum testen habe ich diesen Code erst mal geschrieben.

Code: Alles auswählen

def suche_luecken(mandant):
    sql_vp = 'SELECT A.X FROM (WITH RECURSIVE cnt(X) AS (VALUES((SELECT MIN(dateinummer) FROM VP)) \
        UNION ALL SELECT X+1 FROM cnt WHERE X < ((SELECT MAX(dateinummer) FROM VP))) \
        SELECT X FROM cnt ) A LEFT JOIN ( SELECT CAST( dateinummer AS NUMBER ) AS dateinummer \
        FROM VP WHERE dateinummer >= (SELECT MIN(dateinummer) FROM VP) and dateinummer <= (SELECT MAX(dateinummer) FROM RUV) ) \
        B ON A.X = B.DATEINUMMER WHERE B.DATEINUMMER IS NULL LIMIT ( (SELECT MAX(dateinummer) FROM VP) - (SELECT MIN(dateinummer) FROM VP) + 1 )'

    if mandant == 'VP':
        connection = sqlite3.connect(db_file)
        cursor = connection.cursor()
        cursor.execute(sql_vp)
        result = cursor.fetchall()
        connection.close()
Leider bekomme ich diese Fehlermeldung.

Code: Alles auswählen

Traceback (most recent call last):
  File "/usr/local/bin/mdk-check.py", line 183, in <module>
    main()
  File "/usr/local/bin/mdk-check.py", line 179, in main
    suche_luecken('VP')
  File "/usr/local/bin/mdk-check.py", line 80, in suche_luecken
    datenbank_zeiger.execute(sql_vp)
sqlite3.OperationalError: near "cnt": syntax error
In DBeaver funktioniert das SQL, nur innerhalb von Python nicht. Kann der Fehler am Modul sqlite3 liegen???

Re: Sql-Abfrage flexibel gestalten

Verfasst: Donnerstag 22. Oktober 2020, 17:06
von __blackjack__
@16_Bit: Ich glaube nicht dass das irgenwo anders funktioniert, denn ich weiss nicht was der Teilausdruck ``WHERE X < ((SELECT MAX(dateinummer) FROM VP))) SELECT X FROM cnt) A`` bedeuten sollte. Dieses ``SELECT X FROM cnt`` macht an der Stelle keinen Sinn und dürfte syntaktisch falsch sein.