Autor Beitrag
UliTs
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: Do 13.02.20 17:32 
Ausgehend hiervon: Script in MySql schreiben
habe ich inzwischen mit Erfolg diverse Stored Procedures geschrieben.

Dabei gab es bisher aber keine Rückgabewerte. Jetzt möchte ich mehrere Rückgabewerte realisieren und abfragen.
Wie macht man das?


Moderiert von user profile iconTh69: URL-Titel hinzugefügt.
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 470
Erhaltene Danke: 94

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Do 13.02.20 17:45 
Das ist sehr einfach. Anstelle DataSet.ExecSQL rufst du die Stored Procedure mit DataSet.Open; auf.

Anschließend kannst du mit DataSet.Fields[n].AsXXX die Rückgabewerte der StoredProc abholen. FieldByName funktioniert nicht, da die Return Values ja keine Feldnamen haben.

DataSet.Close; nicht vergessen ;)

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.

Für diesen Beitrag haben gedankt: UliTs
UliTs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: Do 13.02.20 22:25 
Hallo OlafSt,

schon einmal vielen Dank! Das hört sich gut an. Ich habe es bisher unter anderem mit FDQuery versucht, bin aber damit gescheitert.
Heute Nacht habe ich Zeit und versuche es...

Viele Grüße

Uli
UliTs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: Fr 14.02.20 14:01 
Bin frustriert.
Komme kein Stück weiter ...

Wenn ich eine einfache Stored Procedure nehme mit einem Integer-Eingabe-Parameter und als Ergebnis soll der Eingabewert +1 und ein weiteres Zeichen-Feld mit dem Wert 'TestProcedure' herauskommen, wie kann ich dann die Rückgabewerte abfragen?

also z.B.
ausblenden Quelltext
1:
2:
3:
4:
5:
stored procedure TestUli( in Ziffer int, out Ziffer2 int, out Bemerkung text );
begin
  set Ziffer2 = Ziffer+1;
  set Bemerkung = 'TestProcedure';
end

und dann?

Moderiert von user profile iconTh69: Code-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4232
Erhaltene Danke: 892

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Fr 14.02.20 14:35 

Für diesen Beitrag haben gedankt: UliTs
UliTs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: Fr 14.02.20 16:01 
Hallo Th69,

vielen Dank für den Link. Leider bin ich damit nicht weiter gekommen.
Allerdings habe ich beim Einsatz von TFDQuery folgendes festgestellt: ich kann damit mittels "call" die Stored Procedure ausführen. Als Rückgabe kommen die Werte des ersten innerhalb der Stored Procedure vorkommenden select-Befehls zurück (wie sinnfrei ...). Wenn es die Werte des letzten select-Befehls wären, würde es wunderbar funktionieren.
UliTs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: Sa 15.02.20 12:23 
Bei der folgenden Procedure
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure Test( in Nr int );
begin
  declare Result int;

  select Nr-5;
  set Result = (select Nr+5);
  select Nr,Result;
end

würde ich z.B. bei Aufruf von
ausblenden Quelltext
1:
call Test( 100 );					

als Rückgabe
Zitat:
100 , 105

erwarten. Es kommt aber
Zitat:
95

als Rückgabewert :-( .

Wie komme ich an das Ergebnis des letzten select-Statements?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4456
Erhaltene Danke: 919


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 15.02.20 13:38 
Die StoredProc Klasse wie sie auch im Link von user profile iconTh69 benutzt wird hat eine NextRecordSet Methode um an die weiteren Datasets zu kommen

Für diesen Beitrag haben gedankt: UliTs
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4232
Erhaltene Danke: 892

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Sa 15.02.20 15:44 
@UliTs: Ist die Stored Procedure von dir? Warum benutzt du denn dort verschiedene select Anweisungen?

Für diesen Beitrag haben gedankt: UliTs
UliTs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: So 16.02.20 23:46 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
@UliTs: Ist die Stored Procedure von dir? Warum benutzt du denn dort verschiedene select Anweisungen?

Wie geschrieben um mein Problem zu zeigen.
UliTs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: Mo 17.02.20 00:18 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Die StoredProc Klasse wie sie auch im Link von user profile iconTh69 benutzt wird hat eine NextRecordSet Methode um an die weiteren Datasets zu kommen

Ich habe darüber nachgedacht und glaube, dass dies genau mein Problem ist!
Wenn ich es richtig verstehe, kann eine Stored Procedure nicht nur eine Tabelle sondern mehrere als Ergebnis haben.
Das will ich in meinem Fall aber gar nicht. Ich rufe aber innerhalb der Stored Procedure eine andere Stored Procedure "ProtokollEinfuegen" auf, die als Ergebnis eine Tabelle mit 1 Spalte und 1 Datensatz hat:

ausblenden Quelltext
1:
2:
3:
  ...
  call ProtokollEinfuegen;
  ...


Das heisst, dies wird dann auch als eine Ergebnistabelle genommen?

Normalerweise würde ich sagen, dann mache ich

ausblenden Quelltext
1:
2:
3:
  ...
  set PrResult = (call ProtokollEinfuegen);
  ...

und schon sollte es funktionieren.
Aber dann bekomme ich eine Fehlermeldung und kann die Stored Procedure nicht speichern...
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4232
Erhaltene Danke: 892

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Mo 17.02.20 10:20 
Also enthält ProtokollEinfuegen eine select-Anweisung, welche du dann in eine eigene select-Anweisung übernehmen möchtest (damit du nur genau eine Tabelle zurückgibst)?
Das ist leider bei MySql nicht direkt möglich, s.a. How to call a stored procedure using select statement in mysql.
Wie aus der Antwort zu ersehen muß entweder die Procedure in eine temporäre Tabelle schreiben oder aber du machst daraus eine Funktion (UDF), welche diesen einen Datenwert zurückgibt, den du dann übernehmen kannst:
ausblenden SQL-Anweisung
1:
select ProtokollEinfuegen; -- wobei du dann einen besseren Funktionsnamen nehmen solltest!					


Edit: Sehe gerade, daß eine UDF nur in C++ erstellt werden kann (Adding a User-Defined Function) - das scheidet hier wohl aus.

PS: Nur noch mal zur Bestätigung, du verwendest MySql (denn bisher ist nur in deinem ersten Link davon zu lesen)?

Für diesen Beitrag haben gedankt: UliTs
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4456
Erhaltene Danke: 919


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 17.02.20 14:25 
Zitat:
Stored Procedure "ProtokollEinfuegen" auf, die als Ergebnis eine Tabelle mit 1 Spalte und 1 Datensatz hat:


1 Spalte, 1 Zeile das klingt ziemlich Skalar. Warum ist das ein Tabelle die da zurückkommt?

Zitat:
Edit: Sehe gerade, daß eine UDF nur in C++ erstellt werden kann (Adding a User-Defined Function) - das scheidet hier wohl aus.


Eine Function (nicht UDF) die man direkt in ein anderen SQL Statement benutzen kann geht auch im üblichen MySql Syntax.

Für diesen Beitrag haben gedankt: UliTs
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 470
Erhaltene Danke: 94

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Mo 17.02.20 14:30 
user profile iconUliTs hat folgendes geschrieben Zum zitierten Posting springen:
Bei der folgenden Procedure
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure Test( in Nr int );
begin
  declare Result int;

  select Nr-5;
  set Result = (select Nr+5);
  select Nr,Result;
end

würde ich z.B. bei Aufruf von
ausblenden Quelltext
1:
call Test( 100 );					

als Rückgabe
Zitat:
100 , 105

erwarten. Es kommt aber
Zitat:
95

als Rückgabewert :-( .

Wie komme ich an das Ergebnis des letzten select-Statements?


FDQuery.Fields[0].AsInteger sollte die 95 ausgeben.
FDQuery.Fields[1].AsInteger sollte die 105 ausgeben.

Und so weiter. Ich dachte, die Array-Eigenschaft wäre schon Hinweis genug ;)

Moderiert von user profile iconTh69: Delphi-Tags hinzugefügt

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.

Für diesen Beitrag haben gedankt: UliTs
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4232
Erhaltene Danke: 892

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Mo 17.02.20 15:52 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Eine Function (nicht UDF) die man direkt in ein anderen SQL Statement benutzen kann geht auch im üblichen MySql Syntax.

Oh, danke für den Hinweis - ich hatte mich schon gewundert, daß es nur über UDF funktionieren sollte. Bin beim Suchen nur auf die UDF-Seiten gestoßen, jetzt aber habe ich auch mittels Suche nach ""mysql create function" CREATE PROCEDURE and CREATE FUNCTION Statements gefunden. Und damit ist es ja dann noch einfacher, wenn die Funktion einfach den Datensatzwert direkt zurückgibt (mittels RETURN).
UliTs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: Mo 17.02.20 21:59 
Also erst einmal vielen Dank an alle, dass Ihr so hilfsbereit seit! Das hilft mir sehr. Da ich nicht mit Windows und dem Internet groß geworden bin, fällt doch einiges recht schwer (Internet Recherche, englische Beiträge verstehen). Dank Eurer Hilfe finde ich jetzt schon einmal einen Weg, wie ich weiterkomme!
--
Eine Sache, die schon (oder in einem Link?) angesprochen wurde, ist die, wie man mit Hilfe von temporären Tabellen das Ergebnis von Stored Procedure's in komplexere Select Statements einbaut. Ich habe auch schon versucht, so mit temporären Tabellen zu arbeiten. Bin aber noch daran gescheitert...
Also noch eine konkrete Frage: wie kann ich das Ergebnis einer Stored Procedure in eine temporäre Tabelle speichern?
UliTs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: Mo 17.02.20 22:02 
user profile iconOlafSt hat folgendes geschrieben Zum zitierten Posting springen:
...

FDQuery.Fields[0].AsInteger sollte die 95 ausgeben.
FDQuery.Fields[1].AsInteger sollte die 105 ausgeben.

Und so weiter. Ich dachte, die Array-Eigenschaft wäre schon Hinweis genug ;)

Hallo OlafSt,
vielen Dank. Aber ich glaube, dass Du Dich Irrst. mit .Fields[0] und .Fields[1] kommt man meines Erachtens an die Werte der ersten beiden Spalten eines Select-Ergebnisses. Wenn es mehrere Select-Mengen als Rückgabe gibt, muss es noch eine andere Lösung geben.

Moderiert von user profile iconTh69: Delphi-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4232
Erhaltene Danke: 892

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Di 18.02.20 10:41 
Eine temporäre Tabelle wird mit dem Schlüsselwort TEMPORARY erstellt, s. MySQL Temporary Table bzw. CREATE TEMPORARY TABLE Statement (auf deutsch habe ich dazu keine guten Tutorials gefunden).
Aber für nur einen Datenwert solltest du einfach aus der Prozedur eine Funktion machen.

Und zu
UliTs hat folgendes geschrieben:
Wenn es mehrere Select-Mengen als Rückgabe gibt, muss es noch eine andere Lösung geben.

Dazu wurde schon die Antwort gegeben: NextRecordSet (auch die TFDQuery-Klasse hat diese Methode).
UliTs Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38

Win XP*, Win 7
xBase++, Delphi 10.3
BeitragVerfasst: Mi 19.02.20 12:47 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Und zu
UliTs hat folgendes geschrieben:
Wenn es mehrere Select-Mengen als Rückgabe gibt, muss es noch eine andere Lösung geben.

Dazu wurde schon die Antwort gegeben: NextRecordSet (auch die TFDQuery-Klasse hat diese Methode).

Danke! Ich habe wohl den Wald vor lauter Bäumen nicht gesehen :oops: ...


user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Eine temporäre Tabelle wird mit dem Schlüsselwort TEMPORARY erstellt, s. MySQL Temporary Table bzw. CREATE TEMPORARY TABLE Statement (auf deutsch habe ich dazu keine guten Tutorials gefunden).

Ich kenne es vom Advantage Database Server (ADS) so, dass ich direkt durch ein select statement das Ergebnis in eine temporäre Tabelle schreiben kann, die in dem Moment auch noch erzeugt wird. Ich vermute, dass geht in MySql nicht?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4456
Erhaltene Danke: 919


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 19.02.20 21:39 
Zitat:
Ich kenne es vom Advantage Database Server (ADS) so, dass ich direkt durch ein select statement das Ergebnis in eine temporäre Tabelle schreiben kann, die in dem Moment auch noch erzeugt wird. Ich vermute, dass geht in MySql nicht?


In dem 2.ten Link den du hier zitiert hast zeigt das einzige Code Beispiel genau das. Ohne den dort gezeigten Limit 0 Anhang am Statement würden natürlich auch die Daten kopiert werden die das Select Statement liefert.

Für diesen Beitrag haben gedankt: UliTs