Autor |
Beitrag |
UliTs
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: Do 13.02.20 16: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 Th69: URL-Titel hinzugefügt.
|
|
OlafSt
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Do 13.02.20 16: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
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: Do 13.02.20 21: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
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: Fr 14.02.20 13: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.
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 Th69: Code-Tags hinzugefügt
|
|
Th69
Beiträge: 4791
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 14.02.20 13:35
Für diesen Beitrag haben gedankt: UliTs
|
|
UliTs
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: Fr 14.02.20 15: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
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: Sa 15.02.20 11:23
Bei der folgenden Procedure
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
Quelltext
als Rückgabe
erwarten. Es kommt aber
als Rückgabewert .
Wie komme ich an das Ergebnis des letzten select-Statements?
|
|
Ralf Jansen
Beiträge: 4706
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Sa 15.02.20 12:38
Die StoredProc Klasse wie sie auch im Link von Th69 benutzt wird hat eine NextRecordSet Methode um an die weiteren Datasets zu kommen
Für diesen Beitrag haben gedankt: UliTs
|
|
Th69
Beiträge: 4791
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Sa 15.02.20 14:44
@UliTs: Ist die Stored Procedure von dir? Warum benutzt du denn dort verschiedene select Anweisungen?
Für diesen Beitrag haben gedankt: UliTs
|
|
UliTs
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: So 16.02.20 22:46
Th69 hat folgendes geschrieben : | @UliTs: Ist die Stored Procedure von dir? Warum benutzt du denn dort verschiedene select Anweisungen? |
Wie geschrieben um mein Problem zu zeigen.
|
|
UliTs
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: So 16.02.20 23:18
Ralf Jansen hat folgendes geschrieben : | Die StoredProc Klasse wie sie auch im Link von Th69 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:
Quelltext 1: 2: 3:
| ... call ProtokollEinfuegen; ... |
Das heisst, dies wird dann auch als eine Ergebnistabelle genommen?
Normalerweise würde ich sagen, dann mache ich
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
Beiträge: 4791
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mo 17.02.20 09: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:
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
Beiträge: 4706
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 17.02.20 13: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
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Mo 17.02.20 13:30
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
Für diesen Beitrag haben gedankt: UliTs
|
|
Th69
Beiträge: 4791
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mo 17.02.20 14:52
Ralf Jansen hat folgendes geschrieben : | 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
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: Mo 17.02.20 20: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
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: Mo 17.02.20 21:02
OlafSt hat folgendes geschrieben : | ...
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 Th69: Delphi-Tags hinzugefügt
|
|
Th69
Beiträge: 4791
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Di 18.02.20 09: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
Beiträge: 38
Win XP*, Win 7
xBase++, Delphi 10.3
|
Verfasst: Mi 19.02.20 11:47
Th69 hat folgendes geschrieben : | 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 ...
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
Beiträge: 4706
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 19.02.20 20: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
|
|