Upload
others
View
9
Download
1
Embed Size (px)
Citation preview
SQL in RPG
Transform Your RPG with the Power You Deserve!
Goals
● Create RPG source that can contain SQL
● Compile these sources as programs or modules
● Learn and use techniques to handle data between SQL and RPG variables
● Use some awesome SQL features to power up our RPG
SQLRPGLE
● Way too many letters● A new type of data source, totally backwards compatible● Turn any source into an source● Only adds features, takes none away● Compiles with a different command● Allows
CRTSQLRPGI
● Use this to compile your source● Same outcome, but this runs a SQL precompile first
○ Lets you know if any of your SQL will break○ Checks to make sure tables exist
● Replace both and ○ This new command takes in ObjType(*PGM) or ObjType(*Module)
● If you’re using RDi (you should!) you don’t even have to think about it
Getting started
● Create a program exactly as you normally would, but of type ○ No F-Specs needed!
● Create variables LIKE your tables
● “EXEC SQL …” to run any SQL you want○ Test everything out in Run SQL Scripts and then copy it over!○ Many strategies to getting the most out of embedded SQL
● Within SQL, use colons to access RPG variables○ “… WHERE id = :id ”
CRTSQLRPGI
CRTSQLRPGI OBJ(&O/&N) SRCFILE(&L/&F) SRCMBR(&N) REPLACE(&R)
CRTSQLMOD
CRTSQLRPGI OBJ(&O/&N) SRCFILE(&L/&F) SRCMBR(&N) OBJTYPE(*MODULE) REPLACE(&R)
Many other options you may or may not want
Before we get started
● SQL Options○ Whatever you need to do with commitment control
● Many of the following strategies do not exactly translate to Run SQL Scripts○ For each, I will show which parts can go back and forth for testing
● SQL to create tables, etc. generally won’t apply here○ Instead we’ll be looking at various ways so look through and update data on existing tables
Commitment Control
● Make all the database changes you want
● Nothing happens until a “commit”
● If one statement fails towards the end, you can avoid committing anything
● More often than not I turn off commitment control
EXEC SQL SET OPTION commit=*chg;or
EXEC SQL SET OPTION commit=*none;
Embedded SQL Strategies
External Name
● Create Data Structures exactly like your table● Can be a single data structure, or an array● It will have fields for all your different columns● Must use system name for the table, not the SQL name
Template variables
● Since we don’t have F-specs, we need standalone variables for everything● Create a template DS that is like a table● It will take up no memory itself, but can be used to define variables when
needed
Embedded SQL Strategies
Select Into
Select Into
● Get some data from a table, and put it into a variable● You can use “SELECT *” and the whole data structure● Be sure you’re only getting one record back
Select Into
● Use a template variable if you just need some fields
Select Into
● More usefully, the WHERE clause can also use RPG variables
Select Into - Testing in Run SQL Scripts
● Put together your SELECT in Run SQL Scripts● Leave out the “INTO” - no RPG variables allowed● Try running it and make sure you’re getting the data you expect● Make sure you’re getting one record back with the type of data you want
Select Into - Testing in Run SQL Scripts
Select Into Summary
● Use any crazy query you can come up with
● Utilize joins, Built-In SQL functions, and other SQL features
● Take in input or use any RPG variables to help find your data
● Finally, get that data you retrieved and put it into a new RPG variable
Embedded SQL Strategies
Insert
Insert with RPG variables
● Use RPG variables as we saw, but on an insert statement● Use a whole data structure again to make things nicer
Insert with RPG variables
● Specify column names if you want to use the auto-generate, auto-increment features
● Bulk insert a data structure array
● Wrap the values you’re inserting in SQL functions when you need
● Easy to test in Run SQL Scripts, just replace RPG variables with sample data
Embedded SQL Strategies
Update
Update with RPG variables
● Use RPG variables to filter like SELECT INTO
● Use RPG variables to write data like INSERT
● Still using SQL functions wherever you want
● Easy to test in Run SQL Scripts, just replace RPG variables with sample data
Embedded SQL Strategies
Cursors
Cursors
● Open a cursor with a SELECT statement with many rows● Loop through the cursor● Similar use and concept as and but with increased flexibility
● Fill a data structure array with all your rowsOR
● Fill a single data structure to be used just within each loop
Cursors
● Every cursor is declared with a name
● Every cursor must be opened and closed
Cursors - updating
● Must include FOR UPDATE OF
● UPDATE without a WHERE clause
Cursors without a loop
● Instead of looping, you can fetch all your rows at once
● Declare your data structure with a dimension at the beginning
● Declaring, opening, and closing the cursor still necessary
● Fetch the number of rows equal to that array size instead of a loop
Cursors - Testing in Run SQL Scripts
● Cursors are totally valid in Run SQL Scripts, however RPG loops are not
● The most important thing to test beforehand with cursors is your select statement○ Run SQL Scripts is perfect for testing SELECTs!
● Make sure you get exactly the rows you want to be looping through
● The rest of your cursor logic will largely be RPG, or should be broken down further for testing
Error Handling
SQLSTATE
● sqlstate is a variable you don’t have to define● char(5)
○ But made up of numbers
● Always exists within any SQL compiled RPG● You can check its value at any time● After running a statement, the value will update based on success
SQLSTATE
● ‘00XXX’ - Success
● ‘01XXX’ - Warning
● ‘02XXX’ - No data found to act upon
● Anything greater is an error○ Google!
SQLSTATE
● After any EXEC SQL, you can check the value of sqlstate and throw an error if necessary
● Easy to leave loop or give a known message for ‘02XXX’
● Anything higher is probably not anticipated, so logging the sqlstate in some way is a good idea
SQLSTATE
Use SQLSTATE to leave Cursor
SQLCODE
● Another variable you can use anywhere, similar to sqlstate● Different values with different meanings, but generally map to each other● SQLCODE is numeric● Error if less than 0● Perfect if 0● Warning if greater than 0
○ 100 = No data to act upon
● I tend to use sqlstate but they both do the job
Get the most out of SQL
Set
● Simply setting a variable, but with the power of SQL● Great for handling timestamps● Great for using SQL functions when no data is needed
Set
Whenever I need Regex, I go straight for SQL
Use handy SQL functions - IBM is always creating more!
Diagnostics
Date and Time
● Create a date, time, or timestamp● OR use
○ CURRENT TIMESTAMP○ CURRENT DATE○ CURRENT TIME
Date and Time
● YEAR(:timestamp)● MONTH(:timestamp)● DAY(:timestamp)● HOUR(:timestamp)● MINUTE(:timestamp)● SECOND(:timestamp)
Date and Time
● Easily subtract dates and times
Aggregations
● COUNT(column_name)○ Count how many rows were returned in any select statement
● SUM(column_name)○ Sum up a numeric column, only on the rows that you select
● These are aggregate functions○ They can’t be combined with selecting row data*
● They can be combined with each other, as long as they are aggregating the same rows
Aggregations
Summary
● Create and compile your sources as - no downsides!● Write powerful SQL in , then bring that into your RPG code● Create RPG variables based on a table
○ No F-specs!
● Use many different strategies to use SQL with RPG variables● Try out all the awesome new features SQL provides us, find new features
every day
IBM is putting a crazy amount of effort into this so we want to keep up!