AS/400 (Application System/400) is a midrange computer system developed by IBM in 1988, designed for businesses requiring high reliability, security, and scalability. It runs on IBM's proprietary OS/400 operating system (later evolved into IBM i) and is known for its integrated database (DB2 for i), object-based architecture, and seamless upward compatibility.
Feature | AS/400 (IBM i) | IBM Mainframes (zSeries) | IBM Power Systems (AIX/Linux) |
---|---|---|---|
OS | OS/400 (IBM i) | z/OS, z/VSE, z/VM | AIX (Unix), Linux |
Architecture | Object-based, integrated DB | Batch-oriented, highly scalable | Unix-based, open-source friendly |
Target Market | Midrange businesses | Large enterprises, financial institutions | Enterprise computing, AI, HPC |
Database | DB2 for i (integrated) | DB2, IMS, others | DB2, Oracle, MySQL |
Security | Built-in security, role-based | Extensive security layers | Unix/Linux-based security models |
User Interface | Green screen (5250), web-enabled | Batch processing, CICS, TSO | GUI, SSH, terminal |
Virtualization | Logical partitioning (LPAR) | PR/SM for LPARs | PowerVM for AIX/Linux |
The IBM AS/400 (now IBM i) is a highly integrated system designed for business computing. Its key components include:
IBM developed the System/36 (S/36) and System/38 (S/38) as midrange computers in the late 1970s and early 1980s. The AS/400 (IBM i) was introduced in 1988 to unify and replace these systems while maintaining backward compatibility.
Feature | System/36 (S/36) | System/38 (S/38) | AS/400 (IBM i) |
---|---|---|---|
Release Year | 1983 | 1979 | 1988 (IBM i continues today) |
Target Audience | Small businesses | Mid-to-large enterprises | Businesses of all sizes |
Operating System | SSP (System Support Program) | CPF (Control Program Facility) | OS/400 → IBM i |
Architecture | 16-bit, simple file system | 48-bit, advanced database & security | 48-bit (initially), later IBM Power |
Database | Flat file-based | Relational-like, integrated DB | DB2 for i (fully relational) |
Security | Basic user profiles | Object-based security model | Enhanced role-based security |
Programming Languages | RPG II, COBOL, OCL | RPG III, COBOL, CL | RPG IV, COBOL, C, Java, SQL, PHP |
User Interface | Green screen (5250 terminals) | Green screen (5250 terminals) | Green screen, Web UI, APIs |
Virtualization | None | None | Logical Partitioning (LPAR), PowerVM |
* Strengths: Simple, cost-effective, and widely adopted in small businesses.
* Weaknesses: Lacked a modern database and security model.
* Strengths: Advanced security, integrated DB, and forward-looking architecture.
* Weaknesses: Expensive and complex compared to S/36.
* Strengths: Scalable, secure, highly reliable, backward-compatible.
* Weaknesses: Perceived as outdated due to its green screen UI, but modernized significantly.
The Licensed Internal Code (LIC) is a low-level firmware-like layer in IBM i (formerly AS/400) that acts as an interface between the hardware and the operating system (OS/400 or IBM i). It is essential for the system’s stability, performance, and security.
Feature | LIC (Licensed Internal Code) | OS/400 (IBM i) |
---|---|---|
Role | Low-level firmware-like layer | Full operating system |
User Interaction | Not directly accessible | Directly used by admins and developers |
Functionality | Manages hardware, security, and virtualization | Provides UI, database, networking, and application support |
Storage Model | Controls Single-Level Storage (SLS) | Uses SLS for file and memory management |
There are several ways to check the OS version of an AS400 system (which is now more commonly referred to as IBM i):
1. Using the DSPPTF
command:
DSPPTF
on the command line and press Enter.2. Using the GO LICPGM
command:
GO LICPGM
on the command line and press Enter.3. Using the DSPSFWRSC
command:
DSPSFWRSC
on the command line and press Enter.4. Checking spool files:
WRKSPLF
command to view your spool files.Important Notes:
DSPPTF 5770999
command.Subsystems are a fundamental concept in IBM i (formerly AS400) that provide a way to manage and control the execution of jobs (programs and processes). Think of them as separate environments within the operating system, each with its own set of resources and rules.
Here's a breakdown of how subsystems work:
1. Subsystem Descriptions:
2. Job Queues:
3. Routing Entries:
4. Classes:
How it all works together:
Benefits of using subsystems:
Examples of common subsystems:
IBM i (formerly AS/400) uses an advanced Single-Level Storage (SLS) model for memory management, making it unique compared to traditional operating systems like Windows, Linux, or Unix. This model simplifies storage access, optimizes performance, and enhances system reliability.
Component | Function |
---|---|
Main Storage (RAM) | Holds active jobs, programs, and system data. |
Disk Storage (DASD - Direct Access Storage Device) | Used for persistent storage and automatic paging. |
Storage Pools (Subsystems) | Divides memory into pools for different workloads. |
Page Fault Manager | Handles paging between RAM and disk. |
Automatic Storage Reclamation | Frees up memory automatically when not in use. |
Feature | IBM i (AS/400) | Windows/Linux/Unix |
---|---|---|
Storage Model | Single-Level Storage (SLS) | Separate RAM and disk management |
Paging Mechanism | Automatic, no swap files | Uses virtual memory and swap files |
Memory Fragmentation | Low, due to object-based model | High, requires defragmentation |
Performance Optimization | Dynamic memory pools | Fixed allocations or manual tuning |
A library in AS/400 (IBM i) is a system-level object that organizes and stores other objects such as programs, files, and data. It functions similarly to a directory or folder in other operating systems but has enhanced security, object-based management, and integrated access control.
Library Type | Purpose |
---|---|
QSYS | System library containing IBM-supplied objects. |
QGPL | General purpose library for shared use. |
QTEMP | Temporary library that exists only for the job duration. |
User Libraries | Custom libraries created by users to store programs and data. |
Product Libraries | Contain third-party or IBM software components. |
Command | Function |
---|---|
CRTLIB | Create a new library. |
WRKLIB | Work with libraries (view/manage). |
DSPLIB | Display library contents. |
DLTLIB | Delete a library. |
CHGLIB | Change library attributes. |
Example :
To create a library called MYLIB
, use :
CRTLIB LIB(MYLIB)
To add MYLIB
to the current session’s library list :
ADDLIBL LIB(MYLIB)
* Efficient Organization – Stores objects logically for easy access.
* Security & Access Control – Provides granular control over who can access or modify objects.
* Performance Optimization – System searches objects based on the Library List (LIBL), improving efficiency.
* Backward Compatibility – Applications remain functional across system upgrades.
Control Language (CL) commands are used in IBM i (AS/400) to manage system operations, files, programs, and user interactions. These commands help automate tasks, manage jobs, control system resources, and handle user interactions.
Command | Function |
---|---|
CRTLIB LIB(LIBNAME) |
Create a new library. |
WRKLIB LIB(LIBNAME) |
Work with libraries (view/manage). |
DSPLIB LIB(LIBNAME) |
Display contents of a library. |
DLTLIB LIB(LIBNAME) |
Delete a library. |
CRTDTAARA DTAARA(DTANAME) TYPE(*CHAR) LEN(10) |
Create a data area. |
WRKOBJ OBJ(*ALL/*ALL) |
Work with objects. |
DSPOBJD OBJ(LIBNAME/*ALL) OBJTYPE(*ALL) |
Display object descriptions. |
Command | Function |
---|---|
CRTPF FILE(LIBNAME/FILENAME) RCDLEN(100) |
Create a physical file. |
CRTLF FILE(LIBNAME/FILENAME) SRCFILE(LIB/SRCFILE) |
Create a logical file. |
DSPPFM FILE(LIBNAME/FILENAME) |
Display records in a physical file. |
WRKF FILE(LIBNAME/FILENAME) |
Work with database files. |
CPYF FROMFILE(FILE1) TOFILE(FILE2) MBROPT(*REPLACE) |
Copy file contents. |
RGZPFM FILE(LIBNAME/FILENAME) |
Reorganize a file to remove deleted records. |
Command | Function |
---|---|
WRKACTJOB |
Work with active jobs. |
WRKJOB JOB(JOBNAME) |
Work with a specific job. |
ENDJOB JOB(JOBNAME) |
End a job. |
SBMJOB CMD(CALL PGM(PGMNAME)) JOB(JOBNAME) |
Submit a job to batch processing. |
CHGJOB JOB(JOBNAME) RUNPTY(30) |
Change job priority. |
WRKUSRJOB USER(USERNAME) |
View jobs for a specific user. |
Command | Function |
---|---|
CALL PGM(PGMNAME) |
Call and execute a program. |
SBMJOB CMD(CALL PGM(PGMNAME)) |
Submit a program to batch execution. |
STRDBG PGM(PGMNAME) |
Start debugging a program. |
ENDDBG |
End debugging. |
RUNQRY QRY(QRYNAME) |
Run a query. |
Command | Function |
---|---|
CRTUSRPRF USRPRF(USERNAME) PASSWORD(PASS123) |
Create a new user profile. |
CHGUSRPRF USRPRF(USERNAME) PASSWORD(NEWPASS) |
Change a user password. |
WRKUSRPRF USRPRF(USERNAME) |
Work with user profiles. |
DSPUSRPRF USRPRF(USERNAME) |
Display user profile details. |
GRTOBJAUT OBJ(LIB/PGMNAME) OBJTYPE(*PGM) USER(USERNAME) AUT(*ALL) |
Grant authority to a user for an object. |
Command | Function |
---|---|
DSPJOBLOG |
Display job logs. |
DSPMSG |
Display system messages. |
SNDMSG MSG('Hello') TOUSR(USERNAME) |
Send a message to a user. |
CHGSYSVAL SYSVAL(QDATE) VALUE('2024-02-05') |
Change a system value. |
WRKSYSVAL |
Work with system values. |
Command | Function |
---|---|
SAVLIB LIB(LIBNAME) DEV(TAP01) |
Save a library to tape. |
RSTLIB LIB(LIBNAME) DEV(TAP01) |
Restore a library from tape. |
SAVOBJ OBJ(OBJNAME) LIB(LIBNAME) DEV(*SAVF) |
Save a specific object. |
RSTOBJ OBJ(OBJNAME) LIB(LIBNAME) DEV(*SAVF) |
Restore a specific object. |
Command | Function |
---|---|
WRKOUTQ |
Work with output queues. |
WRKSPLF |
Work with spooled files. |
DLTSPLF FILE(FILENAME) |
Delete a spooled file. |
SBMJOB
and CALL
are both Control Language (CL) commands used to execute programs, but they work differently in terms of execution method, job processing, and system resource management.
The CALL
command executes a program immediately in the current job (interactive or batch).
Syntax :
CALL PGM(MYPGM) PARM('VALUE1' 'VALUE2')
* Runs synchronously – The program executes immediately and must finish before the next command runs.
* Uses the current job's resources – Runs in the same job as the calling program.
* Tied to the user's session – If the session ends, the program stops.
* Common in interactive jobs – Typically used for menu-driven applications.
The SBMJOB
command submits a job to run in batch mode, allowing it to execute separately from the current session.
Syntax :
SBMJOB CMD(CALL PGM(MYPGM)) JOB(MYBATCHJOB)
* Runs asynchronously – The job runs in the background while the user can continue working.
* Uses a batch subsystem – The submitted job runs in a separate batch job queue.
* Independent execution – Even if the user logs off, the job continues running.
* Good for long-running tasks – Ideal for reports, backups, mass data processing, etc.
Feature | CALL | SBMJOB |
---|---|---|
Execution Mode | Synchronous (waits to finish) | Asynchronous (runs in background) |
Job Type | Runs in the current interactive/batch job | Runs in a separate batch job |
User Interaction | Tied to user session | Runs independently |
Resource Usage | Uses current job’s resources | Uses a batch subsystem |
Best Used For | Immediate program execution | Background processing, long tasks |
Continues If User Logs Off? | No | Yes |
Scenario: A user wants to generate a large report.
In IBM i (formerly AS400), the MONMSG
command is a powerful tool used for monitoring and handling messages within Control Language (CL) programs. Its primary purpose is to allow your programs to respond to specific events or errors that occur during their execution.
Here's a breakdown of why MONMSG
is essential:
1. Error Handling:
MONMSG
allows you to define how your program should react to these errors.2. Event Monitoring:
MONMSG
can also monitor for specific events, such as a file being opened or closed, a certain condition being met, or a message arriving in a message queue.3. Program Control:
MONMSG
strategically, you can control the flow of your program based on the messages it receives.How it works:
MONMSG
monitors for specific messages identified by their message IDs (e.g., CPF0001, MCH1211).MONMSG
can be placed at the beginning of a program (program-level) to monitor messages throughout the program, or it can be placed after a specific command (command-level) to monitor messages from that command only.Example :
PGM /* Program to copy a file */
CPYF FROMFILE(MYLIB/MYFILE1) TOFILE(MYLIB/MYFILE2)
MONMSG MSGID(CPF2812) EXEC(GOTO ERROR) /* File not found */
/* ... more processing ... */
GOTO END
ERROR: /* Error handling routine */
SNDPGMMSG MSG('File not found!') MSGTYPE(*ESCAPE)
/* ... other error handling actions ... */
END: ENDPGM
In this example, the MONMSG
command monitors for message CPF2812, which indicates that the "from" file was not found. If this message is received, the program jumps to the ERROR
label to handle the error.
Error handling is a crucial aspect of writing robust CL programs in IBM i. Here's a breakdown of how you can effectively handle errors:
1. Understanding Messages:
2. Using the MONMSG
command:
MONMSG
command is the primary tool for handling messages in CL programs.3. Setting up MONMSG
:
MONMSG
: Placed at the beginning of your program to monitor messages throughout the entire program.MONMSG
: Placed immediately after a specific command to monitor messages generated by that command.4. Actions in MONMSG
:
GOTO
: Transfers control to a specific label in your program, allowing you to execute error-handling routines.EXEC
: Executes a CL command, such as displaying a message or calling another program.RTVMSG
: Retrieves the message text for a specific message ID.SNDPGMMSG
: Sends a program message to the user or to a message queue.5. Example :
PGM /* Program to copy a file */
CPYF FROMFILE(MYLIB/MYFILE1) TOFILE(MYLIB/MYFILE2)
MONMSG MSGID(CPF2812) EXEC(GOTO ERROR) /* File not found */
/* ... more processing ... */
GOTO END
ERROR: /* Error handling routine */
SNDPGMMSG MSG('File not found!') MSGTYPE(*ESCAPE)
/* ... other error handling actions ... */
END: ENDPGM
In this example :
MONMSG
command monitors for message CPF2812 (file not found) after the CPYF
command.ERROR
label.ERROR
routine sends an escape message to the user and can perform other error handling actions.6. Best Practices:
By effectively using MONMSG
and following best practices, you can create robust and reliable CL programs that can handle errors gracefully and ensure the smooth operation of your IBM i system.
Passing parameters between CL (Control Language) and RPG (Report Program Generator) programs in IBM i is a common requirement when you need to integrate these two languages. Here's how you can achieve this:
1. Defining Parameters in RPG:
Example :
**FREE
ctl-opt dftactgrp(*no) actgrp(*caller);
dcl-s Name char(20) ;
dcl-s Age zoned(3) ;
dcl-s Salary packed(7:2);
dcl-pi *n
Name like(Name) ;
Age like(Age) ;
Salary like(Salary) ;
end-pi;
// ... rest of your RPG program logic ...
In this example :
Name
is a character parameter of length 20.Age
is a zoned numeric parameter of length 3.Salary
is a packed numeric parameter with 7 digits and 2 decimal places.2. Calling the RPG Program from CL:
CALL
command to invoke the RPG program.PARM
parameter of the CALL
command.PARM
list must match the order of the parameters defined in the RPG program.Example :
PGM /* CL program to call the RPG program */
DCL VAR(&NAME) TYPE(*CHAR) LEN(20) VALUE('John Doe')
DCL VAR(&AGE) TYPE(*CHAR) LEN(3) VALUE('30')
DCL VAR(&SALARY) TYPE(*CHAR) LEN(9) VALUE('000500.00')
CALL MYLIB/MYRPGPGM PARM(&NAME &AGE &SALARY)
ENDPGM
In this example :
&NAME
, &AGE
, and &SALARY
and assign values to them.MYLIB/MYRPGPGM
and pass these variables as parameters using the PARM
parameter.Important Considerations:
%BIN
or %DEC
built-in functions in CL to ensure that the values are passed correctly.PARM
list of the CALL
command.Best Practices:
Both SNDPGMMSG
and SNDUSRMSG
are CL commands used to send messages in IBM i, but they serve different purposes and have distinct characteristics:
SNDPGMMSG (Send Program Message)
*STATUS
*ESCAPE
*NOTIFY
*COMPL
(Completion)*DIAG
(Diagnostic)*EXT
)SNDUSRMSG (Send User Message)
*INQ
(Inquiry)*INFO
(Informational)*COMPL
(Completion)*DIAG
(Diagnostic)Key Differences Summarized:
Feature | SNDPGMMSG | SNDUSRMSG |
---|---|---|
Primary Use | Intra-program/call stack communication | User/operator communication |
Message Types | Wider range (status, escape, notify, etc.) | Primarily inquiry and informational |
Destination | Job's external queue, specific queue, caller's queue | User's queue, operator's queue, display station |
In essence:
SNDPGMMSG
is for internal program communication and error handling.SNDUSRMSG
is for interacting with users or the system operator.Example:
If you want to display a message to the user asking for confirmation, you would use SNDUSRMSG
with MSGTYPE(*INQ)
. If you want to send a message to the calling program indicating that a subroutine has completed successfully, you would use SNDPGMMSG
with MSGTYPE(*COMPL)
.
Job Descriptions (JOBDs) in IBM i (formerly AS400) are essential objects that define the characteristics and environment for running jobs (programs and processes). They act as templates that specify how a job should behave when it's submitted to the system.
Here's how you can create a JOBD:
1. Using the CRTJOBD command:
CRTJOBD
command.Syntax:
CRTJOBD JOBD(library/jobd-name) parameters
library
: The library where you want to create the JOBD.jobd-name
: The name you want to give to the JOBD.parameters
: Various parameters that define the JOBD's attributes.2. Key Parameters:
Here are some of the most important parameters you'll likely use when creating a JOBD:
3. Example:
CRTJOBD JOBD(MYLIB/MYJOBD) JOBQ(MYLIB/MYJOBQ) JOBPTY(5) OUTPTY(5) INLLIBL(MYLIB, QSYS) TEXT('Job description for batch processing')
This command creates a JOBD named MYJOBD
in library MYLIB
. Jobs using this JOBD will be submitted to the MYJOBQ
job queue, have a job priority of 5, an output priority of 5, an initial library list of MYLIB
and QSYS
, and a description of "Job description for batch processing."
4. Using WRKJOBD:
WRKJOBD
command to work with job descriptions.WRKJOBD
display.5. Important Considerations:
By creating and configuring JOBDs effectively, you can:
Let's break down the use of OVRDBF
, OPNQRYF
, and DSPRCDLCK
in IBM i (formerly AS400), explaining their purposes and how they're typically employed.
OVRDBF (Override with Database File) :
OVRDBF
is used to temporarily change the attributes of a physical file used by a program. This allows you to redirect a program to use a different file, a different member within a file, or modify certain file access characteristics.OVRDBF
to set the correct file.SHARE(*YES)
, it allows other programs (like RPG) to use the same open data path, which is often necessary when working with OPNQRYF
.FILE
: The original file name to be overridden.TOFILE
: The file to be used instead of the original.MBR
: The member to be used (if overriding with a different member).POSITION
: Allows positioning the file pointer at a specific record (e.g., *START
, *END
, *RRN nnn
).SHARE
: Specifies whether the open data path can be shared with other programs.OVRDBF FILE(CUSTFILE) TOFILE(TESTLIB/CUSTFILE) MBR(TESTDATA)
CUSTFILE
to use the CUSTFILE
in TESTLIB
and specifically the TESTDATA
member.
OPNQRYF (Open Query File) :
OPNQRYF
is used to create a dynamic view or subset of data from one or more physical files. It's a way to perform selection, joining, sorting, and calculations on data before it's accessed by a program.FILE
: The name of the file(s) to be used.QRYSLT
: The selection criteria to filter records (e.g., WHERE CUSTNO = 12345
).JOIN
: Specifies how to join multiple files.SORT
: Specifies the fields to sort by.OPNID
: An identifier for the open query file, used when sharing access paths.OPNQRYF FILE(CUSTFILE ORDERFILE) QRYSLT('CUSTNO = 12345') JOIN(CUSTNO) SORT(ORDERDATE) OPNID(MYQUERY)
CUSTFILE
and ORDERFILE
based on CUSTNO
, selects records where CUSTNO
is 12345, sorts the results by ORDERDATE
, and assigns the identifier MYQUERY
.OPNQRYF
is often used in conjunction with OVRDBF
with SHARE(*YES)
to make the resulting data available to RPG or other programs.
DSPRCDLCK (Display Record Locks) :
DSPRCDLCK
is used to display the record locks held by jobs on a specific file. This is crucial for understanding and resolving lock contention issues that can prevent programs from accessing data.DSPRCDLCK
helps identify which job holds the lock.FILE
: The file for which to display record locks.JOB
: Optionally specify a specific job to see locks held by that job.DSPRCDLCK FILE(CUSTFILE)
CUSTFILE
.In summary:
OVRDBF
is for overriding file attributes, often used for testing, data manipulation, and dynamic file selection.OPNQRYF
is for creating dynamic views of data, allowing selection, joining, sorting, and calculations.DSPRCDLCK
is for displaying record locks, used for troubleshooting and performance analysis.These commands are essential tools for managing and working with data in IBM i environments, enabling you to control file access, manipulate data effectively, and diagnose data contention problems.
Debugging CL programs in AS400 (IBM i) involves a combination of techniques and tools. Here's a breakdown of the process:
1. Preparation:
DBGVIEW(*SOURCE)
or DBGVIEW(*ALL)
parameter on the CRTCLPGM
or CRTBNDCL
command.2. Starting the Debugger:
STRDBG
command to start the debugger. Specify the program you want to debug:STRDBG PGM(library/program-name)
OPMSRC(*YES)
on the STRDBG
command.UPDPROD
parameter controls whether you can make changes to production files during debugging. It's generally recommended to keep this set to *NO
to avoid unintentional modifications to live data.3. Debugging Commands:
Once the debugger starts, you'll be presented with a display showing your CL program's source code. You can use various debug commands to control the debugging session:
BREAK
: Set breakpoints at specific lines in your code to pause execution.CLEAR
: Remove breakpoints.F6 (Add/Clear Breakpoint)
: Use this function key to toggle breakpoints on the displayed source code.STEP
or F10
: Execute the next statement.STEP INTO
or F22
: Step into a called program or subroutine.EVAL
: Display or change the value of a variable.ATTR
: Display the attributes (type, length) of a variable.DISPLAY
: Display a different source module.FIND
: Search for a string or line number in the source code.UP
, DOWN
, LEFT
, RIGHT
: Scroll through the source code.TOP
, BOTTOM
: Go to the beginning or end of the source code.HELP
: Display help information about debug commands.SET
: Change debugging options.WATCH
: Monitor the value of a variable or expression.4. Debugging Process:
STEP
, STEP INTO
) to execute your CL program line by line. This allows you to observe the program's flow and identify any logical errors.EVAL
command to examine the values of variables at different points in your program. This helps you understand how data is being processed and identify any incorrect values.EVAL
to evaluate expressions and see the results. This can be useful for debugging complex logic.5. Ending the Debugger:
ENDDBG
command to end the debugging session.Tips for Effective Debugging:
Both RTVJOBA
and RTVMSG
are CL commands in IBM i (formerly AS400) used to retrieve information, but they target different types of information:
1. RTVJOBA (Retrieve Job Attributes)
RTVJOBA
is used to retrieve various attributes of a job currently running on the system. This information can then be stored in CL variables and used to control the flow or behavior of your CL program.JOB
: Specifies the job for which to retrieve attributes (defaults to the current job).USER
: Specifies the user of the job.NBR
: Specifies the job number.TYPE
: Specifies the type of job (e.g., *INT
for interactive, *BAT
for batch).STATUS
: Specifies the status of the job (e.g., *ACTIVE
, *JOBQ
, *OUTQ
).OUTQ
: Specifies the output queue.INLLIBL
: Specifies the initial library list.CURLIB
: Specifies the current library.RTGDTA
: Specifies the routing data.RTVJOBA USER(&USER) TYPE(&JOBTYPE)
IF (&JOBTYPE *EQ '*INT') THEN(DO)
/* Perform interactive processing */
ENDDO
ELSE(DO)
/* Perform batch processing */
ENDDO
2. RTVMSG (Retrieve Message)
RTVMSG
is used to retrieve the text of a message from a message file. This allows you to dynamically display messages to users or use message text in your programs.SNDUSRMSG
.MSGID
: Specifies the message ID of the message to retrieve.MSGF
: Specifies the message file containing the message.MSG
: Specifies the CL variable where the message text will be stored.MSGDTA
: Specifies the message data to be substituted into the message text.RTVMSG MSGID(CPF2812) MSGF(QCPFMSG) MSG(&MSGTEXT)
SNDPGMMSG MSG(&MSGTEXT) MSGTYPE(*ESCAPE)
QCPFMSG
message file and stores it in the &MSGTEXT
variable. It then sends an escape message containing this text.Key Differences Summarized :
Feature | RTVJOBA | RTVMSG |
---|---|---|
Purpose | Retrieve job attributes | Retrieve message text |
Target | Job characteristics | Message from a message file |
Use Cases | Job control, user information, status checks | Displaying messages, error handling, internationalization |
In essence:
RTVJOBA
provides information about a job.RTVMSG
provides information from a message file.Both commands are valuable tools in CL programming, enabling you to create more dynamic and responsive programs by accessing job attributes and retrieving message text.
RPG (Report Program Generator) has evolved significantly since its inception, leading to different versions and programming styles. Here's a breakdown of the main types of RPG programming you might encounter:
1. Historical RPG Versions:
2. Modern RPG (RPG IV/ILE RPG):
3. RPG Programming Styles:
Within RPG IV, you'll find two distinct coding styles:
Key Differences Summarized:
Feature | RPG II/III | RPG IV/ILE RPG |
---|---|---|
Syntax | Column-oriented | Free-form (and column-oriented for compatibility) |
Structure | Less structured | More structured, with support for modern constructs |
Integration | Limited | Integrated with other ILE languages |
Features | Basic report generation and data manipulation | Extensive features for modern application development |
Which type should you use?
Important Notes:
By understanding the different types of RPG programming, you can choose the most appropriate approach for your development needs and effectively work with RPG code in various IBM i environments.
You're asking about the evolution of RPG, and it's a good question because the distinctions can be a bit confusing! Here's a breakdown of RPG III, RPG IV, and RPG Free Format:
RPG III
IF-THEN-ELSE
and DO
loops), subroutines, and better data handling. This made RPG more powerful and flexible.RPG IV
RPG Free Format
Here's a table to summarize:
Feature | RPG III | RPG IV | RPG Free Format |
---|---|---|---|
Version | Older version | Current version | Coding style within RPG IV |
Syntax | Column-oriented | Can be column-oriented or free-form | Free-form only |
ILE | No | Yes | Yes (because it's RPG IV) |
Use for new development | No | Yes | Yes (recommended style) |
%SCAN
, %CHECK
, and %SUBST
are built-in functions (BIFs) in RPG IV (ILE RPG) that provide powerful string manipulation capabilities. Let's explore each one:
%SCAN (Scan for Substring) :
%SCAN
searches for the first occurrence of a substring within a string. It returns the starting position of the substring if found, or 0 if it's not found.%SCAN(substring : string : start)
substring
: The substring you're looking for.string
: The string you're searching within.start
: (Optional) The starting position for the search. If omitted, the search starts at the beginning of the string.DCL-S String VARCHAR(50) INZ('This is a test string.');
DCL-S Substring VARCHAR(10) INZ('test');
DCL-I Position INT(10);
Position = %SCAN(Substring : String); // Position will be 11
IF Position > 0;
// Substring found at position 'Position'
DSPLY ('Substring found at position ' + %CHAR(Position));
ELSE;
// Substring not found
DSPLY ('Substring not found.');
ENDIF;
Position = %SCAN('is' : String : 4); // Position will be 6 (finds the second "is")
%CHECK (Check Characters) :
%CHECK
verifies if a string contains only characters from a specified set. It returns the position of the first character that is not in the set, or 0 if all characters are in the set. %CHECKR
(Check Reverse) does the opposite, finding the first character from the right that is not in the set.%CHECK(characters : string)
or %CHECKR(characters : string)
characters
: The set of valid characters.string
: The string to be checked.DCL-S String VARCHAR(20) INZ('ABC123XYZ');
DCL-S ValidChars VARCHAR(10) INZ('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
DCL-I InvalidPos INT(10);
InvalidPos = %CHECK(ValidChars : String); // InvalidPos will be 4 (the '1')
IF InvalidPos > 0;
DSPLY ('Invalid character found at position ' + %CHAR(InvalidPos));
ELSE;
DSPLY ('All characters are valid.');
ENDIF;
InvalidPos = %CHECKR(ValidChars : String); // InvalidPos will be 7 (the '1')
%SUBST (Substring) :
%SUBST
extracts a portion of a string.%SUBST(string : start : length)
string
: The string from which to extract the substring.start
: The starting position of the substring.length
: The length of the substring to extract. If omitted, it extracts to the end of the string.DCL-S String VARCHAR(30) INZ('This is a test string.');
DCL-S Substring VARCHAR(10);
Substring = %SUBST(String : 9 : 4); // Substring will be 'is a'
Substring = %SUBST(String : 12); // Substring will be 'test string.' (from position 12 to end)
Key Differences and Use Cases :
These BIFs are frequently used in RPG programs for tasks like :
Handling dates and times in RPGLE involves using specific data types, built-in functions (BIFs), and understanding the various formats available. Here's a comprehensive overview:
1. Date and Time Data Types:
D
data type. Stores a date in a specific format (e.g., YYYY-MM-DD, MM/DD/YY).T
data type. Stores a time in a specific format (e.g., HH.MM.SS, HH:MM:SS).Z
data type. Stores both date and time.
2. Defining Date/Time Variables :
DCL-S MyDate D INZ(2024-03-15); // Initialized to March 15, 2024
DCL-S MyTime T INZ(14.30.00); // Initialized to 2:30 PM
DCL-S MyTimestamp Z INZ(2024-03-15-14.30.00); // Date and Time
3. Date/Time Formats:
%date(*YMD)
converts a date to YYYYMMDD format.
4. Built-in Functions (BIFs):
5. Date/Time Arithmetic:
You can perform arithmetic operations on dates and times :
MyDate = MyDate + %DAYS(7); // Add 7 days
MyDate = MyDate - %MONTHS(1); // Subtract 1 month
MyTimestamp = MyTimestamp + %MINUTES(30); // Add 30 minutes
6. Converting Between Formats :
// Convert date to character in a specific format
MyCharDate = %CHAR(MyDate : *MDY); // MyCharDate will be in MM/DD/YY format
// Convert character to date
MyDate = %DATE('12/25/2024' : *MDY);
// Get the current date in YYYYMMDD format
CurrentDate = %CHAR(%DATE() : *YMD);
7. Working with Timestamps :
Timestamps are particularly useful for tracking events and recording when something occurred.
// Get the current timestamp
Now = %TIMESTAMP();
8. Handling Date/Time Errors:
Example :
DCL-S OrderDate D INZ(2024-03-01);
DCL-S ShipDate D;
DCL-S DaysToShip INT(10);
DCL-C DueDate D INZ(2024-12-31); // Example Due Date
ShipDate = OrderDate + %DAYS(10); // 10 days after order
DaysToShip = %DIFF(ShipDate : OrderDate : *D); // Calculate days between dates
IF ShipDate > DueDate;
DSPLY ('Order is late!');
ENDIF;
DSPLY ('Order Date: ' + %CHAR(OrderDate : *MDY));
DSPLY ('Ship Date: ' + %CHAR(ShipDate : *MDY));
By understanding these concepts and using the appropriate BIFs, you can effectively handle date and time operations in your RPGLE programs. Remember to pay close attention to data types and formats to avoid errors.
Data structures in RPG (specifically ILE RPG or RPG IV) are powerful tools for grouping related data items together. They provide a way to organize data, improve code readability, and simplify data manipulation. Here's a comprehensive guide to using data structures in RPG:
1. Defining Data Structures :
You define a data structure using the DS
keyword in the Definition specifications (D specs).
Dcl-s MyDataDS Ds; // Basic data structure
2. Subfields :
Within a data structure, you define individual data items called subfields. You specify the name, data type, and length of each subfield.
Dcl-s MyDataDS Ds;
Dcl-s Name Char(20);
Dcl-s Age Int(3);
Dcl-s Salary Packed(7:2);
3. Qualified Data Structures :
For better code organization and to avoid naming conflicts, it's highly recommended to use qualified data structures. This means you access subfields using the data structure name as a qualifier.
Dcl-s MyDataDS Ds Qualified; // Note the Qualified keyword
MyDataDS.Name = 'John Doe';
MyDataDS.Age = 30;
MyDataDS.Salary = 50000.00;
4. Like-named Subfields :
You can define subfields based on the definition of existing fields using the LIKE
keyword. This helps maintain consistency and reduces redundancy.
Dcl-s CustomerName Char(20); // Existing field
Dcl-s CustInfoDS Ds Qualified;
Dcl-s Name Like(CustomerName); // Same type and length as CustomerName
Dcl-s CustNo Int(10);
5. Data Structure Types :
EXTRCD
(Extract Record) or INZ(*LIKEFILE)
keywords.EXTNAME
keyword.
6. Using Data Structures : You access subfields of a qualified data structure using the dot notation: DataStructureName.SubfieldName
.
Dsply (MyDataDS.Name);
If MyDataDS.Age >= 18;
// ...
Endif;
7. Initializing Data Structures:
* INZ: You can initialize subfields when defining the data structure.
Dcl-s ProductDS Ds Qualified Inz;
Dcl-s ProdCode Char(10) Inz('ABC-123');
Dcl-s Price Packed(9:2) Inz(0);?
* Clear: You can clear a data structure or its subfields using the CLEAR
operation.
Clear MyDataDS; // Clears all subfields
Clear MyDataDS.Name; // Clears only the Name subfield
8. Data Structure Arrays:
You can define arrays of data structures, which is very useful for working with lists of related data.
Dcl-s EmployeeDS Ds Qualified Dim(100); // Array of 100 Employee data structures
EmployeeDS(1).Name = 'First Employee';
EmployeeDS(2).Name = 'Second Employee';
// ...
9. Examples :
Dcl-f CustomerFile E K Disk Prefix('Cust_'); // Prefix for record format
Dcl-s CustRec Ds Qualified Inz(*LikeRec(CustomerFile)); // Program-described DS
Read CustomerFile;
If %eof(CustomerFile);
// ...
Else;
Dsply (CustRec.CustName); // Accessing data from the file using the DS
Endif;
// In the calling program
Dcl-s MyCustInfo Like(CustInfoDS);
Call MySubroutine Parm(MyCustInfo);
// In the called subroutine
Dcl-s MySubroutine Pr ExtProc('MYFUNC');
Dcl-s CustData Like(CustInfoDS); // Receiving the DS as a parameter
Benefits of using Data Structures :
SQL on AS400 (now IBM i) is a powerful way to interact with your data. It's deeply integrated into the system and offers a lot of flexibility. Here's how it works:
1. DB2 for i :
2. Accessing Data :
SELECT
: Retrieve dataINSERT
: Add new dataUPDATE
: Modify existing dataDELETE
: Remove dataCREATE
: Define tables and other database objectsDROP
: Delete tables and other database objects3. Running SQL :
You can run SQL in several ways on IBM i:
4. Key Features :
WHERE
clause for filtering dataJOIN
operations for combining data from multiple tablesGROUP BY
and aggregate functions for summarizing dataORDER BY
for sorting data5. Working with AS400 Objects :
You're asking about two fundamental ways of defining and working with data on IBM i (formerly AS400). Here's a breakdown of the key differences between DDS and SQL tables:
DDS (Data Description Specifications) :
SQL Tables :
Key Differences Summarized :
Feature | DDS | SQL Tables |
---|---|---|
Approach | Traditional, file-based | Modern, table-based |
Data Validation | Read time | Write time |
Data Access | Record-oriented | Set-oriented |
Functionality | More limited | Rich and extensive |
Standardization | IBM i specific | Industry standard |
Which to use?
Important Considerations:
You create an SQL index in DB2 for i (on IBM i) using the CREATE INDEX
statement. Here's a breakdown of the syntax and options:
Basic Syntax :
CREATE INDEX index-name
ON table-name (column1, column2, ...);
index-name
: The name you want to give to your index. It's good practice to use a naming convention that makes it clear what the index is for.table-name
: The name of the table on which you're creating the index.column1, column2, ...
: The columns that you want to include in the index. You can include one or more columns. The order of the columns is important, as it affects how the index is used.Example :
CREATE INDEX CustNameIdx
ON CUSTOMERS (LastName, FirstName);
This creates an index named CustNameIdx
on the CUSTOMERS
table, using the LastName
and FirstName
columns. Queries that filter by LastName
and then FirstName
will be able to use this index efficiently.
Key Options and Considerations:
CREATE INDEX OrderDateIdx
ON ORDERS (OrderDate DESC); -- Index in descending order of OrderDate?
* UNIQUE : You can create a unique index, which enforces that the combination of values in the indexed columns is unique across all rows in the table. This is often used for primary keys or other unique constraints.
CREATE UNIQUE INDEX CustNoIdx
ON CUSTOMERS (CustomerID);?
Partitioned Tables: If your table is partitioned, you might need to include partitioning columns in the index or specify how the index is partitioned.
Expression-based Indexes: You can create indexes on expressions involving columns, not just on the columns themselves. This can be useful for optimizing queries that filter or sort by calculated values.
CREATE INDEX UpperNameIdx
ON CUSTOMERS (UPPER(LastName));
Index Type: While DB2 for i typically uses B-tree indexes, there are other index types (like Encoded Vector Indexes) that might be appropriate for specific workloads or data characteristics. The default is usually a B-tree index.
Journaling: Indexes can be journaled, which is important for recovery in case of system failures. The journaling attributes of an index are often inherited from the table.
File vs. Index: It's important to distinguish between a file (which stores the actual data) and an index (which is a separate structure that helps speed up data access). An index is like the index in a book; it doesn't contain the data itself, but it tells you where to find it.
Best Practices:
WHERE
clauses, JOIN
conditions, ORDER BY
clauses, or GROUP BY
clauses.Both FETCH FIRST 1 ROWS ONLY
and LIMIT 1
serve the same basic purpose: restricting the result set of a query to a single row. However, there are subtle differences, primarily related to SQL standards and database system support.
FETCH FIRST 1 ROWS ONLY
FETCH FIRST
is often the preferred choice.FETCH FIRST
to retrieve the first n rows (e.g., FETCH FIRST 10 ROWS ONLY
). It's more flexible in this regard. You can also include an OFFSET
clause to skip a certain number of rows before fetching the first n.LIMIT 1
LIMIT
clause is not part of the SQL standard. It's syntax that originated in PostgreSQL and has been adopted by some other database systems (like MySQL).LIMIT
, your SQL might not work on all database platforms.LIMIT 1
is often a bit shorter and easier to write than FETCH FIRST 1 ROWS ONLY
.Key Differences Summarized:
Feature | FETCH FIRST 1 ROWS ONLY | LIMIT 1 |
---|---|---|
SQL Standard | Standard (SQL:2008+) | Non-standard |
Portability | More portable | Less portable |
Expressiveness | Supports fetching multiple rows (FETCH FIRST n), OFFSET | Typically only for single row (or a small, fixed number) |
Syntax | FETCH FIRST n ROWS ONLY [OFFSET m] |
LIMIT n |
Which to use?
FETCH FIRST 1 ROWS ONLY
. This is the most important consideration.LIMIT 1
is slightly simpler.FETCH FIRST
is the only option.Example:
Both of these queries will return the first row from the CUSTOMERS
table :
SELECT * FROM CUSTOMERS FETCH FIRST 1 ROWS ONLY;
SELECT * FROM CUSTOMERS LIMIT 1;
However, if you wanted the first 10 customers, you'd have to use FETCH FIRST
:
SELECT * FROM CUSTOMERS FETCH FIRST 10 ROWS ONLY;
You can't do this with LIMIT
in a standard way. Some databases do have a LIMIT n OFFSET m
syntax, but it's not standard.
In short: For most cases, especially when portability is a factor, FETCH FIRST 1 ROWS ONLY
is the better and more standard choice. LIMIT 1
is acceptable for quick, non-portable queries when you're absolutely sure you only want one row.
Embedded SQL in RPG (specifically ILE RPG) allows you to seamlessly integrate SQL statements directly within your RPG programs. This enables your programs to interact with the database for tasks like retrieving, inserting, updating, and deleting data. Here's a comprehensive guide:
1. Setting up your RPG program:
EXEC SQL
preprocessor.**FREE // For free-form RPG
CTL-OPT BNDDIR('QC2LE'); // Bind directory for SQL services
/COPY QSYSINC/SQLC // Include SQL definitions (important!)?
2. Embedding SQL Statements :
You embed SQL statements within your RPG code using the EXEC SQL
keywords .
EXEC SQL SELECT * FROM CUSTOMERS;
EXEC SQL INSERT INTO ORDERS (CustNo, OrderDate) VALUES (:CustNo, :OrderDate);
* Host Variables : To pass data between your RPG program and the SQL statements, you use host variables. These are RPG variables preceded by a colon (:
) in the SQL statement. They act as placeholders for data.
DCL-S CustNo INT(10);
DCL-S CustName CHAR(20);
DCL-S OrderDate D;
EXEC SQL SELECT CustName INTO :CustName FROM CUSTOMERS WHERE CustNo = :CustNo;
3. Handling SQL Results:
INTO
clause in a SELECT
statement specifies the host variables where the retrieved data will be stored.DCL-S CustName CHAR(20);
DCL-S CustNameInd INT(5); // Indicator variable
EXEC SQL SELECT CustName INTO :CustName :CustNameInd FROM CUSTOMERS WHERE CustNo = :CustNo;
IF CustNameInd < 0;
// CustName is null
ELSE;
// CustName has a value
ENDIF;?
* SQLCA (SQL Communication Area): The SQLCA is a structure that contains information about the execution of SQL statements, including error codes. It's essential for error handling.
DCL-S SQLCA SQLCA; // Include the SQLCA
EXEC SQL SELECT * FROM CUSTOMERS;
IF SQLCA.SQLCODE <> 0;
// Handle the error (SQLCA.SQLCODE contains the error code)
Dsply ('SQL Error: ' + %char(SQLCA.SQLCODE));
ENDIF;
4. Working with Multiple Rows (Cursors):
If your SELECT
statement can return multiple rows, you need to use a cursor.
// Declare the cursor
EXEC SQL DECLARE CustCursor CURSOR FOR SELECT * FROM CUSTOMERS;
// Open the cursor
EXEC SQL OPEN CustCursor;
// Fetch rows from the cursor in a loop
DOWHILE SQLCA.SQLCODE = 0;
EXEC SQL FETCH CustCursor INTO :CustNo, :CustName;
IF SQLCA.SQLCODE = 0; // Check after each fetch
// Process the retrieved data
Dsply (CustName);
ENDIF;
ENDDO;
// Close the cursor
EXEC SQL CLOSE CustCursor;
5. Dynamic SQL:
For more flexibility, you can use dynamic SQL, where the SQL statements are built at runtime.
DCL-S SqlStmt VARCHAR(200);
SqlStmt = 'SELECT * FROM ' + TableName; // Build the SQL statement
EXEC SQL PREPARE MyStmt FROM :SqlStmt;
EXEC SQL EXECUTE MyStmt;
6. Error Handling:
Always check the SQLCA.SQLCODE
after each SQL statement to handle potential errors.
7. Examples:
EXEC SQL INSERT INTO ORDERS (CustNo, OrderDate, OrderAmt) VALUES (:CustNo, :OrderDate, :OrderAmt);
IF SQLCA.SQLCODE <> 0;
// Handle insert error
ENDIF;
EXEC SQL UPDATE CUSTOMERS SET CustName = :NewName WHERE CustNo = :CustNo;
IF SQLCA.SQLCODE <> 0;
// Handle update error
ENDIF;
Key Considerations :
EXEC SQL
statements are processed by a preprocessor before the RPG compiler runs.Embedded SQL is a crucial technique for integrating database access into your RPG programs. By mastering its use, you can create powerful applications that leverage the full capabilities of DB2 for i.
Triggers in DB2 are a powerful mechanism that allows you to automatically execute a set of SQL statements when a specific event occurs on a table. Think of them as event-driven actions that help you enforce business rules, maintain data integrity, and automate tasks.
Here's a breakdown of how triggers work and how to implement them in DB2:
What are Triggers?
Types of Triggers:
DB2 supports different types of triggers based on when they are activated:
Implementing Triggers in DB2:
You create triggers using the CREATE TRIGGER
statement. Here's the basic syntax :
CREATE TRIGGER trigger-name
{BEFORE | AFTER | INSTEAD OF} {INSERT | UPDATE | DELETE}
ON table-name
[REFERENCING {OLD ROW AS old-row-name} {NEW ROW AS new-row-name}]
[FOR EACH {ROW | STATEMENT}]
trigger-body
Let's break down the key parts :
trigger-name
: The name you give to your trigger.BEFORE | AFTER | INSTEAD OF
: Specifies when the trigger executes.INSERT | UPDATE | DELETE
: The event that activates the trigger.table-name
: The table on which the trigger is defined.REFERENCING
: Allows you to refer to the old and new values of the row being modified (useful for BEFORE
and AFTER
triggers).FOR EACH {ROW | STATEMENT}
:
ROW
: The trigger executes for each row affected by the triggering event.STATEMENT
: The trigger executes once for the entire SQL statement, even if it affects multiple rows.trigger-body
: The SQL code that will be executed when the trigger is activated.Example:
Let's say you want to ensure that the OrderDate
in your ORDERS
table is never in the future. You can create a BEFORE
trigger like this :
CREATE TRIGGER CheckOrderDate
BEFORE INSERT ON ORDERS
REFERENCING NEW ROW AS newOrder
FOR EACH ROW
BEGIN
IF newOrder.OrderDate > CURRENT DATE THEN
SIGNAL SQLSTATE '70001' SET MESSAGE_TEXT = 'Order date cannot be in the future.';
END IF;
END;
This trigger checks the OrderDate
before a new row is inserted. If it's in the future, the trigger raises an error, preventing the insertion.
You're asking about two fundamental types of joins in SQL, and understanding the difference is crucial for retrieving the correct data from your database. Here's a breakdown of LEFT JOIN and INNER JOIN in AS400 SQL (DB2 for i):
INNER JOIN
Customers
and Orders
. An INNER JOIN on CustomerID
would only return customers who have placed orders, and only those orders placed by customers in the Customers
table.SELECT c.CustomerID, c.Name, o.OrderID
FROM Customers c
INNER JOIN Orders o ON c.CustomerID = o.CustomerID;?
LEFT JOIN
FROM
clause), and the matching rows from the right table.NULL
values in the result.Customers
and Orders
tables, a LEFT JOIN would return all customers, even those who haven't placed any orders. For customers without orders, the OrderID
column would be NULL
.SELECT c.CustomerID, c.Name, o.OrderID
FROM Customers c
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID;?
Key Differences Summarized :
Feature | INNER JOIN | LEFT JOIN |
---|---|---|
Rows Returned | Only matching rows from both tables | All rows from the left table, matching rows from the right table (or NULLs if no match) |
Use Case | When you need data only when it exists in both tables | When you need all data from one table, and matching data from another table if available |
User profiles are fundamental to security on AS400 (now IBM i). They define who can access the system and what they can do. Here's a breakdown of how to create and manage them:
1. Creating User Profiles
CRTUSRPRF Command: The primary way to create a user profile is with the CRTUSRPRF
command. You'll need security administrator (*SECADM) or security officer (*SECOFR) special authority to do this.
CRTUSRPRF USRPRF(username) PASSWORD(password) USRCLS(userclass) ...
USRPRF
: The name of the user profile (e.g., SMITHJ).PASSWORD
: The user's initial password.USRCLS
: The user class (e.g., *USER, *PGMR, *SYSOPR, *SECADM, *SECOFR). This determines their base level of authority.WRKUSRPRF Command: You can also create a user profile using the WRKUSRPRF
command. This provides a menu-driven interface to work with user profiles.
2. Managing User Profiles
CHGUSRPRF Command: Use the CHGUSRPRF
command to modify existing user profiles. You can change passwords, user class, library lists, and other attributes.
CHGUSRPRF USRPRF(username) PASSWORD(newpassword) ...
DSPUSRPRF Command: The DSPUSRPRF
command displays the details of a user profile.
DSPUSRPRF USRPRF(username)
DLTUSRPRF Command: Use the DLTUSRPRF
command to delete a user profile.
DLTUSRPRF USRPRF(username)
WRKUSRPRF Command: As mentioned earlier, WRKUSRPRF
provides a menu-driven interface to work with user profiles. You can use it to create, change, display, copy, or delete user profiles.
3. Key Concepts
User Classes: AS400 has predefined user classes that represent different levels of authority:
*USER
: Basic user with limited access.*PGMR
: Programmer with authority to develop and test programs.*SYSOPR
: System operator with authority to manage system operations.*SECADM
: Security administrator with authority to manage system security.*SECOFR
: Security officer with the highest level of authority.Special Authorities: In addition to user class, you can grant specific special authorities to a user profile. These authorities allow users to perform specific tasks, such as managing objects, controlling jobs, or auditing security events.
Object Authority: User profiles are granted authority to access and manipulate objects (files, programs, etc.). You can grant different levels of authority, such as *READ, *UPDATE, *DELETE, *EXECUTE, and *ALL.
Group Profiles: You can create group profiles to group users together and grant them common authorities. This simplifies user management.
4. Security Best Practices
WRKSPLF and WRKOUTQ are essential commands in IBM i (formerly AS400) for managing spooled files and output queues. Here's a breakdown of their roles:
WRKSPLF (Work with Spooled Files)
WRKOUTQ (Work with Output Queues)
Key Differences Summarized:
Feature | WRKSPLF | WRKOUTQ |
---|---|---|
Focus | Spooled files | Output queues |
Actions | Manage individual spooled files | Manage output queues and their contents |
Use Cases | Troubleshooting print jobs, managing print output, viewing reports | Managing printer resources, controlling print flow, troubleshooting output queue issues |
The CHGJOB
command in IBM i (formerly AS400) allows you to change the attributes of a currently running job. It's a powerful tool for dynamically adjusting job characteristics without having to end and resubmit the job.
Here's a breakdown of its purpose and key uses:
Purpose:
CHGJOB
lets you modify various aspects of a job while it's active. This can be crucial for:
CHGJOB
to adjust its priority, time slice, or other attributes.Key Parameters and Uses:
CHGJOB
has many parameters, allowing you to modify a wide range of job attributes. Here are some of the most commonly used ones:
JOB
parameter, it defaults to the currently running job.HLD
for hold, RLS
for release). This is useful for pausing and resuming jobs.Examples:
Changing Job Priority:
CHGJOB JOB(MYJOB) JOBPTY(3)
This command changes the priority of the job named MYJOB
to 3.
Holding a Job:
CHGJOB STATUS(HLD)
This command puts the currently running job on hold.
Changing the Current Library:
CHGJOB CURLIB(NEWLIB)
This command changes the current library for the currently running job to NEWLIB
.
Setting a Time Limit:
CHGJOB TIMLMT(30) /* 30 seconds */
This command sets a time limit of 30 seconds for the currently running job.
ou're asking about the core save commands on IBM i (formerly AS400), used for backing up your system and data. Here's a breakdown of SAVOBJ, SAVLIB, and SAVSYS:
SAVOBJ (Save Object)
SAVOBJ OBJ(MYPROG) LIB(MYLIB) SAVF(MYLIB/SAVEFILE1)
MYPROG
from library MYLIB
to the save file SAVEFILE1
in MYLIB
.SAVLIB (Save Library)
SAVLIB LIB(MYLIB) SAVF(MYLIB/SAVEFILE2)
MYLIB
to the save file SAVEFILE2
in MYLIB
.SAVSYS (Save System)
SAVSYS DEV(TAP01)
TAP01
.Key Differences Summarized:
Feature | SAVOBJ | SAVLIB | SAVSYS |
---|---|---|---|
Scope | Individual objects or groups of objects | Entire library | Entire system |
Granularity | Very fine-grained | Library level | System level |
Use Cases | Specific object backups, archiving | Library backups, copies, migrations | Disaster recovery, system upgrades, migrations |
State | Can be run online (for most objects) | Can be run online (for most libraries) | Must be run in a restricted state |
Troubleshooting slow jobs on IBM i (AS400) requires a systematic approach. Here's a breakdown of common causes and how to investigate them:
1. Identify the Slow Job
WRKACTJOB
command to display active jobs. Look for jobs that have been running for an unusually long time or have a high CPU percentage.2. Common Causes and Solutions
CPU Bottleneck:
WRKACTJOB
or performance monitoring tools.Memory Bottleneck:
I/O Bottleneck:
Lock Contention:
DSPRCDLCK
command to display record locks and identify which job is holding the lock.Network Bottleneck:
Database Issues:
Software Issues:
3. Performance Monitoring Tools
4. Other Tips
Troubleshooting slow jobs often involves a process of elimination. Start by identifying the job, then systematically investigate potential causes, using the tools and techniques described above. Remember to document your findings and any changes you make to the system or application.
Backing up and restoring data on AS/400 (IBM i) is essential for system recovery, disaster preparedness, and maintaining business continuity. Below are the key methods, commands, and best practices for backup and restore operations.
IBM i provides various SAV*
commands to back up different objects:
Command | Purpose |
---|---|
SAVLIB |
Saves a library (including objects and data) |
SAVOBJ |
Saves a specific object (e.g., files, programs) |
SAVDLO |
Saves documents and folders |
SAVCFG |
Saves system configuration |
SAVSYS |
Saves entire system (Licensed Internal Code, QSYS library, OS, and user profiles) |
SAVSECDTA |
Saves security data (user profiles, authorization lists, passwords, etc.) |
SAVCHGOBJ |
Saves only changed objects since last backup |
IBM i provides the GO SAVE menu for automated backup operations.
Command :
GO SAVE
SAVLIB LIB(MYLIB) DEV(TAP01) SAVACT(*YES)
SAVACT(*YES)
allows saving active objects.SAVOBJ OBJ(MYFILE) LIB(MYLIB) DEV(*SAVF) SAVF(MYLIB/MYBACKUP)
SAVSECDTA DEV(TAP01)
SAVCFG DEV(TAP01)
SAVCHGOBJ OBJ(*ALL) LIB(MYLIB) DEV(TAP01) REFERENCE(*LIB)
IBM i provides various RST*
commands for restoring data:
Command | Purpose |
---|---|
RSTLIB |
Restores an entire library |
RSTOBJ |
Restores specific objects |
RSTUSRPRF |
Restores user profiles |
RSTCFG |
Restores system configurations |
RSTSYS |
Restores the entire system (from SAVSYS backup) |
RSTLIB LIB(MYLIB) DEV(TAP01) MBROPT(*ALL) ALWOBJDIF(*ALL)
MBROPT(*ALL)
: Restores all members of files.ALWOBJDIF(*ALL)
: Allows restoring even if object differences exist.RSTOBJ OBJ(MYFILE) LIB(MYLIB) DEV(*SAVF) SAVF(MYLIB/MYBACKUP)
RSTUSRPRF DEV(TAP01) USRPRF(*ALL)
RSTCFG OBJ(*ALL) DEV(TAP01) OBJTYPE(*ALL)
RSTSYS DEV(TAP01)
Instead of using tapes, backups can be stored in a save file (SAVF) on disk.
CRTSAVF FILE(MYLIB/MYBACKUP)
SAVLIB LIB(MYLIB) DEV(*SAVF) SAVF(MYLIB/MYBACKUP)
RSTLIB LIB(MYLIB) DEV(*SAVF) SAVF(MYLIB/MYBACKUP)
IBM i allows scheduling backups using job scheduler (WRKJOBSCDE).
ADDJOBSCDE JOB(BACKUP) CMD(SAVLIB LIB(MYLIB) DEV(TAP01))
FRQ(*DAILY) SCDTIME(230000)
* Perform regular full backups (SAVSYS, SAVLIB, SAVSECDTA, SAVCFG).
* Use Save Files (SAVF) for faster, disk-based backups.
* Schedule incremental backups (SAVCHGOBJ) to save only changed objects.
* Verify backups using DSPTAP (Display Tape Contents).
* Perform test restores to ensure backup integrity.
* Store backups offsite for disaster recovery.
* Monitor backup jobs using WRKACTJOB.
DSPTAP DEV(TAP01) DATA(*SAVRST)
DSPLOG PERIOD((*AVAIL *CURRENT))
Task | Backup Command | Restore Command |
---|---|---|
Entire Library | SAVLIB LIB(MYLIB) DEV(TAP01) |
RSTLIB LIB(MYLIB) DEV(TAP01) |
Specific Object | SAVOBJ OBJ(MYFILE) LIB(MYLIB) DEV(*SAVF) |
RSTOBJ OBJ(MYFILE) LIB(MYLIB) DEV(*SAVF) |
User Profiles | SAVSECDTA DEV(TAP01) |
RSTUSRPRF DEV(TAP01) USRPRF(*ALL) |
System Configuration | SAVCFG DEV(TAP01) |
RSTCFG DEV(TAP01) OBJ(*ALL) |
Entire System | SAVSYS DEV(TAP01) |
RSTSYS DEV(TAP01) |
CPF (Control Program Facility) messages are absolutely fundamental to understanding and managing IBM i (formerly AS400) systems. They're the primary way the system communicates with users and administrators about everything from routine operations to critical errors. Here's a breakdown of their significance:
What are CPF Messages?
Significance of CPF Messages:
Error Handling: CPF messages are essential for handling errors in programs and commands. CL programs, for example, use the MONMSG
command to monitor for specific CPF messages and take appropriate actions. RPG programs can also check for SQL errors indicated by CPF messages.
System Monitoring: System administrators rely on CPF messages to monitor the health and status of the system. They can be configured to receive alerts for critical messages, allowing them to proactively address problems.
Troubleshooting: When something goes wrong on the system, CPF messages are the first place to look for clues. They provide valuable information about the nature of the problem and can guide you towards a solution.
Job Management: Job logs, which contain CPF messages related to the execution of a job, are crucial for understanding how a job ran and for troubleshooting any issues that occurred.
Auditing: CPF messages can be audited to track system events and user activity. This is important for security and compliance.
User Interaction: Inquiry messages, a type of CPF message, allow the system to interact with users, requesting input or confirmation.
Working with CPF Messages:
DSPMSG
command is used to display messages in a message queue. You can use it to view system messages, job log messages, or messages sent to a specific user.WRKMSG
command provides a menu-driven interface for working with messages.QCPFMSG
is the system message file. You can create your own message files for application-specific messages.Example:
If a program tries to open a file that doesn't exist, the system will issue a CPF2812 message ("File not found"). The program can use MONMSG
to trap this message and take appropriate action (e.g., display an error message to the user, create the missing file, or end the program).
API calls on AS400 (now IBM i) serve the same fundamental purpose as they do in any other computing environment: to enable communication and interaction between different software components.
Here's a breakdown of why API calls are important on AS400:
1. Accessing System Resources and Functions:
2. Integrating with Other Applications:
3. Enhancing Functionality:
4. Simplifying Development:
5. Security:
How API Calls Work on AS400:
Multi-threading in AS400 (now IBM i) allows a single job to execute multiple parts of its program concurrently. Think of it as having multiple workers within the same job, each handling a different task at the same time. This can significantly improve performance, especially for applications that can break down their work into independent pieces.
How Multi-threading Works on AS400
Benefits of Multi-threading
How Multi-threading is Handled on AS400
Considerations for Multi-threading