Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi selectable stored procedure (https://www.delphipraxis.net/191248-selectable-stored-procedure.html)

SvB 25. Dez 2016 11:54

Datenbank: Firebird • Version: 2.5 • Zugriff über: Firedac

selectable stored procedure
 
Ich habe eine selectable stored procedure die ich mit einem Parameter (KDNR) aufrufe. Diesen Parameter benutze ich im WHERE des SQL.
Code:
SELECT ... FROM Kunden WHERE KDNR=:KDNR
Jetzt möchte ich einen optionalen zweiten Parameter (ID) übergeben. Ist es möglich das WHERE abhängig vom übergebenen Parameter zu wählen. Entweder ist dann KDNR null oder ID null.
Das SELECT und die Felder sind immer gleich.
Also
Code:
SELECT ... FROM Kunden WHERE KDNR=:KDNR
oder
SELECT ... FROM Kunden WHERE ID=:ID
Geht so etwas, dass ich nicht alles doppelt habe?

jobo 25. Dez 2016 12:12

AW: selectable stored procedure
 
Du kannst Select Statements, die die gleiche Struktur ausgeben per Union bzw. Union all hintereinander hängen:
Code:
select feld1, .. feldx from mytable where ein Bedingung
union
select feld1, .. feldx from mytable where andere Bedingung
Dann gibt es das Problem auf NULL zu prüfen. Es wird nicht mit
Code:
feldxy<!>=Null
gemacht, sondern mit

Code:
feldxy is <not> Null
Das bedeutet, Du musst vorher(vor dem SQL Abruf) wissen, ob ein PArameter leer ist oder nicht und das SQL entsprechend anlegen.
Das sollte aber in einer SP kein Problem sein oder?
Du schickst dann nach der Prüfung unterschiedliche SQL Statements ab, die entweder den einen oder den anderen Parameter nutzen.

P.S.: ach so, Du kannst natürlich die verschiedenen Kriterien mit OR hintereinander in die WHERE Bedingung hängen. Das bedeutet aber etwas Ressourcenverschwendung. Denn es werden dann alle 4, 5 .. Abfragen durchgeführt auch wenn Du immer nur eine brauchst.
P.S.2: Das UNION fasst automatisch Mehrfachergebnisse zusammen zu einem Datensatz, UNION ALL würde alle Ergebnisse einzeln aufführen, also auch Mehrfachtreffer.

SvB 25. Dez 2016 12:31

AW: selectable stored procedure
 
OK, alles klar.
Ich möchte nichts hintereinander hängen.
Ich möchte praktisch einmal nach Kundennummer (KDNR) oder ID abfragen. Die zurückgegebenen Struktur ist immer gleich.
Code:
CREATE PROCEDURE SP_CXKD (
    KDNR varchar(8) )
RETURNS ( 
    KD_NR varchar(8),
    KD_NAME1 varchar(35) )
AS
BEGIN
    FOR SELECT
        a.KD_NR,
        a.KD_NAME1
    FROM CXKD a WHERE a.KD_NR=:KDNR  <--- einziger Unterschied
    INTO
        KD_NR,
        KD_NAME1 
    DO
    BEGIN
        SUSPEND;
    END
END!!
oder
Code:
CREATE PROCEDURE SP_CXKD (
    ID integer )
RETURNS ( 
    KD_NR varchar(8),
    KD_NAME1 varchar(35) )
AS
BEGIN
    FOR SELECT
        a.KD_NR,
        a.KD_NAME1
    FROM CXKD a WHERE a.ID=:ID   <--- einziger Unterschied
    INTO
        KD_NR,
        KD_NAME1 
    DO
    BEGIN
        SUSPEND;
    END
END!!
kann man das geschickt in eine einzelne SP zusammenfassen?

Neumann 25. Dez 2016 12:57

AW: selectable stored procedure
 
Ich sehe den Sinn der SP hier nicht so richtig, es sind doch nur einfache Abfragen, die ein Select auf die Tabelle auch reichen würde.

Man könnte es so lösen:
Code:
CREATE PROCEDURE SP_CXKD (
    KDNR varchar(8), ID integer )
RETURNS ( 
    KD_NR varchar(8),
    KD_NAME1 varchar(35) )
AS
BEGIN
   if (KDNR <> '') then
   begin
    FOR SELECT a.KD_NR, a.KD_NAME1 FROM CXKD a WHERE a.KD_NR=:KDNR INTO KD_NR, KD_NAME1 
    DO SUSPEND;
   END ELSE
   begin
    FOR SELECT a.KD_NR, a.KD_NAME1 FROM CXKD a WHERE a.ID=:ID INTO KD_NR, KD_NAME1 
    DO SUSPEND;
   END

 
END!!
So sollte es gehen. Man übergibt immer 2 Parameter.

jobo 25. Dez 2016 15:14

AW: selectable stored procedure
 
Tja der Sinn, vielleicht denkt der TE, SP ist schneller?
Das wäre hier falsch gedacht.

Zum Vorschlag:
Im Prinzip ok, ich würde allerdings überlegen, wie die Prozedur aufgerufen werden kann/soll und wie entsprechend die Parameter abzusichern sind.
Idiotensicher mit vollständiger Prüfung innerhalb der SP> welche Parameter sind überhaupt befüllt?
>Welcher Aufruf des Select macht dann also Sinn?

Geschützter Aufruf> Anwendung überwacht die Befüllung der Parameter und setzt nur vorgeprüfte Parameterkombi ab.

Im Beispiel ist die Parameterprüfung mit anschließender Verzweigung recht grob und kann zu schlechten Ergebnissen führen.

SvB 25. Dez 2016 15:17

AW: selectable stored procedure
 
Danke.
Das hier waren nur Beispiele, ich wollte keine 50 Zeilen Code posten.
Ich probiere das so mal aus.

SvB 25. Dez 2016 16:21

AW: selectable stored procedure
 
Aufgrund eurer Infos habe ich generell bisschen mit "stored procedures" vs "View" herumgespielt.
Einmal habe ich meine Abfrage komplett auf SP und das andere mal komplett auf eine View aufgebaut.
Meine Datenbankverbindung läuft über ein VPN auf die DB in der Zentrale.
Die Rückgabe der Daten über SP benötigt durchweg ca. 300ms.
Bei der View sind es beim ersten Aufruf ca. 550ms, alle weiteren sind dann unter 200ms.
Ich glaube ich werde mal weiter in Richtung View gehen.

Neumann 25. Dez 2016 18:42

AW: selectable stored procedure
 
Sicher ist die Verzweigunsprüfung nur als Beispiel gedacht und sollte real etwas differenzierter sein.

Ob ein View, eine Sp oder eine direkte Abfrage schneller ist, kann man nicht pauschal sagen. Gerade Abfragen auf Views oder Sps mit Joins könne sehr lange dauern.

Manchmal ist es sogar besser, die View-Daten in eine Temporäre Tabelle zu Kopieren und dann darauf seine Selects loszulassen.

p80286 25. Dez 2016 23:19

AW: selectable stored procedure
 
Ich frage mich wofür diese Abfrage gut sein soll.
Wie wäre es mit
Code:
Select id from tab1 where kdnr=:kdnr;

select Daten from tab1.....where id=:id
and bed1=....;
Gruß
K-H

jobo 26. Dez 2016 23:35

AW: selectable stored procedure
 
Zitat:

Zitat von SvB (Beitrag 1357181)
Bei der View sind es beim ersten Aufruf ca. 550ms, alle weiteren sind dann unter 200ms.
Ich glaube ich werde mal weiter in Richtung View gehen.

Arbeitest Du mit Parametern oder machst Du Stringreplace / Format im Select Statement.
Vielleicht bekommst Du mit Parameter Verwendung die anfänglichen 550 ms noch gedrückt.

Und
Hab jetzt nicht mehr alles im Blick, aber wieso Views? Auch wenn ich immer die Verwendung von Views empfehle- grundsätzlich-, auch ein View bringt hier nichts gegenüber der SP. Ein simples Select sollte genau so schnell sein wie der View. Die Varianz liegt doch nur in dem wechselnden Feld in der Where Bedingung.

Ich frage deswegen, weil man auf die Idee kommen könnte, die beiden Abfrage-Varianten per Union zusammenzufassen, indem man die beiden abzufragenden Felder in einer künstlichen Spalte zusammenführt und dann eine einheitliche Abfrage auf das neue virtuelle Feld machen kann. Da ist man dann wieder beim Thema Resourcenverschwendung.
Je nachdem wie kleine Deine Tabelle ist, fällt sowas dann anfangs nicht durch schlechte Antwortzeiten auf.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:35 Uhr.
Seite 1 von 2  1 2      

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