I’m not going to criticise anyone for trying to move away from native I/O on the IBM i and into SQL, but I have seen a few eye-watering attempts. So in the spirit of sharing knowledge and making life a bit easier for all of us, here is an example of reading and updating a table using SQL.
Let’s start with the table we’re updating. It’s a very simple table and simply maps the SoldTo/ShipTo combination in the distibution system to a Store number in the retail system. You can build a simplified version of this using the following:
create table
testlib.sqltest
(index integer not null
GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),
Soldto char (5) not null,
shipto char (4) not null,
store numeric (5, 0) not null)
The requirement is that, based on various business rules, some SoldTo numbers in this table need to be changed. In order to keep things simple, the below program applies a simple rule of: If the store number is less than ten, change the SoldTo to 99999. (I know, I said I was keeping things simple).
The program, as it stands, is pretty much as simple as it gets, but there are couple of points that are worth noting explicitly.
Firstly, when we declare the cursor, we need to include a For Update clause to identify which field (or fields) can be updated.
Secondly, in the Update statement, the Where Current of C1 clause applies the update to all records returned by the cursor. That means that flexible mass updates with a minimum of logical mess are now at your fingertips.
H
D SqlRecord DS
D SoldTo 5A
D ShipTo 4A
D Store 5S 0
D
D NewSoldTo S 5A
/Free
Exec Sql
Declare C1 cursor for
Select SoldTo, ShipTo, Store
From SqlTest
For Update of SoldTo;
Exec Sql
Open C1;
Dou SQLSTATE>='02000';
Exec Sql
Fetch C1 into :SqlRecord;
If SQLSTATE<'02000';
If Store<=10;
NewSoldTo='99999';
Exec Sql
Update SqlTest
Set SoldTo = :NewSoldTo
Where current of C1;
Endif;
Endif;
Enddo;
Exec Sql
Close C1;
*INLR=*ON;
/End-Free


Talkback