我们有一个使用 CL 和 RPG 程序组合编写的存储过程。 当在 iSeries 上本地调用时,一切都很好。 当从外部调用时(例如从 SQL 前端),RPG 程序无法获取它生成的假脱机文件的 hadle,因为假脱机文件出现在不同的(随机?)作业号和用户下。
作业在 QUSRWRK 子系统中以 QUSER 身份运行,但假脱机文件获取连接池中外部建立连接的用户 ID(即 USERA)。
有没有一种方法能够在作业运行时可靠地获取正确的 sppol 文件的句柄(而不是依赖于从该队列中选取最后一个假脱机字段等)。
We have a stored procedure written using a CL and RPG program combination. When called locally on the iSeries all is fine. When called externally (for example from a SQL frontend) the RPG program cannot get a hadle on the spool file it produces because the spool file appears under a different (random?) job number and user.
The jobs run as QUSER in the QUSRWRK subsystem but the spool file gets the user id of which the connection was made externally in the connection pool (i.e USERA).
Is there a way of being able reliably to get a handle on the correct sppol file as the job runs (rather than relying on picking the last spool fiel from that queue etc).
发布评论
评论(5)
如果您正在运行存储过程(在作业 QZDASOINIT 中运行),您将无法通过程序状态数据结构访问假脱机输出。 这些假脱机文件驻留在名为 user/QPRTJOB 的作业中,其中 user 是运行存储过程的“当前用户”。 要访问假脱机文件,请运行 api QSPRILSP 以获取指向假脱机文件的结构。
IBM 信息中心中的行为和 API 都有详细记录。
If you're running a stored procedure (running in job QZDASOINIT), you will no be able to access the spooled output via the program status data structure. Those spooled files reside in a job named, user/QPRTJOB, where user is the "current user" running the stored procedure. To access the spooled files, run api QSPRILSP to obtain a structure that points you to the spooled file.
Both the behavior and API is well documented in IBM's infocenter.
服务器作业(例如,ODBC/JDBC 的数据库服务器实例)在系统用户配置文件下运行。 对于存储过程,系统用户通常是 QUSER。 在作业中创建的对象通常由作业用户拥有。
服务器作业通常代表其他用户执行工作。 当您建立连接时,您告诉服务器作业哪个用户。 (请注意,在其生命周期中,给定的服务器作业可能代表许多不同的用户工作。)
特别是对于假脱机输出,这是一个问题,因为假脱机子系统的存在时间比我们拥有“Web”的时间还要长,而且在我们出现之前有大量用户连接到远程数据库。 从一个用户切换到另一个用户的行为根本不是假脱机子系统构成的一部分,IBM 等供应商也无法确定假脱机文件何时应由特定作业用户或连接用户拥有。 (假脱机并不是数据库连接的主要元素。)
IBM 确实调整了假脱机将输出与用户关联的方式,默认将“切换用户”输出收集在 名为 QPRTJOB 的作业,但它不太适合如何您想要稍后的 RPG 程序来处理输出。
但是,如果您创建一个生成假脱机输出的存储过程,则该过程可以选择谁拥有该输出,从而选择将其保留在同一作业中。 考虑这些可以粘贴到 iSeries Navigator“运行 SQL 脚本”功能中的示例 CALL:
如果将它们作为一组运行,它们将创建显示 CPF9899 消息描述属性的假脱机输出。 如果您事后检查,您应该会看到 QUSER 现在拥有一个名为 QPMSGD 的假脱机文件,并且它驻留在正在处理远程数据库请求的 QZDASOINIT 作业中。 在这种情况下,该作业中的 RPG 程序可以轻松找到“*LAST”假脱机文件。 另外,如果您删除第一个和最后一个 CALL,现在只运行中间的一个,您应该会发现您拥有下一个假脱机文件。
(QUSER 是 IBM 默认值。如果您的系统使用不同的用户配置文件,请将该用户替换为“QUSER”。)
建议:
更改您的 SP,以便在假脱机输出您需要的输出之前发出适当的 OVRPRTF 命令。在作业中捕获并在生成输出后发出 DLTOVR。
您可以使用与此处显示的命令类似的命令来创建测试过程。 尝试不同的 OVRSCOPE() 设置和 FILE(*PRTF) 或专门命名的文件。 另外,在覆盖命令之前和之后创建输出,以查看它们的行为有何不同。
请注意,SP 完成后,服务器作业可能会处理不同的用户(或者稍后可能会在作业中调用不同的 SP),因此您需要确保 DLTOVR 运行。 (这是让它靠近 OVRPRTF 的原因之一。)
A server job (e.g., a database server instance for ODBC/JDBC) runs under a system user profile. For stored procs, the system user will usually be QUSER. Objects created within a job are usually owned by the job user.
Server jobs generally perform work on behalf of other users. You tell the server job which user when you establish a connection. (And note that during its lifetime a given server job might work on behalf of many different users.)
Particularly for spooled output, this is a problem because the spooling subsystem has been around longer than we've had the "Web" and before we had significant numbers of users connecting to remote databases. The behavior of switching around from user to user simply isn't part of the spooling subsystem's makeup, nor can a vendor such as IBM determine when a spooled file should be owned by a particular job user or connection user. (And spooling is not a major element of database connections.)
IBM did adapt how spooling is associated output with users by defaulting "switched users" output to collect in a job named QPRTJOB, but it doesn't quite fit with how you want a later RPG program to handle the output.
However, if you create a stored proc that generates spooled output, the proc can choose who owns the output and thereby choose to keep it within the same job. Consider these example CALLs that can be be pasted into the iSeries Navigator 'Run SQL Scripts' function:
If you run them as a set, they create spooled output showing the attributes of the message description for CPF9899. If you check afterwards, you should see that QUSER now owns a spooled file named QPMSGD and that it resides within the QZDASOINIT job that's handling your remote database requests. A RPG program within that job can easily find the "*LAST" spooled file in that case. Also, if you delete the first and last CALL and now run just the middle one, you should find that you own the next spooled file.
(QUSER is the IBM default. If your system uses a different user profile, substitute that user for "QUSER".)
Recommendation:
Change your SP to issue an appropriate OVRPRTF command before spooling output that you need to capture in the job and to issue DLTOVR after the output is generated.
You might use commands similar to the ones shown here to create a test procedure. Experiment with different OVRSCOPE() settings and with FILE(*PRTF) or with specifically named files. Also, create output before and after the override commands to see how differently they behave.
Stay aware that the server job might handle a different user after your SP finishes (or a different SP might be called later in the job), so you'll want to be sure that DLTOVR runs. (That's one reason to keep it close to the OVRPRTF.)
我需要更多信息,但我会做出一些假设。 如果我假设错误,请澄清。
QUSRWRK 中的 QUSER 行为是正确的。 您现在正在通过 SQL 服务器(或类似服务器)运行。 所有连接都在这些设置下运行。
有几种方法。
1) 假设这一切都在一项作业中运行。 使用“*”作为作业信息应该可以。2
) 另一种选择是使用 RTVJOBA CURUSER(&ME)。当前用户是登录的人。在这种情况下,USER 将不起作用。
I need a bit more information, but I'll make some assumptions. Please clarify if I assumed wrong.
The QUSER in QUSRWRK behavior is correct. You are now running through the SQL server (or similar server). All connections run under these settings.
There are a couple approaches.
1) Assuming that this all runs in one job. Using '*" for the job information should work.
2) The other option is to use RTVJOBA CURUSER(&ME). The current user is the person that is logged in. USER would not work in this case.
如果您可以修改 RPG 程序,则可以从 检索作业信息程序状态数据结构,而文件信息数据结构 具有来自打开反馈区域的假脱机文件编号。 但是,我不确定作业信息是针对 QUSER 作业(不是您需要的)还是针对 USERA 作业(您需要的)。 假脱机文件号足以作为后续 打印 API 调用。
If you can modify the RPG program you can retrieve job information from the Program Status Data Structure while the File Information Data Structure has the spool file number from the open feedback area. However I'm not sure the job information will be for the QUSER job (not what you need) or for the USERA job (what you need). The spool file number could be enough of a handle for subsequent Print API calls.
作业本身知道或可以找出(请参阅前面的答案),因此,如果其他方法都失败,请修改程序以将消息放入提供您所需信息的队列中。 闲暇时读一下。
。
The job itself knows or can find out (see previous answers) so, if all else fails, modify the program to place a message on a queue that provides the information you need. Read it off at your leisure.
.