Advanced Technical Support (ATS), Americas © 2004 IBM Corporation New Cool SQL Enhancements in DB2 for z/OS Version 8 CDUG – July 20, 2006 John Iczkovits [email protected]
Jan 20, 2015
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
New Cool SQL Enhancements in DB2 for z/OS Version 8
CDUG – July 20, 2006
John [email protected]
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
What's new in V8?
Scalar fullselect
Multiple DISTINCT clauses
Dynamic scrollable cursors
Multi-row FETCH and INSERT
GET DIAGNOSTICS statement
INSERT within SELECT statement
Sequence objects
Identity column enhancements
CURRENT PACKAGE PATH special register
Common table expressions and recursive SQL
And maybe more....
DB2
DB2DB2DB2DB2
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Scalar Fullselect
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Scalar fullselect
What is it? .....
–A scalar fullselect is a fullselect, enclosed in parentheses, that returns a single value
–Scalar fullselect can be used in an expression
–Example:SELECT PRODUCT, PRICE
FROM PRODUCTS
WHERE PRICE <= 0.7 * (SELECT AVG(PRICE) FROM PRODUCTS);
Benefits .....
–Enhances usability and power of SQL
–Facilitates portability
–Conforms with SQL standards
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Scalar fullselect -- tables used in examples
PART PROD# SUPPLIER WIRE 10 ACWF OIL 160 WESTERN_CHEM MAGNETS 10 BATEMAN PLASTIC 30 PLASTIC_CORP BLADES 205 ACE_STEEL
PROD# PRODUCT PRICE505 SCREWDRIVER 3.70 30 RELAY 7.55 205 SAW 18.90 10 GENERATOR 45.75
PRODUCTS
PART _ PROD# SUPPLIER PRICEWIRE 10 ACWF 3.50 OIL 160 WESTERN_CHEM 1.50 MAGNETS 10 BATEMAN 59.50 PLASTIC 30 PLASTIC_CORP 2.00 BLADES 205 ACE_STEEL 8.90
PART PROD# SUPPLIER ONHAND#WIRE 10 ACWF 8 OIL 160 WESTERN_CHEM 25 MAGNETS 10 BATEMAN 3 PLASTIC 30 PLASTIC_CORP 5 BLADES 205 ACE_STEEL 10
INVENTORY
PARTS PARTPRICE
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Scalar fullselects in a WHERE clauseFind which products have the prices of at least twice the lowest price of all the products.
SELECT PRODUCT, PRICE FROM PRODUCTS A
WHERE PRICE >= 2 * (SELECT MIN(PRICE) FROM PRODUCTS);
PRODUCT PRICERELAY 7.55 SAW 18.90GENERATOR 45.75
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Nested scalar fullselects in a SELECT list
Find the cost of inventory for each product by calculating the sum of(price * onhand#) for each part in the product.
SELECT PRODUCT, (SELECT COALESCE(SUM(X.COST),0) AS INV_COST
FROM (SELECT ( (SELECT PRICE FROM PARTPRICE P WHERE P.PART = B.PART) *(SELECT ONHAND# FROM INVENTORY I WHERE I.PART =B.PART) ) AS COST FROM PARTS B WHERE B.PROD# = A.PROD#
) X(COST) )
FROM PRODUCTS A;
PRODUCT INV_COSTSCREWDRIVER .00 RELAY 10.00 SAW 89.00 GENERATOR 206.50
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Scalar fullselects -- in CASE expression of UPDATE
Give discount to the parts that have the large inventory and raise price on the parts that have the small inventory.
CREATE TABLE NEW_PARTPRICE LIKE PARTPRICE; INSERT INTO NEW_PARTPRICE SELECT * FROM PARTPRICE; UPDATE NEW_PARTPRICE N SET PRICE = CASE
WHEN( (SELECT ONHAND# FROM INVENTORY WHERE PART=N.PART) < 7)THEN 1.1 * PRICE
WHEN( (SELECT ONHAND# FROM INVENTORY WHERE PART=N.PART) > 20) THEN .8 * PRICE
ELSE PRICE END;
SELECT * FROM NEW_PARTPRICE;
PART PROD# SUPPLIER PRICEWIRE 10 ACWF 3.50 OIL 160 WESTERN_CHEM 1.20 MAGNETS 10 BATEMAN 65.45 PLASTIC 30 PLASTIC_CORP 2.20 BLADES 205 ACE_STEEL 8.90
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Scalar fullselect -- restrictions
a CHECK constraint
a grouping expression
a view that has a WITH CHECK OPTION
a CREATE FUNCTION (SQL scalar)
a column function
ORDER BY clause
join-condition of the ON clause for INNER and OUTER JOINS
Scalar fullselect not supported in...
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Multiple DISTINCT Clauses
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Multiple DISTINCT clauses
What is it? .....
–Allows more than one DISTINCT keyword on the SELECT or HAVING clause for a query
–DB2 can now evaluate standard deviation & variance column functions
Benefits .....
–Enhances usability and power of SQL
–DB2 family compatibility
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Multiple DISTINCT clauses
Prior to Version 8 . . .–SELECT DISTINCT C1, C2 FROM T1;
–SELECT COUNT(DISTINCT C1) FROM T1;
–SELECT C1, COUNT(DISTINCT C2) FROM T1 GROUP BY C1;
–SELECT COUNT(DISTINCT(C1)),SUM(DISTINCT C1) FROM T1; -- same col
With Version 8 . . .–SELECT DISTINCT COUNT(DISTINCT C1), SUM(DISTINCT C2) FROM T1;
–SELECT COUNT(DISTINCT C1), AVG(DISTINCT C2) FROM T1 GROUP BY C1;
–SELECT SUM(DISTINCT C1), COUNT(DISTINCT C1), AVG(DISTINCT C2) FROM T1 GROUP BY C1 HAVING SUM(DISTINCT C1) = 1;
Not supported in Version 8 . . .–SELECT COUNT(DISTINCT A1,A2) FROM T1 GROUP BY A2;
–SELECT COUNT(DISTINCT(A1,A2)) FROM T1 GROUP BY A2;
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Dynamic Scrollable Cursors
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Dynamic scrollable cursors
What is it? .....–Dynamic scrollable cursor:
Scrolls directly on base table (TS scan, IX scan & DPSI) No result table materialized at any time Immediate visibility of committed updates, inserts, deletes
Positioned updates and deletes allowed when possibleAvoid sort by using backward index scan for ORDER BY
Benefits .....–Enhances usability and power of SQL
–Facilitates portability
–Conforms to SQL standards
–Performance improved by sort elimination
–Elimination of work file (temporary table)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Static scrollable cursors -- Version 7 review
FETCH CURSOR...
Cursors can be scrolled–backwards–forwards–to an absolute position–to a position relative to the current cursor
–before/after position
Result table in TEMP DB
Rows refreshed on demand
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Sensitive and insensitive Static cursors - V7 review
DECLARE C1 INSENSITIVESCROLL..
OPEN C1 ...FETCH INSENSITIVE...
TEMP TABLE
BASE TABLE
ƒRead only cursorƒNot aware of updates or
deletes in base table
PROGRAM
DECLARE C1 SENSITIVESTATIC SCROLL..
OPEN C1 ...FETCH INSENSITIVE...
ƒUpdatable cursorƒAware of own updates or
deletes within cursorƒOther changes to base
table not visible to cursorƒAll inserts not recognized
TEMP TABLE
BASE TABLE
PROGRAM
DECLARE C1 SENSITIVESTATIC SCROLL..
OPEN C1 ...FETCH SENSITIVE...
ƒUpdatable cursorƒAware of own updates and
deletes within cursorƒsees all committed updates and deletesƒAll inserts not recognized
TEMP TABLE
BASE TABLE
PROGRAM
Order by, table join and aggregate functions will force READ ONLY
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
STATIC SCROLL CursorsBase TableDB2 Table
Result TableDB2 Declared Temp Table
SCROLL
Accessed by many
Exclusive access by agent
Fixed number of rows
Goes away at Close Cursor
Requires declared TEMP database and predefined table spaces
Base Table &Result Table are kept in sync as each row is fetched if sensitive. Insensitive reads off the DTT – no need to fetch updated or deleted data.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
What does the TEMP ROW look like?
SELECT C1, C2, C1+C2, LOB1 WHERE C3 < 5
Insensitive cursor temp table row
16 byte Absolute number
C1
Length of C1
C2
Length of C2
C1+C2
Max Length(C1,C2)
Lob1120 bytelob descriptor
Sensitive cursor temp table row
16 byte Absolute number
6 byte control information
5 byte Rid
C1
Length of C1
C2
Length of C2
C1+C2
Max Length(C1,C2)
Lob1120 bytelob descriptor
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Dynamic scrollable cursors -- V8 new functionScrollable cursor that provides access to the base
table rather than a DTT (Declared Temporary Table) --allows visibility of updates and inserts done by you or other users
Defaults to single row FETCH, so DDF applications should use:
–Multi-row FETCH
–Positioned UPDATE/DELETE for multi-row FETCH
DECLARE C1 SENSITIVE DYNAMIC SCROLL CURSOR FOR SELECT C1, C2 FROM T1;
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
New DECLARE CURSOR statement attributes
SENSITIVE DYNAMIC–Specifies that size of result table is not fixed at OPEN cursor time–Cursor has complete visibility to changes
All committed inserts, updates, deletes by other application processes All positioned updates and deletes within cursorAll inserts, updates, deletes by same application processes, but outside cursor
–FETCH executed against base table since no temporary result table created
ASENSITIVE –DB2 determines sensitivity of cursor–If read-only...
It behaves as an insensitive cursorCursor is INSENSITIVE if SELECT statement does not allow it to be SENSITIVE (UNION, UNION ALL, FOR FETCH ONLY, FOR READ ONLY)
–If not read only, SENSITIVE DYNAMIC is used for maximum sensitivity–Mainly for client applications that do not care whether or not the server supports the sensitivity or scrollability
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Implications on FETCH with Dynamic ScrollINSENSITIVE not allowed with FETCH statement (SQLCODE -244) if
–The associated cursor is declared as SENSITIVE DYNAMIC SCROLL
–The cursor is declared ASENSITIVE and DB2 chooses the maximum allowable sensitivity of SENSITIVE DYNAMIC SCROLL
There are no "holes" (almost) as there is no temporary result table
–Special case: If FETCH CURRENT or FETCH RELATIVE +0 requested but row on which cursor is positioned was deleted or updated so that it no longer meets selection criteria (SQLCODE +231) which says "hole" detected
–For example, can occur with ISOLATION(CS) and CURRENTDATA(NO)
Inserts by the application itself are immediately visible -- inserts by others are visible after commit
Order is always maintained
–If current row is updated, the cursor is positioned before the next row of the original location and there is no current row
–If current row deleted, the cursor is positioned before the next row of the original location and there is no current row
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
DECLARE CURSOR Syntax
>>-DECLARE-cursor-name---+--------------------------------------------------------------+---->| || |-ASENSITIVE-------------------| |
+---|-INSENSITIVE-------------------|----SCROLL--+|-SENSITIVE---STATIC--------|
|-DYNAMIC-|
>-----CURSOR--------+-----------------------+-----FOR---+-select-statement---+---------><+-WITH HOLD-----+ +-statement-name---+ +-WITH RETURN-+
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
• INSENSITIVE is used for static scrollable cursors only. Keep in mind that for static scrollable cursors you can have a combination of SENSATIVE and INSENSATIVE for the DECLARE and FETCH statements. Make sure you know which one is being discussed on which statement.
• SENSITIVE can be used for either static or dynamic scrollable cursors. Which one are you dealing with?
• Be careful when using ASENSITIVE, you may not get what you want.
• Isolation levels and CURRENTDATA values matter, mostly because of the ‘holes’ issue. Make sure you are getting the datayou want.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
FETCH Orientation Syntax
+---NEXT------------------------------------------+>>-FETCH----+--------------------+--+-----------------------------------------------------+--------->
+-INSENSITIVE-+ |---PRIOR------------------------------------------|+-SENSITIVE----+ |---FIRST-------------------------------------------|
|---LAST--------------------------------------------||---CURRENT-------------------------------------||---BEFORE---------------------------------------||---AFTER------------------------------------------||---ABSOLUTE--+-host-variable-------+---|| +-integer-constant--+ ||---RELATIVE----+-host-variable-------+---|
+-integer-constant--+
+-FROM-+>---+------------+----cursor-name-------+--------------------------------+------------------><
+--single-fetch-clause---+
single-fetch-clause:+---,----------------------+
|--+-----INTO---v---host-variable-----+-------------------+------------------------------------|+----INTO DESCRIPTOR----descriptor-name-----+
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
At OPEN CURSOR, cursor is positioned before first row
After FETCH, fetched row becomes current row and cursor positioned on current row
•When FETCH reaches end of file, cursor positioned after last row if scroll number positive and before first row if scroll number negative
•Ability to scroll backwards and forwards through result set which is ever changing
–Note that scroll quantity counts new inserts and has no way of counting deleted rows
–Usage example: airline reservation or credit card processing
Cursor position and scrolling
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
123456789
10 XXXX XXXX XXXX XXXX
11121314151617181920
Fetch Orientation and Cursor PositionResult table
FETCH ABSOLUTE 5
FETCH BEFORE
FETCH FIRST
FETCH RELATIVE - 3
FETCH PRIOR
FETCH RELATIVE 3
FETCH ABSOLUTE - 5
FETCH LAST
FETCH AFTER
FETCH or FETCH NEXT
FETCH CURRENT
Current Cursor Position
Independent ofstart cursor position
Ending position depends on startcursor position
Independent ofstart cursor position
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Cursor Positioning: Mixing Row and Rowset Positioned Fetches - Multi Row Fetch (V8)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Rowset Positioned Fetches
CUST_NO CUST_TYP CUST_NAME
1 P Ian2 P Mark3 P John4 P Karen5 P Sarah6 M Florence7 M Dylan8 M Bert9 M Jo
10 R Karen11 R Gary12 R Bill13 R Geoff14 R Julia15 R Sally
FETCH FIRST ROWSET FOR 3 ROWS
FETCH NEXT ROWSET
FETCH ROWSET STARTING AT ABSOLUTE 8
FETCH NEXT ROWSET FOR 10 ROWSPartial Result Set
Result table
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Partial Rowsets (Result Sets)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Determining rowset sizeIf FOR n ROWS is NOT specified and cursor is declared for rowsetpositioning..
Size of rowset will be the same as the previous rowset fetch as long as –It was the previous fetch for this cursor
–Or the previous fetch was a FETCH BEFORE or FETCH AFTER and the fetch before that was a rowset fetch
Else rowset is 1
FETCH FIRST ROWSET FOR 5 ROWS Returns 5 rows
FETCH NEXT ROWSET Returns the next 5 rows
FETCH NEXT Returns a single row
FETCH NEXT ROWSET Returns a single row
FETCH NEXT ROWSET FOR 3 ROWS Returns 3 rows
FETCH BEFORE Returns 0 rows
FETCH NEXT ROWSET Returns 3 rows
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Fetching beyond the result set
If you try to fetch beyond the result set you will receive end of data condition
–i.e., When there are only 5 rows left in result table and you request FETCH NEXT ROWSET FOR 10 ROWS, 5 rows will be returned with an SQLCODE +100
This includes where FETCH FIRST n ROWS ONLY has been specified
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Partial Result Sets
If you fetch beyond the end of the result set, you will receive an end of data conditionƒi.e., When there are only 5 rows left in result table and you
request FETCH NEXT ROWSET FOR 10 ROWS, 5 rows will be returned - SQLCODE +100
ƒSQLERRD(3) will contain the number or rows returnedƒThis includes where FETCH FIRST n ROWS ONLY has been
specified
If you fetch beyond the beginning of the result set, you will receive an end of data conditionƒ i.e., if you are positioned on rows 3,4,5,6, and 7, and you
request FETCH PRIOR ROWSET FOR 10 ROWS, 2 rows will be returned (Rows 1 and 2) - SQLCODE +20237
ƒSQLERRD(3) will contain the number or rows returned
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Fetching Beyond the Result Set ABSOLUTE or RELATIVE
If you fetch beyond the end of the result set, or beyond the beginning of the result set, you will receive an end of data conditionƒAssume you are positioned on row 5 in a result set with 10
rows. ƒFETCH ROWSET STARTING AT ABSOLUTE 15ƒFETCH ROWSET STARTING AT RELATIVE -7
ƒNo rows will be returned - SQLCODE +100ƒSQLERRD(3) will contain 0ƒCursor position will be either “BEFORE” or “AFTER” depending
on the direction of the FETCH.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
What's my position with Dynamic Scroll?
When you get a +100 fetching forward–Position is AFTER
Subsequent–FETCH PRIOR will give you the last row, or–FETCH NEXT will give you +100 again
When you get a +100 fetching backward–Position is BEFORE
Subsequent–FETCH NEXT will give you the first row, or–FETCH PRIOR will give you +100
When you get a +231 (row not found fetch current )
–Position is before the next rowFETCH NEXT will give you the next rowFETCH PRIOR will give you the previous rowFETCH CURRENT will give you +231
Application 1Cursor fetchCS, currentdata(no)
Application 2doing searched updates
Pos Delete
Fetch Current+231
+100
+100
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Resulting Cursor PositionsFetch
OrientationCurrent Position
before first row
Current Position on
first row
Current Position on
last row
Current Position After
Last row
Resulting Position on
Delete or Update Hole
Resulting Position on normal Row
Resulting Position Before
First row
Resulting Position After
Last Row
NEXT OK OK +100 +100 +222 IF OK N/A IF +100 FROM LAST ROW
PRIOR +100 +100 OK OK +222 IF OK IF+100 FROM LAST ROW
N/A
FIRST OK OK OK OK +222 IF OK N/A N/A
LAST OK OK OK OK N/A IFOK N/A N/A
BEFORE OK OK OK OK N/A N/A IF OK N/A
AFTER OK OK OK OK +222 N/A N/A IF OK
CURRENTRELATIVE 0
+231 OK OK +231 +222 IF OK N/A N/A
ABSOLUTE +N
OK OK OK OK +222 IF OK N/A IF +100 AND N OUT OF RANGE
ABSOLUTE -N
OK OK OK OK +222 IF OK IF +100 AND N OUT OF RANGE
N/A
RELATIVE +N
OK OK +100 +100 +222 IF OK N/A IF +100 AND N OUT OF RANGE
RELATIVE -N +100 +100 OK OK +222 IF OK IF +100 AND N OUT OF
RANGE
N/A
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Locking with dynamic scrollable cursorsISO CS recommended for maximum concurrency
–RR and RS severely restrict update of table by other users, therefore defeating purpose of SENSITIVE DYNAMIC
Lock is held on current row as base table is always accessed directly - beware of multi row operations!
As before, if ISO UR is on BIND option and SELECT statement contains FOR UPDATE OF, ISO promoted to CS
As normal, if cursor defined WITH HOLD, locks will be held until first commit after close of cursor unless DSNZPARM SPRMRCHL = NO, in which case locks held for held cursors released at COMMIT
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Serialization Preview
Use existing locking mechanisms, added one
RR - lock every page/row as it is readRS - lock every row that qualifies stage 1 predicateCS - lock each row fetched(currentdata(YES))
- lock only if cursor FOR UPDATE OF if (currentdata(no))UR - No rows locked
Optimistic Locking Mechanism (Static cursor only)Provides Maximum concurrency with isolation level
of Cursor StabilityNo locks held between fetchesValues Concurrency model (as opposed to the Lock
Concurrency model which is pessimistic locking)
New!
Review
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
No SCROLLand dynamic Cursor
StaticSCROLLCursor
OPTIMISTIC LOCKING
We release locks after fetch
Because we are optimistic that no positioned update or delete will occur
Even if it does, we are optimistic that the pertinent values will not have changed
So we compare by value under a new locknew lock to ensure data integrity
FETCH row 1Lock row 1
FETCHUnlock row 1Lock row 2
Update row 2
FETCH row 1Lock row 1Unlock row 1
FETCHLock row 2Unlock row 2
Update row 2Lock row 2ReevaluateCompareUpdate
Time Row 1 locked Row 2 lockedNo Locks No Locks
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Updating via scrollable cursors
Optimistic locking is used by static scrollable cursors
–Static scrollable cursors hold no locks on base tables after OPEN CURSOR
–Check at update time whether the row has not changed
Optimistic locking is not used by dynamic scrollable cursors
–Locks against the underlying table while fetching, similar to non-scrollable cursors
Positioned UPDATE and DELETE always allowed if cursor not read-only and the page or row lock was acquired successfully
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Updating Using Static Scrollable CursorsPositioned Updates & Deletes based on position on Temporary Result Table
DB2 locks corresponding Base Table row on a positioned update or delete and verifies that the row still satisfies the search condition
DB2 then matches the old values to the current values, while the row is locked, and allows the update or delete only if the values match
Update/Delete disallowed if either the row fails search condition or the values do not match
If the row passes the above two conditions then DB2 does the following
–For UPDATE
Updates the Base Table Refetches from the Base Table to reevaluate the predicateUpdates the Result Table
–If search condition fails - marks as Update Hole–If search condition satisfied - updates it with latest values
–For DELETE
Deletes the Base Table RowUpdates (deletes row from) the Result Table
–If search condition fails - marks as delete Hole–If search condition satisfied – deletes row
The next FETCH will see these updates
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Some Dynamic Scrollable Cursor considerations
Dynamic scrollable cursors are supported with stored procedures
–SP itself can update via dynamic scrollable cursor but program calling SP is restricted from updating using allocated cursor
Scalar functions and arithmetic expressions in SELECT list are reevaluated at every fetch
Column functions (AVG, MIN, MAX, etc.) are calculated once at open cursor
–Functions may not be meaningful because size of result set can change
Use of non-deterministic function (built-in or UDF) in WHERE clause of select statement or statement name of scrollable cursor can cause misleading results
–Result of function can vary from one FETCH to subsequent FETCH of same rowCursors requiring use of a workfile cannot be declared SENSITIVE DYNAMIC
–e.g. - SELECT COL1, MAX(COL2), COUNT(*) FROM T1 GROUP BY COL1 ORDER BY 3
Changes to tables referenced in subqueries are not reflected
Parallelism is not supported with dynamic scrollable cursors
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Cursor Type ComparisonCursor Type Result Table Visibility of
Own ChangesVisibility of Others' Changes
Updatability(*)
SCROLL not Specified(In V6)
Fixed, workfile No No No
SCROLL not Specified(In V6)
No workfile, base table access
No(No fetch current)
Yes Yes
INSENSITIVE SCROLL(In V7)
Fixed, declared temp table
No No No
SENSITIVE STATIC SCROLL(In V7)
Fixed, declared temp table
Yes(Inserts not allowed)
Yes(Not Inserts)
Yes
SENSITIVE DYNAMIC SCROLL (In V8)
No declared temp table, base table access
Yes Yes Yes
* A cursor can become read-only if the SELECT statement references more than one table, or contains a GROUP BY etc. (read-only by SQL)
New
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Static Scroll vs. Dynamic Scroll
IndexNPSI
UniqueIndex
DPSI Index
User table
Static ResultTable copy in temp database
Static scrollCursor Position
Dynamic scrollCursor Position
Dynamic scrollCursor Position
Dynamic scrollCursor Position
Dynamic scrollCursor Position
COPY
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
The HOLE ConceptIn STATIC SCROLL Cursors the number of rows in the result table is fixed but deletes and updates to the underlying base table can create DELETE HOLES or UPDATE HOLES
Holes are detected on a Sensitive FETCH–DELETE HOLE - Created when the corresponding base table row has been deleted
Once a delete hole, always a delete hole, delete holes are not refetched -HOWEVER, You can remove a delete hole only by opening the scrollable cursor, setting a savepoint, executing a positioned DELETE statement with the scrollable cursor, and rolling back to the savepoint.
–UPDATE HOLE - Created when the corresponding base table row has been modified such that the values of the rows do not qualify the row for the query any longer
Every SENSITIVE FETCH reevaluates the row against the predicate, if the evaluation fails, the row is marked as an Update Hole and a SQLCODE is returnedAn Update Hole can turn into a row again on a subsequent sensitive fetch of an Update hole. Basically, the row is updated back to its original value therefore the hole no longer exists.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Removing an Update Hole
1
2
3
4
5
2
3
4
5
66
1
2
3
4
5
EXEC SQL OPEN C4;
EXEC SQL
UPDATE A
SET COL1=COL1+1;
EXEC SQL UPDATE A
SET COL1=COL1-1;
Update
hole
Update
hole
disappears
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Savepoints and Rollback
Declare Cursor CUR1 SENSITIVE STATIC SCROLL for SELECT...
Set EXT Savepoint SVPT1; (1)Open CURSOR CUR1;Fetch from CUR1 into...;Update ....where current of CUR1; (2)Fetch from CUR1 into...; (3)Rollback to Savepoint SVPT1;
The update (2) is rolled backCursor stays openCursor keeps position from fetch (3)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
FETCH C1 INTO :hv_account, :hv_account_name
DECLARE C1 INSENSITIVE SCROLL CURSOR FORSELECT ACCOUNT, ACCOUNT_NAMEFROM ACCOUNTWHERE TYPE = 'P'
FOR UPDATE OF ACCOUNT_NAME
OPEN C1
Cursor temporary table
RID ACCOUNT ACCOUNT_NAMEA04 MNP230 MR P TENCHA07 ULP231 MS S FLYNN
DELETE FROM ACCOUNTWHERE ACCOUNT = 'MNP230';COMMIT;
ACCOUNT table
ACCOUNT ACCOUNT_NAME TYPE
ABC010 BIG PETROLEUM CBWH450 HUTH & DAUGHTERS CZXY930 MIGHTY BEARS PLC CMNP230 MR P TENCH PBMP291 BASEL FERRARI CXPM673 SCREAM SAVER PTY LTD CULP231 MS S FLYNN PXPM961 MICHAL LINGERIE C
ACCOUNT table
ACCOUNT ACCOUNT_NAME TYPE
ABC010 BIG PETROLEUM CBWH450 HUTH & DAUGHTERS CZXY930 MIGHTY BEARS PLC CMNP230 MR P TENCH CBMP291 BASEL FERRARI CXPM673 SCREAM SAVER PTY LTD CULP231 MS S FLYNN PXPM961 MICHAL LINGERIE C
ƒFETCH / FETCH ... ROWSET will not recognize the delete
ƒhv_account will contain MNP230ƒhv_account_name will contain MR P TENCH
ƒreturns 0 SQLCODE
Insensitive scrolling and holesReturns the row(s) from the result table as it is.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
FETCH C1 INTO :hv_account, :hv_account_name
Update and delete holes for sensitive static
DECLARE C1 SENSITIVE STATIC SCROLL CURSOR FOR
SELECT ACCOUNT, ACCOUNT_NAMEFROM ACCOUNTWHERE TYPE = 'P'
FOR UPDATE OF ACCOUNT_NAME
OPEN C1
Cursor temporary table
RID ACCOUNT ACCOUNT_NAMEA04 MNP230 MR P TENCHA07 ULP231 MS S FLYNN
DELETE FROM ACCOUNTWHERE ACCOUNT = 'MNP230';COMMIT;
ACCOUNT table
ACCOUNT ACCOUNT_NAME TYPE
ABC010 BIG PETROLEUM CBWH450 HUTH & DAUGHTERS CZXY930 MIGHTY BEARS PLC CMNP230 MR P TENCH PBMP291 BASEL FERRARI CXPM673 SCREAM SAVER PTY LTD CULP231 MS S FLYNN PXPM961 MICHAL LINGERIE C
ACCOUNT table
ACCOUNT ACCOUNT_NAME TYPE
ABC010 BIG PETROLEUM CBWH450 HUTH & DAUGHTERS CZXY930 MIGHTY BEARS PLC CMNP230 MR P TENCH CBMP291 BASEL FERRARI CXPM673 SCREAM SAVER PTY LTD CULP231 MS S FLYNN PXPM961 MICHAL LINGERIE C
ƒFETCH / FETCH ... ROWSET positions at first row in temp table
ƒrow has been deleted from base tableƒDB2 flags that FETCH is positioned on a delete hole by returning SQL code +222
ƒhost variables are not reset
Updates the fetched row in the result table from the corresponding row in the base table of the cursor’s SELECT statement and returns the current values. Thus, it reflects changes made outside this cursor.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Considerations using static scrollable cursors - multi row operations
When scrolling between rowsets:
–With insensitive fetches, updates by the application itself could cause changes and holes
–With sensitive fetches, updates by other applications could cause changes and holes
–For example, FETCH PRIOR ROWSET may return update or delete holes in place of rows that were fetched before
Row contents can change between fetches
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Using Multi-Row FETCH with Scrollable Cursors
CUSTNO NULLABLE_COL IND_VAR CUST_TYPE
1000 M P 2000 -1 B
-34000 F P
As holes may occur, ensure at least one indicator variable array is defined for a column
–Even if no nullable columns exist add an indicator variable array for at least one column
–If nullable columns exist all indicator variable arrays providedare updated if a hole is found
New value of -3 indicates hole
•SQLCODE +222 will also be returned
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Starting point and contents of rowsets will change when scrolling back and forth
Note that just after fetching the CURRENT ROWSET, other applications can insert rows in between the rows being returned as part of the rowset
–Refetching current rowset would return different rows, unless ISOLATION(RR)
FETCH PRIOR ROWSET will return the previous n rows that qualify from the start of the current cursor position
–Therefore n rows will be returned as long as start of rowset is not reached
Considerations with dynamic scrollable cursors -multi row operations
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Retrieve Data Backward with a Cursor********************************************* * Fetch the previous row in the table. ********************************************** EXEC SQL FETCH SENSITIVE PRIOR FROM THISEMP INTO :EMP-NUM, :NAME2, :DEPT, :JOB-NAME
END-EXEC. ********************************************* * Check that the fetched row is not a hole * * (SQLCODE +222). If not, print the contents. * ********************************************* IF SQLCODE IS GREATER THAN OR EQUAL TO 0
AND SQLCODE IS NOT EQUAL TO +100 AND SQLCODE IS NOT EQUAL TO +222
THEN PERFORM PRINT-RESULTS....
* Branch back to fetch the previous row. * ...* Close the cursor * CLOSE-THISEMP.
EXEC SQL CLOSE THISEMP
END-EXEC.
* Declare a cursor to retrieve the data backward * * from the EMP table. The cursor has access to * * changes by other processes. *EXEC SQL DECLARE THISEMP SENSITIVE STATIC
SCROLL CURSOR FOR SELECT EMPNO, LASTNAME,
WORKDEPT, JOB FROM DSN8810.EMP
END-EXEC. * Open the cursor * EXEC SQL OPEN THISEMP
END-EXEC. * Indicate what action to take when all rows * * in the result table have been fetched. * EXEC SQL WHENEVER NOT FOUND GO TO
CLOSE-THISEMP END-EXEC.
* Position the cursor after the last row of the result** table * EXEC SQL
FETCH AFTER FROM THISEMP END-EXEC.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Considerations for positioned update/delete
It is possible for another application process to update or delete a row in the base table of the SELECT statement so that the specified row of the cursor no longer has a corresponding row in the base table
–If the cursor is non-scrollable, this could happen if the cursor is ISOLATION(CS) CURRENTDATA(NO) and lock avoidance succeeds
–If the cursor is static scrollable, this could happen, since the result set is materialized into a temporary table and all underlying locks are released (unless ISOLATION(RR) or ISOLATION(RS)
–If the cursor is dynamic scrollable, this could happen if the cursor is ISOLATION(CS) CURRENTDATA(NO) and lock avoidance succeeds.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Cursor Related SQLCODEs
+222 - Update/delete hole detected
+231- Cursor position invalid
-222 - Update or delete attempted against an update or delete hole
-224 - Result table does not agree with base table
-225 - FETCH statement incompatible with Cursor definition
-228 - For update of clause specified for Read-only cursor
-243 - Sensitive Cursor cannot be defined for specific SELECT stmt
-244 - SENSITIVE specified on FETCH is not valid
-5012 - Host variable not exact numeric with scale zero
Existing SQLCODEs in new situations+100, -104, -151, -199, -508, -510, -628
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Determining Attributes of a Cursor By Checking the SQLCA - for V8 consider GET DIAGNOSTICS
After you open a cursor, you can determine the following attributes of the cursor by checking the following SQLWARN and SQLERRD fields of the SQLCA: SQLWARN1 Indicates whether the cursor is scrollable or non-scrollable. SQLWARN4 Indicates whether the cursor is insensitive (I), sensitive static (S), or sensitive dynamic (D). SQLWARN5 Indicates whether the cursor is read-only, readable and deletable, or readable, deletable, and updatable. SQLERRD(1) The number of rows in the result table of a cursor when the cursor position is after the last row (when SQLCODE is equal to +100). This field is not set for dynamic scrollable cursors. SQLERRD(2) The number of rows in the result table of a cursor when the cursor position is after the last row (when SQLCODE is equal to +100). This field is not set for dynamic scrollable cursors. SQLERRD(3) The number of rows in the result table of an INSERT when the SELECT statement of the cursor contains the INSERT statement.
If the OPEN statement executes with no errors or warnings, DB2 does not set SQLWARN0 when it sets SQLWARN1, SQLWARN4, or SQLWARN5. See Appendix D of DB2 SQL Reference for specific information about fields in the SQLCA.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Determining Attributes of a Cursor By Using the GET DIAGNOSTICS Statement
After you open a cursor, you can determine the following attributes of the cursor by checking these GET DIAGNOSTICS items:
DB2_SQL_ATTR_CURSOR_HOLD Indicates whether the cursor can be held open across commits (Y or N) DB2_SQL_ATTR_CURSOR_ROWSET Indicates whether the cursor can use rowset positioning (Y or N) DB2_SQL_ATTR_CURSOR_SCROLLABLE Indicates whether the cursor is scrollable (Y or N) DB2_SQL_ATTR_CURSOR_SENSITIVITY Indicates whether the cursor is asensitive, insensitive, or sensitive to changes that are made by other processes (A, I, or S) DB2_SQL_ATTR_CURSOR_TYPE Indicates whether the cursor is declared static (S for INSENSITIVE or SENSITIVE STATIC) or dynamic (D forSENSITIVE DYNAMIC)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Example - How would you Improve this?
* TABLE TXN ( TXNID CHAR(8), * TXNDATE CHAR(8) * DESC VARCHAR(8), * AMT INTEGER)
DECLARE CURSOR CU1 SENSITIVE STATIC SCROLL FOR
SELECT TXNDATE, AMT WHERE TXNID = 'SMITH' ORDER BY TXNDATE;
OPEN CURSOR CU1;
FETCH LASTFETCH LAST FROM CU1 INTO :HV1,:HV2 FETCH RELATIVE FETCH RELATIVE --44 FROM CU1 INTO :HV1,:HV2 App logic to Output row to screen
DO I = 1 TO 3 FETCH NEXT FROM CU1 INTO :HV1,:HV2 App logic to Output row to screen
END CLOSE CURSOR CU1
Sample application
program to display the last five rows from a table
e.g. Last 5 transactions from checking account
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Example - Alternative
* TABLE TXN ( TXNID CHAR(8), * TXNDATE CHAR(8) * DESC VARCHAR(8), * AMT INTEGER)
DECLARE CURSOR CU1 SENSITIVE STATIC SCROLL FOR
SELECT TXNDATE, AMT WHERE TXNID = 'SMITH' ORDER BY TXNDATE;
OPEN CURSOR CU1;
FETCH INSENSITIVE ABSOLUTE -5FROM CU1 INTO :HV1,:HV2
DO I = 1 TO 4 FETCH NEXT FROM CU1 INTO :HV1,:HV2 App logic to Output row to screen
END CLOSE CURSOR CU1
Sample application
program to display the last fiverows from a table
e.g. Last 5 transactions from checking account
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
ZPARM Considerations (V8)• MAX_NUM_CUR (MAX OPEN CURSORS)
– Number of cursors, including allocated cursors, that are open at a given DB2 site per thread.
– RDS will keep a total of currently open cursors. – If an application attempts to open a thread after the
maximum is reached, the statement will fail.– In a data sharing group, this parameter has member scope. – Acceptable values: 0 to 99999– Default (review default setting): 500
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Limit Result Table Size
Scrollable Cursors support FETCH FIRST n ROWS ONLY
–New function to limit number of rows in the result table
–Limits the result table to FIRST n ROWS
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
REXX SUPPORT
REXX to DB2 interface has changes for Scrollable Cursors V7
REXX to DB2 interface for V8 Dynamic Scrollable Cursors not implemented
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
DRDA considerations DB2 Linux, UNIX, and Windows V8.1 clients support dynamic scrollable cursors with FP4
–Only via the ODBC interface
–Only when calling DB2 for z/OS V8
Dynamic scrollable cursors do not support the DRDA limited block fetch protocol
–To achieve blocking, use multi-row fetch operations. This is currently supported between:
DB2 for z/OS V8 systemsYou can use any DB2 application programming
interface on the requesting mainframe which supports the use of multi-row in DB2 V8.
DB2 ODBC distributed clients using dynamic scrollable cursors and DB2 for z/OS V8
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Intersection with Other New V8 FunctionsInsert within SELECT
–A dynamic cursor is NOT allowed with a SELECT statement containing INSERT, but STATIC cursor is allowed. E.g.:
SELECT CHAR(MYROWID), MYIDENT into :HV1, HV2FROM FINAL TABLE(INSERT INTO VEHICLE (COLOR , TYPE) VALUES (:HV3,:HV4));
Multi Row Fetch–A dynamic cursor can have a SELECT statement with a multi row fetch option. E.g.:
DECLARE C1 SENSITIVE DYNAMIC CURSOR WITH ROWSET POSITIONING FOR SELECT * FROM EMP;FETCH ROWSET STARTING AT -3 FROM C1 FOR 3 ROWS INTO.....
Data Partitioning Secondary Index(DPSI)–Dynamic scrolling is supported using a DPSI if selected by the optimizer. Nuance - Order may or may not be important.
–Externally, DPSI is like any other index, however, DB2 has several LOC (Lines Of Code) to accommodate scrolling with DPSI, specially when the request includes an ORDER BY.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Index Manager Backward Scan SupportBackward Scan in Index Manager is enabled in V7
Used for performance improvement of Max and Min Functions–e.g.. When MutualFundsTable has an ascending index on RateOfReturn
SELECT FundName, MAX(RateOfReturn) WHERE Sector = 'Technology'
FROM MutualFundTable;
The ascending index is scanned backwards starting from the end until the WHERE clause is satisfied.
Eliminates need for descending indexes for Max function performance (or ascending indexes for MIN)
•Backward Index Scan is used more for DYNAMIC SCROLL Cursors during index scan in V8
No indexes on static table.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Backward index scan enabled
In V8, DB2 selects an ascending index and can use a backward scan to avoid the sort for the descending order
In V8, DB2 uses the descending index to avoid the sort and can scan the descending index backwards to provide the ascending order
To be able to use an index for backward scan, –Index must be defined on the same columns as ORDER BY and –Ordering must be exactly opposite of what is requested in ORDER BY. –i.e., if index defined as DATE DESC, TIME ASC, can do:
Forward scan for ORDER BY DATE DESC, TIME ASC Backward scan for ORDER BY DATE ASC, TIME DESC
– But must sort forORDER BY DATE ASC, TIME ASCORDER BY DATE DESC, TIME DESC
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Avoid Sort by using Backward Index Scan with ORDER BY in V8
SELECT STATUS_DATE, STATUSFROM ACCT_STATWHERE ACCT_NUM = :HVORDER BY STATUS_DATE DESC, STATUS_TIME DESC;
SELECT STATUS_DATE, STATUSFROM ACCT_STATWHERE ACCT_NUM = :HVORDER BY STATUS_DATE ASC, STATUS_TIME ASC;
Index on ACCT_STAT is ACCT_NUM, STATUS_DATE, STATUS_TIME
Same Index is used.
Backward index scan
Forward index scan
For scrollable and non
scrollable cursors
DB2 optimizer will select an ascending index to provide a descending sort order by traversing the index backwards rather than do a sort
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
IFCID Updates and SQL CODES in V8IFCID 65 for OPEN CURSOR
–adding information for
Scrollability -scrollable/non-scrollableSensitivity - sensitive/insensitive/not knownResult Table Type -static/dynamic/not known
IFCID 59 for FETCH
–adding information for
Sensitivity -sensitive/insensitive/not specifiedFetch Orientation -first/last/before/after/next/previous/absolute/relative/unknown
No new SQLCODES
Updated SQLCODES:
–+231 - Current position is not valid for fetch current
Only possible with dynamic scrollable cursors with isolation level CS, CURRENTDATA(NO) when FETCH CURRENT is issued and the current rowhas been deleted or updated so that it does not meet the selection criterion
–-244 - Keyword INSENSITIVE cannot be specified on the FETCH statement when fetching from a SENSITIVE DYNAMIC SCROLL cursor
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Basic Decisions for Application Design
What Result Types?–STATIC - fixed membership in result table
–DYNAMIC - result table membership changes as rows are inserted and deleted in the table
Restricted with SELECT statementNo ORDER BY with UPDATENo Joins, Functions, complex SQL
What Sensitivity?–ASENSITIVE - you don't know what you'll get
INSENSITIVESENSITIVE DYNAMIC
–INSENSITIVE - explicitly specified (membership is fixed)
–SENSITIVE - explicitly specified (membership depends on STATIC or DYNAMIC specification)
•What Isolation Level and Lock size?–CS with CURRENTDATA(YES) recommended if doing updates.
–CS with CURRENTDATA(NO) if not doing updates
–Row level locking will give max concurrency, however at a CPU cost, so be careful.
–But all locking semantics supported
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Performancebased on:
DB2 UDB for z/OS Version 8 Performance Topics SG24-6465
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Hardware and software environmentAll the test cases use the following environment:• Hardware: IBM z900 Series 2064-216 (z900 turbo)
– One LPAR with 2 dedicated processors– 7 GB real storage– Dedicated ESS model 800 (ESS)– 4 dedicated FICON channels
• Software– z/OS V1.4– DB2 V8– Non-data sharing
• Measurement data collected with DB2 Performance Expert V2– Accounting trace class 1,2,3– Statistics trace class 1,3,4,5,6,8
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Measurement methodology• One table defined in one segmented table space is used for
all measurements.• All the measurements involved only table space scans (1
index is defined).• First time effect
– Bring up the DB2 subsystem before each measurement to clear the data in the buffer pool, eliminating the inconsistency of different buffer hit ratios from run to run.
• No concurrency issues– There is no other program accessing the table space during the
measurements.• Read programs are bound with ISOLATION(CS) and
CURRENT DATA(NO)• Update programs are bound with ISOLATION(RS)• Each program issues one commit after closing the cursor
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Measurement cases• Read cursor (single row fetch) - Static vs.
dynamic• Update cursor (single row fetch and update)
- Static vs. dynamic• Multi-row FETCH using static or dynamic
cursors - Single row vs. multi-row• Multi-row FETCH and UPDATE or
DELETE using static or dynamic cursors -Single row vs. multi-row
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Test scenario 1: Read cursor - Static vs. dynamic
This test uses two types of FETCH programs. The intent is to compare insensitive with asensitive cursors for static and dynamic.The first program declares an insensitive scrollable cursor to retrievedata from the table. It means this program is strictly read-only (does not allow positioned update and delete).
DECLARE C1 INSENSITIVE SCROLL CURSOR WITH HOLD FOR SELECTCOL1, COL2, COL3, COL4, COL5,COL6, COL7, COL8, COL9, COL10FROM TABLEWHERE COL2 < ‘ROWNNNNNNNNN’;
DO I = 1 TO 50000;FETCH INSENSITIVE NEXT C1 INTO
:COL1,:COL2,:COL3,:COL4,:COL5,:COL6,:COL7,:COL8,:COL9,:COL10;
END;
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
The second program declares an ASENSITIVE SCROLLABLE cursor, which is the default in DECLARE CURSOR of V8. ASENSITIVE scrollable cursors allow DB2 to choose the maximum sensitivity of a cursor as possible, and in this case the following SELECT statement does not indicate read-only cursor (that is, a UNION or UNION ALL, ORDER BY, FOR READ ONLY, FOR FETCH ONLY) so DB2 determines dynamic as the maximum sensitivity.
DECLARE C1 ASENSITIVE SCROLL CURSOR WITH HOLD FOR SELECTCOL1, COL2, COL3, COL4, COL5,COL6, COL7, COL8, COL9, COL10FROM TABLEWHERE COL2 < ‘ROWNNNNNNNNN’;
DO I = 1 TO 50000;FETCH NEXT C1 INTO
:COL1,:COL2,:COL3,:COL4,:COL5,:COL6,:COL7,:COL8,:COL9,:COL10;
END;
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
TEST 1
• The measurements have been done varying the number of FETCHes and the number of qualified rows opened as a cursor. This is done to show how the performance is affected by different result set sizes (the size of the temporary table in the case of the static cursor examples). The summary of our test cases is:
• Use ISO(CS) and CD(NO) as a bind parameter• For the read program these options provide maximum performance and concurrency.• 50k or 10 FETCHes• FETCH of 10 columns for a total of 50 bytes• Qualified 1 million or 100k rows opened as a cursor• In the program we specified 1,000,000 or 100,000 in• ‘ROWnnnnnnnnn’ row-id.
• test results for static and dynamic cursors from the output of the DB2 PE trace record.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Fetch of 50K and 10 rows take almost the same time. This is due to populating the temp table with 1 million rows. Class 3 time is about the same, overhead for opening and formatting the temp table.
Times aremuch lowerbecause we
only populate
100K rows.
95% performanceimprovement overStatic!
99% performanceimprovement overStatic!
85% performanceimprovement overStatic!
The amount of FETCHes becomes the deciding factor for the dynamic cursor’s performance, whereas the number of qualifying rows was a deciding factorin the static cursor model.
Test 1 - Read cursor (single row fetch) - Static vs. dynamic
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Test scenario 2: Update cursor - Static vs. dynamic
• This case tests positioned updates and deletes. The intent is to compare sensitive cursors for static and dynamic.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
DECLARE C1 SENSITIVE STATIC SCROLL CURSOR WITH HOLD
FOR SELECT
COL1, COL2, COL3, COL4,
COL5,COL6 FROM TABLE
WHERE COL2 < ‘ROWNNNNNNNNN’
FOR UPDATE OF COL6;DO I = 1 TO 1000;FETCH SENSITIVE NEXT C1 INTO
:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;
UPDATE TABLE SET COL6 = :COL6 +10 WHERE CURRENT OF C1;END;(Same for Deletes)
DECLARE C1 SENSITIVE DYNAMIC SCROLL CURSOR WITH HOLDFOR SELECTCOL1, COL2, COL3, COL4, COL5,COL6 FROM TABLEWHERE COL2 < ‘ROWNNNNNNNNN’FOR UPDATE OF COL6;
DO I = 1 TO 1000;FETCH SENSITIVE NEXT C1 INTO
:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;
UPDATE TABLE SET COL6 = :COL6 +10 WHERE CURRENT OF C1;END;(Same for Deletes)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Test 2• As in the previous test case, we now examine UPDATEs and
DELETEs with different numbers of qualified rows. The summary description of this test case is:
• Use ISO(RS) as a bind parameter– This option protects data integrity (not for performance).
• 100k or 10 FETCHes followed by 100k or 10 UPDATEs• 100k or 10 FETCHes followed by 100k or 10 DELETEs• FETCH of 6 columns for a total of 37 bytes• Qualified 1 M or 50k rows opened as a cursor
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Test 2 - Update cursor (single row fetch and update) - Static vs. dynamic
NOTE – same type of results as in test 1!
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Test 3 - Multi-row FETCH using static or dynamic cursors –Single row vs. multi-row
DECLARE C1 INSENSITIVE SCROLL CURSOR WITH ROWSET POSITIONING WITH HOLD FOR SELECTCOL1, COL2, COL3, COL4, COL5,COL6, COL7, COL8, COL9, COL10FROM TABLEWHERE COL2 < ‘ROWNNNNNNNNN’;
FETCH INSENSITIVE FIRST ROWSET FROM C1 FOR 100 ROWS INTO:COL1,:COL2,:COL3,:COL4,:COL5,:COL6,:COL7,:COL8,:COL9,:COL10;
DO I = 1 TO 499;FETCH INSENSITIVE NEXT ROWSET
C1 INTO:COL1,:COL2,:COL3,:COL4,:COL5,:COL6,:COL7,:COL8,:COL9,:COL10;
END;
DECLARE C1 ASENSITIVE SCROLL CURSOR WITH ROWSET POSITIONING WITH HOLD FOR SELECTCOL1, COL2, COL3, COL4, COL5,COL6, COL7, COL8, COL9, COL10FROM TABLEWHERE COL2 < ‘ROWNNNNNNNNN’;
FETCH FIRST ROWSET FROM C1 FOR 100 ROWS INTO:COL1,:COL2,:COL3,:COL4,:COL5,:COL6,:COL7,:COL8,:COL9,:COL10;
DO I = 1 TO 499;FETCH NEXT ROWSET
C1 INTO:COL1,:COL2,:COL3,:COL4,:COL5,:COL6,:COL7,:COL8,:COL9,:COL10;
END;
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Test 3 - Multi-row FETCH using static or dynamic cursors –Single row vs. multi-row
Multi-row FETCH static
No great difference Since the 1 million row temporary table is built row by row, regardless of the fetch implementation.
Multi-row FETCH dynamic
Reducing the number of trips between the application and database engine by a factor of 100(50,000 fetches vs. 500 multi-fetches) accounts for the performance gains observed.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Test 4 - Single row vs. multi-row FETCH & UPDATE or DELETE
The summary of this test case is:•Use ISO (RS) as a bind parameter•These options protect data integrity (not for performance).•40 FETCHes followed by UPDATE on a rowset of 25 rows•40 FETCHes followed by DELETE on a rowset of 25 rows•Qualified 1 million rows at open cursors
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
DECLARE C1 SENSITIVE STATIC SCROLL CURSOR WITH ROWSET POSITIONING WITH HOLD FOR SELECTCOL1, COL2, COL3, COL4,COL5,COL6 FROM TABLEWHERE COL2 < ‘ROWNNNNNNNNN’FOR UPDATE OF COL6;
FETCH SENSITIVE FIRST ROWSET FROM C1 FOR 25 ROWS INTO:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;
UPDATE TABLE SET COL6 = :COL6+10 WHERE CURRENT OF C1;DO I = 1 TO 39;FETCH SENSITIVE NEXT ROWSET FROM C1 INTO
:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;UPDATE TABLE SET COL6 = :COL6 +10 WHERE CURRENT OF C1;END;(Same for Deletes)
DECLARE C1 SENSITIVE DYNAMIC SCROLL CURSOR WITH ROWSET POSITIONING WITH HOLD FOR SELECT
COL1, COL2, COL3, COL4, COL5,COL6 FROM TABLEWHERE COL2 < ‘ROWNNNNNNNNN’FOR UPDATE OF COL6;
FETCH SENSITIVE FIRST ROWSET FROM C1 FOR 25 ROWS INTO:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;
UPDATE TABLE SET COL6 = :COL6+10 WHERE CURRENT OF C1;DO I = 1 TO 39;FETCH SENSITIVE NEXT ROWSET FROM C1 INTO
:COL1,:COL2,:COL3,:COL4,:COL5,:COL6;UPDATE TABLE SET COL6 = :COL6 +10 WHERE CURRENT OF C1;END;(Same for Deletes)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Test 4 - Single row vs. multi-row FETCH & UPDATE or DELETE
Multi-row FETCH and UPDATE or DELETE dynamic
Multi-row FETCH and UPDATE or DELETE static
No significant changes in performance because of DTT build and population
17.8% performance improvement in DB2 class 2 CPU time (0.135 vs. 0.111) and a 7% performance improvement in DB2 class 2 elapsed time (0.589 vs. 0.547).
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Performance Considerations – Page 1 of 2
Choosing the right Cursor Type
–If you just want to blast out your data, choose forward only cursors
–If you want to maintain position, go back and forth - choose Scrollable Cursors
–If you don't care about the freshness of data, choose INSENSITIVE CURSORS
–If you want fresh some times, choose SENSITIVE on DECLARE and SENSITIVE or INSENSITIVE on FETCH
–If you want to see inserts and not deletes, choose DYNAMIC CURSORS
–If you only want to scroll only between the first few rows of the result set - use FIRST n ROWS
–Use stored procedures to OPEN in distributed environment if update not required
Choose the appropriate isolation level - usually CS (CURRENTDAT(NO))
–RR/RS provides low concurrency - may not be feasible
–Take advantage of optimistic locking (static only)
Provide sufficient declared TEMP database table space storage for STATIC and INSENSITIVE cursors
Commit as often as practical, use CURSOR HOLD
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Performance Considerations – Page 2 of 2The summary of the recommendations for static and dynamic cursors is:
•Static scrollable cursors can be the better solution if:– You need to scroll backwards to obtain initial values– You do not care about constant changes (such as business intelligence or representative samples).- Optimistic locking if more concurrency is required.
•Dynamic scrollable cursors can be preferable in situations where:– It is important for the application to access/see
updated/inserted rows– Performance is important
•Use multi-row operations whenever possible, particularly for the dynamic cursor model.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Cursor Attributes on PREPARE Statement EXEC SQL DECLARE mycursor
CURSOR FOR mystmt; EXEC SQL PREPARE mystmt
ATTRIBUTES :attrvarFROM :stmttxt;
EXEC SQL DESCRIBE mystmt INTO :mysqlda;
EXEC SQL OPEN mycursor; EXEC SQL FETCH FROM mycursor
USING DESCRIPTOR :mysqlda ;
Flexibility
Applications can pass a host variable containing a list of attributes, such as SCROLL, WITH HOLD, WITH RETURN, INSENSITIVE, SENSITIVE STATIC, optimize-clause, isolation-clause, etc.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
ODBC Scrollable Cursors Usage
DefineCursor Type–Determine which cursor types supported by driver
SQLGetInfo()SQL_CURSOR_SENSITIVITYSQL_SCROLL_OPTIONSSQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2SQL_KEYSET_CURSOR_ATTRIBUTES1SQL_KEYSET_CURSOR_ATTRIBUTES2SQL_STATIC_CURSOR_ATTRIBUTES1SQL_STATIC_CURSOR_ATTRIBUTES2SQL_DYNAMIC_CURSOR_ATTRIBUTES1 (Not in V7)SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 (Not in V7)
–Set Cursor Characteristic and Typee.g.. SQLSetStmtAttr SQL_ATTR_CURSOR_TYPE SQL_ATTR_CURSOR_STATIC
Specify Rowset Size–e.g.. SQLSetStmtAttr SQL_ATTR_ROW_ARRAY_SIZE ROWSET_SIZE
Fetch– e.g.. SQLFetchScroll SQL_FETCH_RELATIVE 5
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
ODBC and Scrollable Cursors
SQLFetchScroll(fetch orientation, offset)SQL_FETCH_NEXTSQL_FETCH_PRIORSQL_FETCH_FIRSTSQL_FETCH_LASTSQL_FETCH_ABSOLUTESQL_FETCH_RELATIVESQL_FETCH_BOOKMARK
SQLSetPos(rownumber, operation, locktype)SQL_POSITIONSQL_REFRESHSQL_UPATESQL_DELETESQL_ADD
SQLBulkOperations(operation)SQL_ADDSQL_UPDATE_BY_BOOKMARKSQL_DELETESQL_FETCH
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
JDBC Scrollable Cursors UsageMethod to get type of Result Set (which is like a cursor)
–int getType()TYPE_FORWARD_ONLYTYPE_SCROLL_INSENSITIVETYPE_SCROLL_SENSITIVE
Methods for Positioning –boolean next() –boolean previous() –boolean first()–boolean last()–boolean absolute()–boolean relative()–void afterLast()–void beforeFirst()
Methods for retrieving column values
–string getString(String columnName)
–int getInt(int columnIndex)–...
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
JDBC Scrollable Cursors Example
Connection con = DriverManager.getConnection("jdbc:my_subprotocol:my_subname");
con.setTransactionIsolation(TRANSACTION_READ_COMMITTED);
PreparedStatement pstmt = con.prepareStatement("SELECT EMP_NO, SALARY FROM EMPLOYEES
WHERE EMP_NO =?",ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
pstmt.setFetchSize(25);pstmt.setString(1,"1000010");boolean b = rs.beforeFirst();ResultSet rs3 = pstmt.executeQuery();
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Multi-row FETCH and INSERT
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Multi-Row FETCH and INSERTWhat is it? .....
–Multi-row FETCH:A single FETCH statement can retrieve multiple rows of data from the
result table of a query as a rowset – A rowset is a group of rows of data that are grouped together and operated on as a set
–Supports dynamic and static SQL (Fetch always static)–Multi-row INSERT:
A single SQL statement can insert one or more rows into a table or viewMulti-row INSERT can be implemented as either static or dynamic SQL
Benefits .....–Enhances usability and power of SQL–Performance is improved by eliminating multiple trips between application and database engine; for distributed access, reducednetwork traffic
–Combined with scrollable cursors important for browse applications
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
RowsetsA ROWSET is a group of rows from the result table of a query, which are returned by a single FETCH statement (or inserted by a single (multi-row) INSERT statement)
•The program controls how many rows are returned in a rowset (it controls the size of the rowset)
–Can be specified on the FETCH ... FOR n ROWS statement (n is the rowset size and can be up to 32767)
Each group of rows are operated on as a rowset
•Ability to intertwine single row and multiple row fetches for a multi-fetch cursor
FETCH FIRST ROWSET STARTING AT ABSOLUTE 10 FROM CURS1 FOR 6 ROWS INTO :hva1, :hva2;
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
DECLARE CURSOR
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
FETCH examplesEXAMPLE 1:Fetch the previous rowset and have the cursor positioned on that rowset
EXEC SQL FETCH PRIOR ROWSET FROM C1 FOR 3 ROWS INTO...
-- OR --EXEC SQL
FETCH ROWSET STARTING AT RELATIVE -3 FROM C1 FOR 3 ROWS INTO...
EXAMPLE 2:Fetch 3 rows starting with row 20 regardless of the current position of the cursor
EXEC SQL FETCH ROWSET STARTING AT ABSOLUTE 20
FROM C1 FOR 3 ROWS INTO...
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
DECLARE CURSOR - Example
Declare C1 as the cursor of a query to retrieve a rowset from the table DEPT.
The prepared statement is MYCURSOR
EXEC SQL DECLARE CURSOR C1 CURSORWITH ROWSET POSITIONINGFOR MYCURSOR;
Rowset positioning specifies whether multiple rows of data can be accessed as a rowset on a single FETCH statement –default is WITHOUT ROWSET POSITIONING
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Distributed Multiple Row Fetch FlowApplicationC1 C2
Client Com-Buffer
IntermediateBuffer
Table Page
ServerCom-Buffer
DiagnosticInfo
SQLCA DiagnosticInfo
DiagnosticInfo
Limited Block Fetch FlowApplicationC1 C2
Client Com-Buffer
IntermediateBuffer
Table Page
ServerCom-Buffer
DiagnosticInfo Diag Info Diag Info
SQLCA
SQLCA
SQLCA
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Local FETCH Flow
1900170013001204
0000
1900170013001204 … …
SQLDAID = SQLDASQLDABC = 104SQLN = 2SQLD = 2SQLTYPE[1] = 496SQLLEN[1] = 4 SQLDATA[1] = x00001000SQLIND[1] = x00002000SQLNAME[1] = x‘0008000000010004’
x1000 x2000 Internal Buffers ‘N’ Table
4
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
MRF Performance Considerations• Up to 50% faster FETCH performance
Performance improvement largely due to savings of API costsPerformance variable based on • Number of rows fetched• Number of columns fetched• Class 2 accounting (on or off) – savings larger if Class 2 is on
• Examples– DSNTEP4– 35% improvement on FETCH of 1000 rows with 5 cols and
20 cols– DSNTIAUL– 50% improvement on FETCH of 10000 rows with 5 cols and
20 cols• Up to 50% reduction in CPU cost for LBF –vs- V7
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Different Forms of INSERTƒINSERT via VALUES is used to insert a single row into the table or
view using values provided or referencedƒINSERT via SELECT is used to insert one or more rows into table or
view using values from other tables or viewsƒINSERT via VALUES… FOR "n" ROWS form is used to insert multiple
rows into table or view using values provided in host variable array
FOR "n" ROWSƒFor static, specify FOR "n" ROWS on INSERT statement
(for dynamic INSERT, you may also specify FOR "n" ROWS on EXECUTE statement)
ƒMaximum value of n is 32767 specified as host-variable, parameter marker, or literal value
ƒInput provided with literal, host variable, or host variable array --each array represents cells for multiple rows of a single column
VALUES… FOR “n” ROWS clause allows specification of multiple rows of
data ƒHost variable arrays used to provide values for a column on INSERT ƒExample: VALUES (:hva1, :hva2) FOR 10 ROWS
Multiple Row INSERT
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Host Variable ArraysHost variable array is an array in which each element of the array contains a value for the same column
Changes have been made to allow host variable arrays in:ƒCOBOLƒPL/1ƒC++ƒNOTE: Assembler support is limited to cases where
USING DESCRIPTOR is allowed. Assembler pre-compiler does not recognize declaration of host variable arrays. The programmer is responsible for allocating storage correctly, etc.
Can only be referenced in multi-row fetch or insertIn general, arrays may not be arrays of structures
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
COBOL
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Example 1: Declare a CURSOR C1 and fetch 10 rows using a multi-row FETCH statement
01 OUTPUT-VARS.05 NAME OCCURS 10 TIMES.
49 NAME-LEN PIC S9(4)COMP-4 SY C.49 NAME-DATA PIC X(40).
05 SERIAL-NUMBER PIC S9(9)COMP-4 OCCURS 10 TIMES.
PROCEDURE DIVISION.
EXEC SQLDECLARE C1 CURSOR WITH ROWSET POSITIONING FORSELECT NAME, SERIAL# FROM CORPORATE.EMPLOYEE END-EXEC.
EXEC SQLOPEN C1 END-EXEC.
EXEC SQLFETCH FIRST ROWSET FROM C1 FOR 10 ROWS INTO :NAME,
:SERIAL-NUMBER END-EXEC.
COBOL
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
PL/I
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
PL/1
Example 2: You can retrieve 10 rows from the table CORPDATA.DEPARTMENT with:
DCL DEPTNO(10) CHAR(3),DEPTNAME(10) CHAR(29) VAR,MGRNO(10) CHAR(6),ADMRDEPT(10) CHAR(3);
DCL IND_ARRAY1(10)BIN FIXED(15);DCL IND_ARRAY2(10)BIN FIXED(15);...EXEC SQL
DECLARE C1 CURSOR WITH ROWSET POSITIONING FORSELECT * FROM CORPDATA.DEPARTMENT;
...EXEC SQL
FETCH FIRST ROWSET FROM C1 FOR 10 ROWS INTO:DEPTNO :IND_ARRAY1,:DEPTNAME :IND_ARRAY2,:MGRNO :IND_ARRAY3,:ADMRDEPT :IND_ARRAY4;
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
C/C++
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
C++
Example 3: Declare an integer and varying character array to holdcolumns retrieved from a multi-row fetch statement
long serial_num(10);struct {
short len;char data [18];}name [10];
...EXEC SQL
DECLARE C1 CURSOR FOR SELECT NAME, SERIAL#FROM CORPDATA.EMPLOYEE WITH ROWSET POSITIONING;
...EXEC SQL OPEN C1;EXEC SQL
FETCH FIRST ROWSET FROM C1 FOR 10 ROWS INTO :NAME,:SERIAL_NUM;
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
ODBC#define TC 10;SQLWCHAR SAVE_H1WCHR[TC][1025];SQLINTEGER LNSAVE_H1WCHR[TC];/* Main Program */int main(){/* initialize data */wcscpy(SAVE_H1WCHR[0], (SQLWCHAR *)"abc 1");...
wcscpy(SAVE_H1WCHR[9], (SQLWCHAR *)“abc 10");
hstmt=0;
rc=SQLAllocStmt(hdbc, &hstmt);
rc=SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_DBCLOB1024, 0, SAVE_H1WCHR, (SQLINTEGER) 2050, (SQLINTEGER *) LNSAVE_H1WCHR);
/* Set number of rows to insert */rc=SQLParamOptions(hstmt, TC, NULL);
/* Insert rows into DBCLOB column via SQLBindParameter */rc=SQLPrepareW(hstmt,(wchar_t *)
"INSERT INTO TABLECU (C1) VALUES (?)",SQL_NTS);
rc=SQLExecute(hstmt);rc=SQLTransact(henv, hdbc, SQL_COMMIT);
} /* End Main */
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
JDBCtry {
stmt = con.prepareStatement ("insert into T1 values (?, ?)");stmt.setInt (1, 1);stmt.setInt (2, 1);stmt.addBatch();stmt.setInt (1, 2);stmt.setInt (2, 2);stmt.addBatch();stmt.setInt (1, 3);stmt.setInt (2, 3);stmt.addBatch();
int[] updateCount = stmt.executeBatch();
for (int i = 0; i < updateCount.length; i++)actualResults.println(UpdateCount[" + i + "] = " + updateCount[i]);
stmt.clearBatch();con.commit();stmt.close();
}
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Different Forms of INSERTƒINSERT via VALUES is used to insert a single row into the table or
view using values provided or referencedƒINSERT via SELECT is used to insert one or more rows into table or
view using values from other tables or viewsƒINSERT via VALUES… FOR "n" ROWS form is used to insert multiple
rows into table or view using values provided in host variable array
FOR "n" ROWSƒFor static, specify FOR "n" ROWS on INSERT statement
(for dynamic INSERT, you may also specify FOR "n" ROWS on EXECUTE statement)
ƒMaximum value of n is 32767 specified as host-variable, parameter marker, or literal value
ƒInput provided with literal, host variable, or host variable array --each array represents cells for multiple rows of a single column
VALUES… FOR “n” ROWS clause allows specification of multiple rows of
data ƒHost variable arrays used to provide values for a column on INSERT ƒExample: VALUES (:hva1, :hva2) FOR 10 ROWS
Multiple Row INSERT
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
INSERT
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
INSERT (cont)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
INSERT Example 1
Insert a variable number of rows using host variable arrays for columnvalues. Assume that the table T1 has one column and that a variable(:hv) number of rows of data are to be inserted into T1 table.
EXEC SQL INSERT INTO T1VALUES (:hva :hvind) FOR :hv ROWSATOMIC;
In this example, :hva represents the host variable array and :hvind represents the array of indicator variables
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
INSERT Example 2Insert 10 rows into a table T2, and return the rows that have been inserted using a multiple row fetch statement.
DECLARE CS1 ASENSITIVE SCROLL CURSOR WITH RETURN WITH ROWSET POSITIONING FOR SELECT T2.C1, T2.C2 FROM FINAL TABLE
(INSERT INTO T2 VALUES (:hvai1 :hvindi1, :hva2 :hvinid2) FOR 10 ROWS);
EXEC SQL OPEN CS1; /* INSERT OCCURS HERE */EXEC SQL FETCH FIRST ROWSET FROM CS1
FOR 10 ROWS INTO :hvao1 :hvindo1, :hvao2 :hvindo2
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Assume that table T3 has two columns: C1 (SMALLINT) and C2(INTEGER)The application allocates two arrays, :hva1 with 5 elements, and :hva2 with 10 elements
:hva1 :hva2
INSERT INTO T3 (C1, C2) VALUES (:hva1, :hva2) FOR 5 ROWS;
INSERT Example 3
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Assume that table T3 has three columns: S1 SMALLINT, I1 INTEGER, and T1 CHAR(8)The application allocates one array, :hva2 with 10 elements. :hv1 is a scalar host variable and the value for T1 is a special register In this example, hv1, and CURRENT TIME are used for each row of data, the values for I1 are obtained from host-variable-array :hva2
:hv1 :hva2
INSERT INTO T3 VALUES (:hv1, :hva2,CURRENT TIME) FOR 10 ROWS -- Assume CURRENT TIME = ’ 13:30:05’
INSERT Example 4
T1I1S1
13:30:0510513:30:059513:30:058513:30:057513:30:056513:30:055513:30:054513:30:053513:30:052513:30:0515
5 12345678910
Result of Insert
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Local INSERT Flow
1900170013001204
0000
1900170013001204 … …
SQLDAID = SQLDASQLDABC = 104SQLN = 2SQLD = 2SQLTYPE[1] = 496 SQLTYPE[2] = 496SQLLEN[1] = 4 SQLLEN[2] = 4SQLDATA[1] = x00001000 SQLDATA[2] = x00003000SQLIND[1] = x00002000 SQLIND[2] = x00000000SQLNAME[1] = x‘0008000000010004’ SQLNAME[2] =x‘0008000000020000’
x1000 x2000 Internal Buffers
4
Table
4
x3000
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Distributed Multiple Row INSERT Flow
ApplicationC1 C2
Client Com-Buffer
IntermediateBuffer
Table Page
ServerCom-Buffer
Distributed Chained INSERT FlowApplicationStmt Data
Client Com-Buffer
IntermediateBuffer
Table Page
ServerCom-Buffer
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
ATOMIC -vs- NOT ATOMICATOMICƒTraditional behaviorƒAll rows being inserted must successfully be inserted. If the insert for any row fails, all changes made to database by that INSERT statement are undone.
NOT ATOMIC CONTINUE ON SQLEXCEPTIONƒInsert rows that are successfulƒReject rows that are not successful
GET DIAGNOSTICS can be used to determine which rows were not successful
ƒSQLCODE will indicate if all failed, all were successful or at least one failed
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
NOT ATOMIC CONTINUE ON SQLEXCEPTION – GET DIAGNOSTICS
• NOT ATOMIC CONTINUE ON SQLEXCEPTION– Diagnostics are available for each failed row
through GET DIAGNOSTICS– SQLCODE indicates if:
• All failed– SQLSTATE 22530, SQLCODE -254
• All were successful, but warnings– SQLSTATE 01659, SQLCODE +252
• At least one failed– SQLSTATE 22529, SQLCODE -253
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
ATOMIC -vs- NOT ATOMIC with Triggers•Trigger Behavior on Multiple Row Insert
•ATOMIC•The inserts are processed as a single statement. •Any statement level triggers fire once for the statement, and the transition tables will include all of the rows that were inserted.
•NOT ATOMIC CONTINUE ON SQLEXCEPTION•Inserts are processed separately. •Any statement level triggers are processed for each row that is inserted•Transition tables include the individual row that is inserted. •When errors are encountered with this option in effect, processing continues, and some of the specified rows will not beinserted.
•In this case, if an insert trigger is defined on the underlying base table, the trigger transition table will only include rows that were successfully inserted.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
PREPARE
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
EXECUTE
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
PREPARE and EXECUTE - ExampleAssume that the prog table has 9 columns. Prepare and execute a dynamicINSERT statement which inserts 5 rows of data into the prog table.
stmt = 'INSERT INTO prog (iwhid, updated_by, update_ts, name, short_description,orderNo, parmData, parmDataLong, VWProgKey)
VALUES (?,?,?,?,?,?,?,?,?)';
attrvar = ’FOR MULTIPLE ROWS ’;NROWS = 5;
EXEC SQL PREPARE ins_stmt ATTRIBUTES :attrvar FROM :stmt;
EXEC SQL EXECUTE ins_stmt FOR :NROWS ROWSUSING :V1,:V2,:V3,:V4,:V5,:V6,:V7,:V8,:V9;
In this example, each host variable in the USING clause represents an array of values for the corresponding column of the target of the INSERT statement.
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
SQLDA must contain a valid description of the host variable arrays or buffers which contain the values to be insertedƒEach SQLVAR describes a host variable or host variable
array which represents a buffer which contains value(s) for a column of target table
ƒSQLDA must have enough storage to contain SQLVAR for each target column for which values are provided, plus an additional SQLVAR entry for use by DB2 for z/OS
ƒPrior to the multi-row insert, the SQLDA fields must be set correctly to include number of SQLVAR occurrences, number of variables used, pointer to arrays, indicator variables etc.
INSERT SQLDA Considerations
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
MRI Performance Considerations• Up to 30% faster INSERT performance
Performance improvement largely due to savings of API costsSavings flattens out quickly, for example, savings (as a percentage) was equal • For 100 Rows, 500 Rows, 1000 Rows…• Reasonable “n” for MRI is about 200 – no additional savings above that, and downside (rollback)
increases.
Distributed MRI performance up to 70% Elapsed Time and 50% Server CPU time reductions seenPerformance variable based on • Number of rows INSERTed• Number of columns INSERTed• Number of INDEXes on table• Class 2 accounting (on or off) – savings larger if Class 2 is on
Note: Don’t use MRI to INSERT 1 row due to overhead to set up for MRI
Similar improvement with UPDATE and DELETE WHERE CURRENT OF when updating/deleting the entire rowset. This is in addition to the savings provided by MRF
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Multi-row FETCH / INSERT -- DRDA Considerations
Can be implemented by any requester or server that supports DRDA Version 3
Between DB2 for z/OS V8 systems–Multi-row INSERT does not affect blocking a single rowset is inserted in a single INSERT statement
–For remote client one rowset returned in a network request32K block size is ignored
–A single network multi-row fetch or insert request can maximum be 10 MB
Between DB2 on distributed platforms and DB2 for z/OS V8–No support for multi-row operations in embedded SQL–In ODBC/CLI driver
Limited support for multi-row FETCHSupport for multi-row INSERT
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Positioned DELETE
Positioned Update
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
GET DIAGNOSTICS
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
GET DIAGNOSTICS statement Enables more diagnostic information to be returned than can be contained in SQLCA
Returns SQL error information–for overall statement
–for each condition (when multiple conditions occur)
Supports SQL error message tokens greater than 70 bytes (SQLCA limitation)
Must be embedded - cannot be dynamically prepared
INSERT INTO T1 FOR 5 ROWS VALUES (:array);GET DIAGNOSTICS :errcount = NUMBER;
DO || = 1 TO ERR_COUNT;GET DIAGNOSTICS FOR CONDITION :||
:rc = RETURNED_SQLSTATE;END;
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
GET DIAGNOSTICS Examples
To determine how many rows were updated in an UPDATE statement
– GET DIAGNOSTICS :rcount = ROW_COUNT;
To handle multiple SQL errors during a NOT ATOMIC multi-row insert
–GET DIAGNOSTICS :numerrors = NUMBER;
–Then code a loop to execute the following for the number of errors
GET DIAGNOSTICS CONDITION :i :retstate = RETURNED_SQLSTATE
To see all diagnostic information for a SQL statement
–GET DIAGNOSTICS :diags = ALL STATEMENT
–Sample output in :diags
Number=1; Returned_SQLSTATE=02000; DB2_RETURNED_SQLCODE=+100;Would continue for all applicable items and for all conditionsItems are delimited by semicolons
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
INSERT within SELECT Statement
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
INSERT within SELECT statement
What is it? .....–Users can automatically retrieve column values inserted in tables by DB2 such as:
Identity columns, sequence valuesUser-defined defaults, expressionsColumns modified by BEFORE INSERT triggersROWIDs
Benefits .....–Enhances usability and power of SQL
–Cuts down on network cost in application programs
–Cuts down on procedural logic in stored procedures
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
INSERT within SELECT Examples
DECLARE CS1 CURSOR FORSELECT EMP_ROWIDFROM FINAL TABLE(INSERT INTO DSN8810.EMP_PHOTO_RESUME (EMPNO)
SELECT EMPNO FROM DSN8810.EMP));
SELECT PROJNAME INTO :name_hvFROM FINAL TABLE(INSERT INTO DSN8810.PROJ (PROJNO,DEPTNO,RESPEMP)
VALUES(:projno_hv,:deptno_hv,:respemp_hv));
ROWID NOT NULL
GENERATED ALWAYS
NOT NULL WITH DEFAULT 'PROJECT NAME UNDEFINED'
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
INSERT within SELECT - Ordering Example
DECLARE CS2 CURSOR WITH ROWSET POSITIONING FORSELECT EMPNOFROM FINAL TABLE(INSERT INTO EMPLOYEE (NAME, TELE)
VALUES(:HVA1, :HVA2))ORDER BY INPUT SEQUENCE;
INTEGER GENERATED ALWAYS AS
IDENTITY
HVA1 HVA2Liz 555-1212David 555-9876Jessica 555-0110
EMPNO123
Input
Result
CREATE TABLE EMPLOYEE(EMPNO INTEGER GENERATED ALWAYS AS IDENTITY,.....
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Trigger example
CREATE TRIGGER TRIG1NO CASCADE BEFORE INSERT ON EMPLOYEEREFERENCING NEW AS NEWSALARYFOR EACH ROW MODE DB2SQLWHEN (NEWSALARY.LEVEL = 'Associate')SET NEWSALARY.SALARY = NEWSALARY.SALARY + 5000.00
SELECT NAME,SALARY INTO :name_hv, :salary_hvFROM FINAL TABLE(INSERT INTO EMPLOYEE(NAME,SALARY,LEVEL)
VALUES('New Hire',35000.00,'Associate'))
:name_hv = 'New Hire'
:salary_hv = 40000.00
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Result table from INSERT statement
Result table is internal work file -- not temporary table
Contains all of the rows inserted, includes all of the columns requested in the SELECT list
–After any BEFORE triggers
–Generated columns (identity, ROWID, columns based on expressions)
–After enforcing constraints (check, unique index, referential integrity)
–Before any AFTER triggers
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Using WITH HOLD Option
Using WITH HOLD option on cursor–Example: user declares cursor, opens cursor, fetches 2 rows, performs commit, then fetches 3rd row successfully
DECLARE CS1 CURSOR WITH HOLD FORSELECT EMP_ROWID FROM FINAL TABLE
(INSERT INTO DSN881.EMP_PHOTO_RESUME(EMPNO)SELECT EMPNO FROM DSN881.EMP);
OPEN CS1; <------------------- inserts 5 rowsFETCH FROM CS1 INTO :hv1; <------------------ receives row id for 1st rowFETCH FROM CS1 INTO ::hv2; <------------------ receives row id for 2nd rowCOMMIT; <------------------ all 5 inserts are committedFETCH FROM CS1 INTO : HV3; <------------------ receives row id for 3rd row
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Other considerations
CREATE VIEW VW1 AS SELECT I1 FROM T1WHERE I1 > 10WITH CASCADED CHECK OPTION;
Example:
Only scrollable cursors defined as INSENSITIVE are valid–If defined as ASENSITIVE a warning is returned indicating that it is being treated as INSENSITIVE
– If SENSITIVE DYNAMIC or SENSITIVE STATIC specified, an error is returned
Views must be defined WITH CASCADED CHECK OPTION if WHERE clause is used in view definition
COMMIT–All changes made by INSERT (including those embedded in OPEN CURSORS) and SELECT INTO containing INSERT executed during unit of recovery are committed and savepoints that were set with unit of recovery are released
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Using SAVEPOINT and ROLLBACKIf application sets a save point prior to opening cursor and then rolls back to that savepoint, all inserts are undone
Example:
DECLARE CS2 CURSOR FOR SELECT EMP_ROWID FROM FINAL TABLE
(INSERT INTO DSN881.EMP_PHOTO_RESUME(EMPNO)SELECT EMPNO FROM DSN881.EMP);
SAVEPOINT A ON ROLLBACK RETAIN CURSORS; <--- sets 1st savepointOPEN CS2; <--- inserts the rowsSAVEPOINT B ON ROLLBACK RETAIN CURSORS; <--- sets 2nd savepoint...ROLLBACK TO SAVEPOINT B; <--- rows still exist in table
DSN881.EMP_PHOTO_RESUMEROLLBACK TO SAVEPOINT A; <--- all inserted rows are undone
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Interaction with other statements and clauses
FETCH FIRST clause
–Does not affect which rows are inserted
–All of the rows from the INSERT statement will be inserted into the target object
–The result table will only contain those rows for which the FETCH FIRST clause satisfies
•DECLARE CURSOR–The cursor will be read-only
•OPEN CURSOR–SQLERRD3 will be set to reflect the effects of the INSERT statement (number of rows inserted)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Interaction with other V8 features
Multiple CCSID Sets per SQL StatementExample:DECLARE CS1 CURSOR FORSELECT C1FROM FINAL TABLE(INSERT INTO EBCDIC_T1 SELECT C2 FROM ASCII_T1);
ASCII data is selected and converted into
EBCDIC data
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
EXPLAIN output
Example:SELECT EMPNO INTO :HV1FROM FINAL TABLE(INSERT INTO EMPLOYEE (NAME, SALARY,LEVEL)VALUES('The New Guy', 50000.00, 'Staff'));
QBLOCK_TYPE
QBLOCKNO PLANNO ACCESSTYPE TABLE_TYPE
SELECT 1 1 V BINSERT 2 0
–New Information Stored in Plan Table–ACCESSTYPE -- V indicates that buffers will be used for singleton INSERT VALUES clause for INSERT within SELECT
–TABLE_TYPE -- B indicates buffers will be used
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Identity Column Enhancements
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Identity column What's new? .....
–Identity column introduced in Version 6Automatically generated by DB2Unique, sequential, recoverable values Useful for generating unique primary key values
–in Version 8, ALTER TABLE statement is extended to include identity column specifications to allow modifying the attributes of an existing identity column
Benefits .....–Better performance and concurrency than application generated counters
–Guaranteed uniqueness both within an individual subsystem and a data sharing group
–Recoverability in the event of a DB2 system failure
–Failure of one data sharing member will not impact the other members from generating key values
–Simple implementation which is internal to DB2
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Identity column -- Version 8 enhancements
Dynamic alter of identity column attributes–ALTER TABLE . . . ALTER COLUMN extended to:
Enable modification of identity column attributes, andSpecify continuation of the sequence associated with identity column from a new point in the range of values that is different from where the column values would otherwise have continued
–Only future values of column affected by change
–Cannot alter data type of identity column
–Unused cache values may be lost when column attributes are altered
New keyword support to aid porting from other vendor platforms–NO MINVALUE
–NO MAXVALUE
–NO ORDER, ORDER
Allows:– INCREMENT BY to be 0
– MINVALUE = MAXVALUE
Prevent loss of unused cache values at end of LOAD for identity column
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Identity column -- considerationsBefore Version 8, if you had a requirement to unload and reload your tables, you were forced to specify GENERATED BY DEFAULT for the identity column
–If you had specified GENERATED ALWAYS at table design, the only option to unload / reload would be to:
Unload the tableDROP the tableRe-CREATE the table using GENERATED BY DEFAULTReload the table
–Otherwise, DB2 will generate new values for the rows during the reload, which is probably not what you want
With Version 8, if you specify GENERATED ALWAYS and later have arequirement to unload / reload your tables, you could:
– ALTER TABLE . . . ALTER COLUMN . . . SET GENERATED BY DEFAULT
–Unload the table
–Reload the table
–ALTER TABLE . . . ALTER COLUMN . . . SET GENERATED ALWAYS
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Sequence Objects
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Sequence objectsWhat is it? .....
–A way for applications to have the DBMS generate unique numeric key values and to coordinate keys across multiple rows and tables
–Sequence object:User-defined object that generates a sequence of numeric valuesStand-alone object -- NOT TIED TO A TABLE Generated values returned to user -- can be used for anything by user
–DB2 does not wait for transaction that has incremented a sequence to commit before allowing the sequence to be incremented again by another transaction
Benefits .....–Better performance and concurrency than application generated counters
–Guaranteed uniqueness
–Recoverability in the event of a DB2 system failure
–Can be shared across members of data sharing group
–Failure of one data sharing member will not impact the other members from generating key values
–Family compatibility and porting of applications from other vendor platforms
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Problems with application generated sequence numbers
Common application-level implementation is to maintain a one row table that contains the sequence number
–Each transaction locks this table, increments the number, commits (that is, one transaction at a time can increment the sequence number)
–OR a variation of this theme is to use SELECT MAX( ) + 1...WITH RR followed by INSERT using retrieved key
–Problem:Page containing counter constitutes hot spot in data base resulting in unpredictable transaction delays caused by inter-system P-lock negotiation for that page and by buffer invalidation and refresh.Contention inhibits transaction throughput and application processing powerIf one member fails, retained locks held by failed member can prevent access to shared counter from surviving members
Identity columns provide a partial solution
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Sequence Objects solutionAvoid the concurrency and performance problems that can
result when user applications generate their own sequence numbers (i.e., hotspots)
•DB2 sequences allow multiple transactions to concurrently increment sequence number and guarantee each number will be unique
•Sequence can be accessed and incremented by many users without waiting
–DB2 does not wait for a transaction that has incremented a sequence to commit before allowing the sequence to be incremented again by another transaction
Failure of one DB2 member in group will never prevent access (R/W) to sequence from surviving members
–No retained locks to prevent access to sequence
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Sequence objects vs. identity columns
Sequences Identity columns
Stand-alone object Tied to a table
Can use one sequence for many tables or many sequences in one table
One to one relationship between identity and tables
Retrieved via NEXT VALUE FOR / PREVIOUS VALUE FOR expressions
Retrieved via IDENTITY_VAL_LOCAL function -- within agents scope only
Can be altered via ALTER SEQUENCE Can be altered via ALTER TABLE (ALTER COLUMN)Prior to V8 could not be altered
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
SQL to Support Sequence ObjectsCREATE SEQUENCE
–Creates a sequence at the application server–Can be embedded in application program or used interactively
ALTER SEQUENCE –Can be used to change INCREMENT BY, MIN VALUE, MAXVALUE, CACHE, CYCLE and to RESTART WITH different sequence
–Only future values affected and only after COMMIT of ALTER–Cannot alter data type of sequence–Unused cache values may be lost
DROP SEQUENCE
COMMENT ON SEQUENCE
GRANT / REVOKE ON SEQUENCE
NEXT VALUE FOR and PREVIOUS VALUE FOR
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Next and Previous ValuesApplications can refer to the named sequence object to get its current or next value
–NEXT VALUE FOR < sequence-name >
–PREVIOUS VALUE FOR < sequence-name >Returns most recently generated value for sequence for previous statement within current
sessionNEXT VALUE must have been invoked within current session
Can be invoked during:–SELECT statement or SELECT INTO statement within select-clause (except if statement contains DISTINCT or UNION keyword, GROUP BY or ORDER BY)
–INSERT statement within VALUES clause
–INSERT statement within select-clause of fullselect
–Update statement within SET clause (except NEXT VALUE cannot be in select-clause of fullselect of expression)
–VALUES or VALUES INTO statement (except within select-clause of fullselect of expression)
–CREATE PROCEDURE, FUNCTION, TRIGGER
–Set :hv = NEXT VALUE FOR sequence
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Ranges and CyclesSequence can be optionally defined to CYCLE after reaching it's maximum value (or minimum if descending)
–Sequence will wrap around to other end of range and start new cycle of values
–Default is NOCYCLE
First cycle always starts with START WITH value but all subsequent cycles start with MINVALUE (asc sequence) or MAXVALUE (desc sequence)
If NO CYCLE in effect, sequence value generation will stop when sequence reaches end of logical range of values
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Duplicate SequencesSequences are guaranteed to be unique within a cycle
However, duplicates can occur if :–Sequence cycles while data from previous cycles still exist
–Sequence is restarted with a value that has already been generated
–Ascending/descending direction of sequence is reversed by ALTER statement (i.e., changing INCREMENT BY from positive to negativenumber, vice versa)
–System crashes followed by COLD START or CONDITIONAL RESTART and skips forward recovery leaving SYSIBM.SYSSEQUENCES table in inconsistent state
–A point-in-time recovery of SYSIBM.SYSSEQ table space regresses SYSIBM.SYSSEQUENCES table to point in time, causing MAXASSIGNEDVAL to become inconsistent with actual current point of the sequence
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Caching sequence numbersCACHE option allows DB2 to cache preallocated values in memory for fast access
–Reduces synchronous I/O to the catalog table SYSIBM.SYSSEQUENCES–I/O to table only required when cached values are exhausted
Recommended value is 20–Assigning a higher value gives no benefit and increases size of gap should a failure occur
In data sharing, each member will have its own set of cached values for a single sequence
–Numbers will not be allocated in sequence
Use NOCACHE if values must be assigned in strict numeric order
–Each assignment of sequence value results in update of Catalog
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Data sharing example
DB2A DB2B
NAME VALUE CACHESEQ1 41 20
SYSIBM.SYSSEQUENCES
1-20 in cacheOnce 20 is used requests another 20
21-40 in cacheIf member fails 61-80 will be cached on NEXTVAL(Maximum of 20 values will be lost)
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Sequences and gapsGaps are possible if:
–Transaction advances sequence and then rolls back–SQL statement leading to generation of next value fails after value generated–NEXTVAL used in SELECT statement of cursor in DRDA where client uses block-fetch and not all retrieved rows are FETCHed
–Sequence or identity column associated with sequence is altered and then ALTER rolled back
–Sequence or identity column table DROPped and then DROP rolled back–SYSIBM.SYSSEQ tablespace is stopped, leading to loss of unused cache values–DB2 system failure or shut-down leading to loss of unassigned cache values lost causing gap in sequence
Note that a transaction incrementing a sequence twice may not be assigned consecutive values
Big gaps could be removed by Altering sequence using RESTART WITH parameter
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Recoverability of sequences
If DB2 fails, sequence status is recovered from catalog and logs, thereby guaranteeing unique sequence values continue to be generated
Unassigned sequence values kept in cache of failing members are lost–With efficient use of sequence, gaps can be minimized
DB2 may generate duplicate sequence numbers after restart if no log records are processed in forward recovery
If there is a gap between first value assigned before system crash and value assigned after system crash
–ALTER sequence to RESTART WITH value that is next value in sequence to be assigned
–DROP and then reCREATE sequence specifying a START WITH value that is next value in sequence to be assigned
–SELECT MAX(colname) or SELECT MIN(colname) may give actual last assigned value (colname is column to which sequence numbers were being assigned) -- works only if every value generated goes into one table --won't work if CYCLE used
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Sequence Objects -- Catalog and DirectorySYSIBM.SYSSEQ tablespace
– SYSIBM.SYSSEQUENCES --Records all data about SEQUENCE attributesMAXASSIGNEDVAL column -- last possible assigned valueNew columns:
–PRECISION -- Precision of sequence object's decimal or other numeric data type
–RESTART WITH -- RESTART WITH numeric constant value specified during ALTER of the sequence or NULL
SYSIBM.SYSSEQ2 tablespace– SYSIBM.SYSSEQUENCESDEP
New Column:–DTYPE–BSCHEMA / BNAME
–SYSIBM.SYSSEQUENCEAUTH NEW TABLE
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
CURRENT PACKAGE PATH Special Register
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
CURRENT PACKAGE PATH special registerWhat is it? .....
–CURRENT PACKAGE PATH special register:Used for package collection resolutionMeans for application to specify a list of package collections to DB server (similar to PKLIST)DB server (rather than application requester) can search through list and find first package that exists with specified package nameControl for applications that do not run under a DB2 plan
Benefits .....–Reduce network traffic and improve CPU/elapsed time for application using DRDA from a z/OS requester
–Allows nested procedure, user-defined function to be implemented without concern for invoker's runtime environment and allows multiple collections to be specified
–Easier to switch to / from JDBC and SQLJ
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Package Resolution today
Given that multiple collections can be used for packages, how is package resolution managed today?...
– CURRENT PACKAGESET special register Set to single collection id to indicate any package to be invoked belongs to that collectionApplication must issue SET CURRENT PACKAGESET before each package is invoked if collection for the package is different from previous package
–BIND PLAN PKLISTAbility to specify list of collection ids for packages for local OS/390 applications that use plans at execution time
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Package Resolution - SQLJWhat about SQLJ?...
–Requirement SQLJ increases need for package switching and versioningWith SQLJ, people bind multiple packages for the same thing each with different bind options (i.e., different ISOs)People want to be able to switch between different versions of package depending on what has been implemented at server (i.e., different qualifiers)
–Before Version 8Application does not know which one to use so has to issue multiple SET CURRENT PACKAGE SETS and retry until it finds the right one -- laborious and time consuming
–With Version 8New CURRENT PACKAGE PATH special register allows list of packagecollections to be specified, which results in reduction in network traffic and CPU where applications use DB2 for z/OS as requesterAlso helps with stored procedures and UDF's and with versioningTo execute statement, requester must specify new DRDA flowSpecial register is 4K (4096), separate collections with commas -- no checks are made until runtime so ensure they are spelled correctly
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Package Resolution - DRDAWhat about remote clients connected via DRDA...
Before Version 8
PKLIST bind option allows them to search package collections at runtime
–PKLIST is a requester function -- remote server doesn't know value set for PKLIST because it is part of PLAN and only packages are used at remote server
–Message sent to server requesting package with first collection from PKLIST; if results in SQLCODE -805, another message sent requesting package with next collection in PKLIST
–With Version 8New CURRENT PACKAGE PATH special register means
crossing network only once to resolve package collection id at server, instead of crossing once per collection id to perform resolution at client
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Package Resolution - proceduresWhat about procedures and user-defined functions?
–Before Version 8Users cannot identify package resolution schemes independent from rules established by caller's planSET CURRENT PACKAGESET or COLLID option for routine can be used within a procedure or function to change package resolution rule from invokers, but can only specify one package collection at a time
–With Version 8New CURRENT PACKAGE PATH special register allows nested procedure, user-defined function to be implemented without concern for invoker's runtime environment and allows multiple collections to be specified
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Local application (CICS, IMS, TSO, batch, etc.)with static SQL
Package resolution today -- local application
PROGA
...SELECT col1 ......
BIND PLAN plana PKLIST
( MAINT_COLLECT.*,PROD_COLLECT.*,TEST_COLLECT.* )
DB2
Plan / Package
MAINT_COLLECT.PROGA
PROD_COLLECT.PROGA
TEST_COLLECT.PROGADB2 packagesearch
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
DRDA clientSET CURRENT PACKAGESETat server
DB2 for z/OS server(through DDF) -- no plan with PKLIST
Package resolution today -- remote DRDA server
SET CURRENT PACKAGESET = 'MAINT_COLLECT'
Search for MAINT_COLLECT.PROGA(not found)
Search for PROD_COLLECT.PROGA(not found)
SET CURRENT PACKAGESET = 'PROD_COLLECT'
PROGA
SELECT col1 . . .
SELECT col1 . . .
DB2
-805
-805etc. . . .
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
DB2 for z/OS server(through DDF) -- no plan with PKLIST
Package resolution today -- remote DRDA server
SET CURRENT PACKAGESET = 'MAINT_COLLECT'
Search for MAINT_COLLECT.PROGA(not found)
Search for PROD_COLLECT.PROGA(not found)
SET CURRENT PACKAGESET = 'PROD_COLLECT'
PROGA
SELECT col1 . . .
SELECT col1 . . .
DB2
-805
-805etc. . . .
DB2 for z/OS clientplan with PKLIST for accessing local packages
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
DB2 for z/OS server(through DDF) -- no plan with PKLIST
Package resolution with CURRENT PACKAGE PATH
SET CURRENT PACKAGE PATH = "MAINT_COLLECT", "PROD_COLLECT","TEST_COLLECT"
PROGA
SELECT col1 . . .
DB2
etc. . . .
DRDA client or DB2 for z/OS clientplan with PKLIST for accessing local packages
MAINT_COLLECT.PROGA
PROD_COLLECT.PROGA
TEST_COLLECT.PROGA
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Common Table Expressions and Recursive SQL
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Common Table Expression (CTE) and Recursion
Refer to table-name later in SQL
Allow in SELECT, CREATE VIEW, INSERT
WITH table-name [ column-list ] AS fullselect
For recursion–fullselect that does not refer to CTE
UNION ALL fullselect that refers to CTE
–fullselect of CTE refers to itself
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Common Table Expression example
WITH DTOTAL (deptno, totalpay) AS ( SELECT deptno, sum (salary + bonus)
FROM employee GROUP BY deptno )
SELECT deptno FROM DTOTAL WHERE totalpay =
(SELECT max ( totalpay ) FROM DTOTAL )
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
AAA
BBB CCC DDD
EEE FFF
GGG
Recursive SQL Example
WITH PARENT ( PKEY, CKEY ) AS ( SELECT PKEY, CKEY FROM HIERARCHY WHERE PKEY = 'AAA'
UNION ALL SELECT C.PKEY, C.CKEY FROM HIERARCHY C, PARENT PWHERE P.CKEY = C.PKEY )
SELECT PKEY, CKEY FROM PARENT;
PKEY CKEYAAA BBBAAA CCCAAA DDDCCC EEEDDD EEEDDD FFFFFF GGG
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
Summary
DB2 V8
CURRENT
PACKAGE
PATH
Multi-row INSERT
Multiple
DISTINC
T
Dymanic scrollable
Scalar
fullselec
t
Indentityenhancement
sMulti-row FETCH
GET
DIAGNOSTICS
INSERT w/inSELECT
Recursive SQL
Sequences
Advanced Technical Support (ATS), Americas
© 2004 IBM Corporation
SG24-6079SG24-6079