-
das habe ich auch zuerst gedacht, aber wenn im CommandText
das (?) rauslasse wird das Programm zwar aufgerufen, scheitert dann
auf der AS400 aber am fehlenden Eingangsparameter.
Das mit dem Toolkit-Tip habe ich schon probiert, leider musste ich
feststellen, dass der Zugriff per SQL bei Provider=IBMDA400 langsamer ist
als mit Driver=Client Access ODBC Driver (32-bit) im Connectionstring.
Desweiteren ist nicht ganz ersichtlich, wie denn jetzt über das ADODB.
Connection-Object direct Parameter an die Execute-Methode übergeben werden
können, da dieses Objekt keine Parameter-Collection hat , ist dieses *N
vielleicht ein Umwandlungs-Parameter des ILERPG-Programms auf der AS400?
Vielen Dank für Ihre Hilfe, wüssten sie vielleicht noch einen anderen Tip?
-
Ok, Ok, mein Fehler.... habe nicht gesehen, wie man Programme
auswählen kann... hab es dann soweit verfolgt... dort wird dann
der Commandtext so generiert....
{{CALL /QSYS.LIB/SAGPLIB.LIB/PSEULABRPG.PGM(?)}}
Alles andere ist identisch mit meinem Aufruf, aber bei diesem
Call bemängelt er schon den ersten Slash vor QSYS als ungültigen
Token...
...was mir leider auch nicht wirklich hilft 
Haben Sie noch eine andere Idee?
-
Was den IBMDA400 angeht hast du leider recht !
Ich verwende auch nicht den {{CALL ...}}, sondern erstelle mir eine Prozedur:
myConn.Execute "CREATE PROCEDURE QTEMP.QCMDEXC (IN :PARM1 CHAR (512), IN :PARM2 DEC(15, 5)) LANGUAGE CL NOT DETERMINISTIC NO SQL EXTERNAL NAME QSYS.QCMDEXC PARAMETER STYLE GENERAL", , adExecuteNoRecords
(Fehler kann ignoriert werden, wenn Prozedur schon da)
Mein Command-Objekt:
With cCallCmd
.Name = "CallCmd"
Set .ActiveConnection = cConnect
.CommandText = "{CALL QTEMP.QCMDEXC (?, ?)}"
.CommandType = adCmdText
.Prepared = True
End With
Der Aufruf erfolgt dann analog:
cCallCmd.Execute(,Array(Cmd, Len(Cmd)))
Der 2. Paramter des Execute kann ein Parameter-Array enthalten.
Dieses Verfahren kannst du bestimmt auf dein Programm umsetzen.
-
Vielen Dank für den Tip. Jedoch kann ich mit dem SQL-Statement
von seiner Bedeutung her nicht all zu viel anfangen, weswegen
ich doch lieber weiter auf der Suche nach dem Ursprung der
Fehlermeldung bleibe, um letzten Endes zu wissen, wie das Programm
auch läuft 
Trotzdem vielen Dank nochmals.
-
Hallo Fuerchau,
leider habe ich bis jetzt keine andere Lösung gefunden und bin somit dann
doch fest entschlossen, deinen Code-Ausschnitt gerne zu benutzen. Nur
leider verstehe ich es nicht so ganz.
Ich habe ein rpg Programm in Lib SAGP und es heisst Pseulabrpg hat einen Paramter
der Etwas zurückliefert (also OUT?) Wie müsste das ganze dann aussehen?
Woher kommt denn der letzte cmd Parameter bei deinem Exceute?
Wäre wirklich sehr nett, wenn du da nochmal helfen könntest, da ich sonst
leider verzweifle
Mit freundlichem Gruße, BeWe
-
Also:
Ein CALL mit dem ODBC-Treiber ist nur auf Prozeduren möglich !
Der generierte CALL "{{CALL /qsys.lib/...." funktioniert so wie das Toolkit ihn erstellt, allerdings nur mit dem IBMDA400, da dann der SQL-Weg umgangen wird.
Wenn du also sowohl SQL als auch Programm-Calls verwenden willst, kannst du
a) 2 Verbindungen nutzen: 1 ODBC für SQL und die 2. IBMDA400 für CALL PGM
b) für jedes Programm eine Prozedur erstellen
Für die Prozedurerstellung kannst du das Beispiel oben nehmen, für den Ausgabeparameter ist dann OUT anzugeben.
Was den letzten Parameter des Execute's angeht, so sollte dieser angewendet werden wenn kein RecordSet zurückgegeben wird, was ja bei fast allen SQL-Befehlen ausser Select der Fall ist.
Der Grund ist, dass Execute sonst ein leeres Recordset-Object erstellt das anschließend sowieso wieder verworfen wird.
-
Hallo und wiedermals lieben Dank,
habe das dann alles so befolgt, aber komme nun zu der Fehlermeldung:
"Die Argumente sind vom falschen Typ, liegen außerhalb des Gültig-
keitsbereiches oder sind miteinander unvereinbar"
Das bei folgendem Code:...
On Error Resume Next
as400db.Execute "CREATE PROCEDURE QTEMP.QCMDEXBW (IN :PARM1 CHAR (512), OUT :PARM2 CHAR(1)) LANGUAGE RPG NOT DETERMINISTIC NO SQL EXTERNAL NAME QSYS.QCMDEXC PARAMETER STYLE GENERAL", , adExecuteNoRecords
On Error GoTo 0
'(Fehler kann ignoriert werden, wenn Prozedur schon da)
With as400cmd
Set .ActiveConnection = as400db
.CommandText = "{CALL QTEMP.QCMDEXBW(?)}"
.CommandType = adCmdText
.Prepared = True
End With
cmd = "CALL SAGPLIB.PSEULABRPG(?)"
'as400cmd.Parameters.Append as400cmd.CreateParameter("PARM1", adChar, adParamOutput, 1)
as400cmd.Execute , Array(cmd, Len(cmd))
Ich hoffe mir ist da einfach nur ein grober Schnitzer unterlaufen, oder wieso
kommt es nicht zum gewünschten Ergebnis? Ich wüsste auch nicht, wie
ich dann, bei erfolgreicher Ausführung den Paramter auslesen könnte?
Tut mir wirklich Leid, wie gesagt, bin ich völliger AS400-Neuling
-
Kleine Korrektur...
as400db.Execute "CREATE PROCEDURE QTEMP.QCMDEXBW (IN :PARM1 CHAR (512), IN :PARM2 DEC(15, 5), OUT :PARM3 CHAR(1)) LANGUAGE RPG NOT DETERMINISTIC NO SQL EXTERNAL NAME QSYS.QCMDEXC PARAMETER STYLE GENERAL", , adExecuteNoRecords
With as400cmd
Set .ActiveConnection = as400db
.CommandText = "CALL QTEMP.QCMDEXBW(?,?,?)"
.CommandType = adCmdText
.Prepared = True
End With
cmd = "CALL PGM(SAGPLIB/PSEULABRPG)"
as400cmd.Execute , Array(cmd, Len(cmd), result)
So wird zwar alles richtig aufgerufen, aber wieder bekommt doch das Programm
Pseulabrpg keinen Zeiger für den Rückgabeparameter und stürtzt ab.
Ein Königreich für alle, die mir da jetzt den letzten Denkanstoß, nein besser
gleich die Lösung geben können.
Erneut mit freundlichstem Gruße, BeWe
-
Da hast du ja was gemacht, was du wohl selber nicht verstehst !
Also:
as400db.Execute "CREATE PROCEDURE MyLib.MyPgm (IN :PARM1 CHAR (512), IN :PARM2 DEC(15, 5)) LANGUAGE RPG NOT DETERMINISTIC NO SQL EXTERNAL NAME MyLib.MyPgm PARAMETER STYLE GENERAL", , adExecuteNoRecords
Du solltest dein Programm und die Lib benennen, denn das wird der Name der Prozedur !
Die 2. Angabe . verweist dann tatsächlich auf das Programm !
Die Parameter definierst du auch entsprechend Deinem Programm mit IN/OUT/INOUT, Typ und Länge !
DANN kannst du auch das Programm aufrufen.
PS:
Mein Beispiel war für den Aufruf des Programmes QCMDEXC um Kommandos per SQL durchzuführen.
-
Richtig,
zugegeben, erst hab ich es wirklich nicht verstanden, wie man
ja an dem obrigen Beispiel erkennen kann. Über Nacht kam dann
die Erleuchtung und heute Morgen konnte ich es korrigieren...
as400db.Execute "CREATE PROCEDURE QTEMP.QCMDPSEU10 (OUT :PARM1 CHAR (1)) LANGUAGE RPG NOT DETERMINISTIC NO SQL EXTERNAL NAME SAGPLIB.PSEULABRPG PARAMETER STYLE GENERAL", , adExecuteNoRecords
...ist der richtige Ausdruck.
Allerdings kann man es dann immer noch nicht auslesen!
Man muss dann, vor dem Ausführen des Command.Execute, noch folgendes mit dem Command-Objekt machen.
as400cmd.Parameters(0).Direction = adParamOutput
as400cmd.Parameters(0).Type = adChar
as400cmd.Parameters(0).Size = 1
Dann ist es auch nicht mehr nötig, das Array mit den Parametern zu übergeben,
was so leider nämlich nicht funktioniert hat.
Das ADODB.Command-Objekt wusste komischer weise, dass es einen Parameter hat
nach dieser Ausführung auf das Connection-Objekt Woher? Der Versuch, einen
zweiten Parameter (Index 1) zu initialisieren führte zu einer Fehlermeldung?
Jedenfalls vielen, vielen Dank für die Geduldige Unterstützung und viele Grüße
aus dem sonnigen Sauerland, BeWe
-
Jedes "?" bedeutet einen Parameter!
Bei IN-Parametern kann der SQL-Treiber die korrekte Umsetzung selber durchführen.
Bei OUT/INOUT-Parametern ist eine Beschreibung der Parameter erforderlich, da keine automatische Anpssung möglich ist.
Daher die Beschreibung der Parameter:
as400cmd.Parameters.Append as400cmd.CreateParameter("PARM1", adChar, adParamOutput, 1)
Beim Zugriff auf die Parameter mit Index wird der CommandText an den Treiber (und damit an die AS/400) zur Ermittlung der Anzahl Parameter gesendet.
Wenn dann die Syntax e.g. nicht stimmt, kommt es zu einer Ausnahme.
"?" gelten als sog. Parametermarker und sind bei der wiederholten Ausführung erheblich schneller. Viele Programme arbeiten immer noch mit voll dynamischem SQL (geht ja so schön einfach mit VB), was die AS/400 aber zwingt den SQL immer neu zu analysieren, Zugriffswege zu ermitteln usw.
Definiere ich einen SQL aber mit "?", erfolgt die Analyse nur 1 Mal und die Ausführung (Execute) erfolgt sofort.
Ausserdem ist die Programmierung damit erheblich einfacher, als jedesmal die SQL zusammenzusetzen.
Problematisch ist das nähmlich bei Zeichenketten, die selber ein Hochkomma enthalten. Bei Parametermarkern braucht man sich nicht zu kümmern, beim zusammengsetzten SQL müssen diese aber verdoppelt werden.
Beim internationalen Einsatz ist auch noch Decimalpoint/Decimalcomma entscheidend, was bei "?" keine Rolle spielt.
Wie übergebe ich nun Parameter ?
IN/INOUT-Parameter können entweder vor dem Execute mittels Zugriff erfolgen:
as400cmd!Parm1 = Wert ' wenn der Parameter einen Namen hat
as400cmd(0) = Wert ' über Index
oder im Execute selber als Array im 2.Parameter (daher mein Beispiel).
OUT-Parameter können halt nicht übergeben werden, aber trotzdem kann dies über Execute erfolgen, wenn man eine Mischung mit IN/OUT hat:
as400cmd.Execute(, Array(Inparm1, Inparm2, ,InoutParm4),)
Anmerkung:
Für einen korrekten Namen der Prozedur solltest du nicht QTEMP wählen, da Prozeduren (im Gegensatz zu anderen QTEMP-Objekten) NICHT wieder entfernt werden. Ich habe nur QTEMP gewählt, weil ich ja QCMDEXC aufrufen wollte.
Wenn die Prozedur vorhanden ist, aber geändert werden muss, kannst du per "drop procedure Lib.Name" die Prozedur wieder entfernen (auch von STRSQL auf der AS/400).
Welche Prozeduren vorhanden sind, lässt sich über "select * from procedures" erfragen.
-
Nicht schlecht, nicht schlecht 
genau das wäre meine nächste nervige Frage gewesen ;-).
Allerdings habe ich bei dem ganzen Probieren mehrere
Procedures mit unterschiedlichen Paramterzusammenstellungen
erstellt eine habe ich mit
drop procedure QTEMP/Procname (CHAR)
gelöscht bekommen, aber zwei weitere nicht mehr. Gibt es
dabei so was wie Wildcards?
Delete * from procedures where Procname = "ProcName"
geht leider nicht 
Vielen Dank nochmal für die Tips, habe jetzt schon ein paar
Programme erstellen können bei denen 29 Parameter über-
geben werden und es ist doch noch recht schnell.
Similar Threads
-
By mk in forum NEWSboard Java
Antworten: 8
Letzter Beitrag: 21-04-11, 21:51
-
By timeless in forum IBM i Hauptforum
Antworten: 5
Letzter Beitrag: 11-01-07, 12:04
-
By Stoeberl in forum NEWSboard Programmierung
Antworten: 8
Letzter Beitrag: 10-01-07, 10:58
-
By hh-mi in forum IBM i Hauptforum
Antworten: 5
Letzter Beitrag: 15-11-06, 12:23
-
By Squall in forum IBM i Hauptforum
Antworten: 31
Letzter Beitrag: 28-09-06, 17:53
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- You may not post attachments
- You may not edit your posts
-
Foren-Regeln
|
Erweiterte Foren Suche
Google Foren Suche
Forum & Artikel Update eMail
AS/400 / IBM i
Server Expert Gruppen
Unternehmens IT
|
Kategorien online Artikel
- Big Data, Analytics, BI, MIS
- Cloud, Social Media, Devices
- DMS, Archivierung, Druck
- ERP + Add-ons, Business Software
- Hochverfügbarkeit
- Human Resources, Personal
- IBM Announcements
- IT-Karikaturen
- Leitartikel
- Load`n`go
- Messen, Veranstaltungen
- NEWSolutions Dossiers
- Programmierung
- Security
- Software Development + Change Mgmt.
- Solutions & Provider
- Speicher – Storage
- Strategische Berichte
- Systemmanagement
- Tools, Hot-Tips
Auf dem Laufenden bleiben
|
Bookmarks