- OOWidgets

advertisement
Interesting SQL Solutions to
Real Life Problems
Anthony Tichonoff
Florida Hospital Sr. DB2 DBA
Tampa Bay RUG Meeting
Fri, Feb 21, 2013 12:45 AM - 1:45 AM
Presentation Overview
• Using the full power of SQL as a programming language
• Fully exploiting common SQL features in creative ways
• Fun SQL –
•
•
•
•
•
•
•
Real Time Statistics Auditing DASD Growth
Probabilistic Matching
DB2 Catalog Logger
Auditing Temporal Data for Errors
Calendars
Dynamic Screens
DDL SQL Generation
• Implementing interesting SQL in different languages
2
The Challenge
I need to identify DB2
objects that grow rapidly.
3
The Steps
Build DB2 table to collect daily
RTS History Stats
- Columns for RTS History Table
Insert both tablespace and
indexspaces into RTS History table
- SQL Insert for RTS Tablespace
- SQL Insert for RTS Indexspace
SQL to determine DASD Growth
- SQL for DASD Growth
4
The Breakdown
Insert
Select
SQL
SQL
5
The
Insert
SQL
INSERT INTO {Your RTS History Table}
SELECT CURRENT TIMESTAMP
,A.DBNAME
,A.NAME
,'T'
,A.PARTITION
,COALESCE(INT(A.TOTALROWS),0)
,COALESCE(A.NACTIVE,0)
,COALESCE(A.SPACE,0)
,COALESCE(A.EXTENTS,0)
,SUBSTR(B.STORNAME,1,8)
AS T_STATS
AS I_DATB
AS I_OBJC
AS I_TYPE_OBJC
AS I_PART
AS Q_ROWS
AS Q_PAGE_ACTV
AS Q_SPAC_KB
AS Q_EXTN
AS I_N_STOR
FROM SYSIBM.SYSTABLESPACESTATS A
JOIN SYSIBM.SYSTABLEPART B
ON B.DBNAME
= A.DBNAME
AND B.TSNAME
= A.NAME
AND B.PARTITION
= A.PARTITION
JOIN SYSIBM.SYSTABLESPACE C
ON C.DBNAME
= A.DBNAME
AND C.NAME
= A.NAME
AND C.DBID
= A.DBID
AND C.PSID
= A.PSID
WHERE {Your Filter}
6
Tablespace
Growth SQL
Part 1
WITH RTS_HISTORY
( I_DATB
,I_OBJC
,T_STATS
,Q_ROWS
,Q_PAGES
,Q_SPAC_KB
,Q_EXTN
) AS
(
SELECT
I_DATB
,I_OBJC ,T_STATS
,SUM(Q_ROWS)
AS Q_ROWS
,SUM(Q_PAGE_ACTV)
AS Q_PAGES
,SUM(Q_SPAC_KB)
AS Q_SPAC_KB
,MAX(Q_EXTN)
AS Q_EXTN
FROM { Your RTS History Table }
WHERE I_TYPE_OBJC
= ‘T’
AND T_STATS BETWEEN CURRENT TIMESTAMP –
(&Q_DAYS + 1) DAYS
AND CURRENT TIMESTAMP
GROUP BY
I_DATB
,I_OBJC
,T_STATS
)
7
SELECT C.I_DATB,
FROM
JOIN
Tablespace
Growth SQL
ON
JOIN
Part 2
ON
JOIN
ON
C.I_OBJC
,&Q_DAYS
AS Q_DAYS
,Output : Row, Page, Space, Extent Data
(
) L
(
SELECT Minimum Values by Database & Object
FROM RTS_HISTORY
SELECT Maximum Values by Database & Object
FROM RTS_HISTORY
) H
H.I_DATB = L.I_DATB AND H.I_OBJC
(
SELECT Current Values by Database & Object
FROM RTS_HISTORY
WHERE T_STATS = SubSelect for MAX(T_STATS)
) C
C.I_DATB = L.I_DATB AND C.I_OBJC
(
= L.I_OBJC
= L.I_OBJC
SELECT Oldest Values by Database & Object
FROM RTS_HISTORY
WHERE T_STATS = SubSelect for MIN(T_STATS)
) O
O.I_DATB = L.I_DATB AND O.I_OBJC
= L.I_OBJC
8
The Output
Rows
Database
Object
# Days
Delta
Max
DKM97PRD
SKM9732
30
-162,082,402
248,311,973
56,125,070
DKM97PRD
SKM9733
30
-35,025,961
49,524,240
9,494,040
DIS97PRD
SIS9761
30
-28,795,566
201,123,146
124,806,402
DHC97PRD
SHC9708
30
22,001,796
-
62,233,272
DGL97PRD
SGL9749
30
18,007,738
-
229,901,672
Pages
Current
Space MB
Delta
Max
Current
Delta
Max
Current
-1,889,280
3,021,840
810,000
-8,136
12,528
3,240
-406,440
603,730
133,210
-1,620
2,628
720
-1,299,136
6,105,568
3,292,608
-5,231
24,496
13,232
769,625
-
2,282,476
3,008
-
9,180
67,841
-
3,160,942
272
-
12,962
9
The Challenge
I need DB2 to match people
and identify duplicates from
two separate systems.
10
The Breakdown & Steps
L
o
a
d
11
The SQL
EX
1
0/Many
IN
Select
Medical Record Id (Patient Key)
,Demographic Data (Compare Keys)
From Internal Demographic Table
Where
IN.SSN
= :EX.SSN
Union
IN.Last Name = :EX.Last Name
& IN.DOB
Union
IN.Driver Lic
Union
•
•
•
=
:EX.DOB
=
:EX.Driver Lic
Result Set outputs
0 to Many Keys
Match ?
Possible match,
more processing
needed to confirm.
No Match
No rows located in
the internal table.
12
The SQL
Check
Compare Keys
If EX.cKey1 = IN.cKey1 and
EX.cKey2 = IN.cKey2 and
…
Then Add to Score
If EX.cKey4 = IN.cKey4 and
EX.cKey5 = IN.cKey5 and
EX.cKey6 = IN.cKey6 and
Match
Ratio
Score
Full
1:1
100%
Partial
1:M
1% - 100%
No
1:0
0%
…
Then Add to Score
13
The Output
FULL
Match
Insert into Cross
Reference Table
PARTIAL
Match
Match
or
Reject
NO
Match
Insert into
Demographic &
Cross Ref Table
14
The Challenge
Can I audit the differences in
two different DB2 subsystems.
15
The Breakdown & Steps
•
•
•
•
•
Create Snap Shot Catalog Tables
Create Catalog Chronology Table
Program must utilize Declare Global Temp Tables to collect
all catalog data for all DB2 Subsystems
Use Full Outer Joins comparing data for changes
Differences are loaded into Catalog Chronology Table
DB2 Subsystem A
Catalog Chronology
DB2 Subsystem B
Databases -Tablespaces -Tablespace Parts
Tables -Table Columns-Indexes-Index Parts-Index Columns
Views-View Columns-Aliases
Routines -Triggers
16
The Breakdown
DB2 Catalog
Logger Program
17
The SQL
Processing DB2 Declared Temporary Tables
Objects exists in both tables but the
column values are different then
object was Altered.
Objects only exists in snapshot catalog then
object was Dropped.
Objects only exists in current catalog then
object was Created.
18
The Output
Work Date
Type
Object
Name
Creator
Work
Operator
Request
Type
Comment
9/12/2012
X
XRSD97321
PCTL
AAT89A
AO
ALTERED PRIMARY
OLD 36,000 NEW 108,000
8/2/2012
8/2/2012
8/2/2012
8/2/2012
8/2/2012
8/2/2012
T
R
R
X
X
T
SSD9732
RSD97321
RSD97320
XSD97321
XSD97320
SSD9732
PCTL
PCTL
PCTL
PCTL
PCTL
PCTL
AAT89A
AAT89A
AAT89A
AAT89A
AAT89A
AAT89A
CO
CO
CO
CO
CO
CO
CREATED NEW TABLESPACE
CREATED NEW TRIGGER
CREATED NEW TRIGGER
CREATED NEW INDEX
CREATED NEW INDEX
CREATED NEW TABLE
2/27/2012
T
SSD9732
TEST
RLB77C
AC
F_VALD_PDX_LOCK
"LOCK PRINCIPAL DIAGNOSIS"
1/4/2012
1/4/2012
1/4/2012
1/4/2012
1/4/2012
1/4/2012
R
R
X
T
X
T
RSD97321
RSD97320
XSD97321
SSD9732
XSD97320
SSD9732
TEST
TEST
TEST
TEST
TEST
TEST
RLB77C
RLB77C
RLB77C
RLB77C
RLB77C
RLB77C
CO
CO
CO
CO
CO
CO
CREATED NEW TRIGGER
CREATED NEW TRIGGER
CREATED NEW INDEX
CREATED NEW TABLESPACE
CREATED NEW INDEX
CREATED NEW TABLE
19
The Challenge
I need to audit the data in my user
maintained inclusive - inclusive
temporal tables.
20
The Breakdown & Steps
Inclusive - Inclusive Time Series
SQL
Same row Check
Start Overlapped 
End Overlapped 
Encapsulated 
SELECT
A.I_KEY
,Output Data
FROM SD00 A JOIN SD00 B
ON A.I_Key
= B.I_KEY
WHERE A.D_STAR
<>
AND A.D_END
<>
AND
( ( A.D_STAR
<=
AND A.D_STAR
<=
AND
( A.D_END
>=
OR A.D_END
>=
)
OR ( A.D_END
>=
AND A.D_END
>=
AND
( A.D_STAR
<=
OR A.D_STAR
<=
)
OR ( A.D_STAR
>=
AND A.D_END
<=
)
Join to Self
B.D_STAR
B.D_END
B.D_STAR
B.D_END
B.D_STAR
B.D_END )
B.D_STAR
B.D_END
B.D_STAR
B.D_END )
B.D_STAR
B.D_END )
22
SQL
UNION ALL
SELECT
A.I_KEY
,Output Data
FROM SD00 A
ON A.I_Key
Gap Check 
Find Next End Date 
Is Gap Span > 1 Day 
Join to Self
JOIN SD00 B
= B.I_KEY
WHERE &GAPS
= 'Y'
AND B.D_STAR
> A.D_STAR
AND B.D_END
=
(
SELECT MIN(C.D_END)
FROM SD00 C
WHERE C.I_KEY
= A.I_KEY
AND C.D_END > A.D_END
)
AND DAYS(B.D_STAR) – DAYS(A.D_END) > 1
ORDER BY
I_KEY
,D_STAR_A
WITH UR
23
The Output
Key
Error
Start -A
End - A
Start - B
End - B
KEY E
EMBEDDED
01/01/0001
12/31/9999
04/10/2008
12/31/2050
KEY E
EMBEDDED
04/10/2008
12/31/2050
01/01/0001
12/31/9999
KEY G
GAP
10/23/2002
12/12/2002
12/18/2002
01/08/2003
KEY G
GAP
12/18/2002
01/08/2003
09/05/2003
12/31/9999
KEY O
OVERLAP
07/01/2004
11/16/2005
10/02/2005
10/31/2009
KEY O
OVERLAP
11/01/2009
01/25/2010
01/02/2010
12/31/9999
24
The Challenge
I need to build a dynamic
calendar in my application.
25
The Breakdown & Steps
1. Calendar 4 dimensional array
a.
b.
c.
d.
Year
Month
Week of Year
Day of Week
2. Need row for each day of month
(Use Recursive SQL)
3. Use SQL Functions for dimensions
a. Week of the Year (Group by)
b. Day of the Week
4. Assign Day of Week to each column
(Sun, Mon, Tue, Wed, Thu, Fri, Sat)
26
SQL
Must build a result set with a row for each day of the month
WITH DAYTAB
(
Recursive SQL
D_DAY
)
AS
(
SELECT
LAST_DAY(DATE(&DATE) – 1 MONTH) + 1 DAY AS D_DAY
FROM SYSIBM.SYSDUMMY1
UNION ALL
SELECT
D_DAY + 1 DAY
FROM DAYTAB
WHERE D_DAY < LAST_DAY(&DATE)
)
AS D_DAY
27
SQL
Formats 
Output & Builds
Week Day Columns
Calculates 
Dimensions for
Week Of Year
& Day Of Week
SELECT
DAYOFYEAR(&DATE)
AS DY
,YEAR(&DATE)
AS YY
,UCASE(
(SUBSTR(CHAR(DATE(&DATE), LOCAL),1,
POSSTR(CHAR(DATE(&DATE), LOCAL),' '))
) )
AS MM_NAME
, WY_DEM
,MAX(CASE WHEN DW_DEM = 1 THEN DD ELSE '' END) AS SUN
,MAX(CASE WHEN DW_DEM = 2 THEN DD ELSE '' END) AS MON
,MAX(CASE WHEN DW_DEM = 3 THEN DD ELSE '' END) AS TUE
,MAX(CASE WHEN DW_DEM = 4 THEN DD ELSE '' END) AS WED
,MAX(CASE WHEN DW_DEM = 5 THEN DD ELSE '' END) AS THU
,MAX(CASE WHEN DW_DEM = 6 THEN DD ELSE '' END) AS FRI
,MAX(CASE WHEN DW_DEM = 7 THEN DD ELSE '' END) AS SAT
FROM
(
SELECT
WEEK(D_DAY)
AS WY_DEM
,DAYOFWEEK(D_DAY)
AS DW_DEM
,RIGHT(' ' || STRIP(CHAR(DAY(D_DAY))),2)
AS DD
FROM DAYTAB
)X
GROUP BY
WY_DEM
WITH UR
28
The Output
D_DAY
02/01/2013
02/02/2013
02/03/2013
02/04/2013
02/05/2013
02/06/2013
02/07/2013
02/08/2013
02/09/2013
02/10/2013
02/11/2013
02/12/2013
02/13/2013
02/14/2013
02/15/2013
02/16/2013
02/17/2013
02/18/2013
02/19/2013
02/20/2013
02/21/2013
02/22/2013
02/23/2013
02/24/2013
02/25/2013
02/26/2013
02/27/2013
02/28/2013
49
FEBRUARY
2013
S M T W T F S
-- -- -- -- -- -- -1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28
QMF Result Set
using a form
Program
Display
Recursive Table Result Set
29
The Challenge
I need to build dynamic report
screens in CICS with scrolling.
30
The Breakdown & Steps
Hospital Grand Totals (Counts & Totals)
$$$$
+ Operator
+ Campus
+ Accounts
$$$$
Errors to work
...
...
...
Campus Totals
$$$$
...
Operator Totals
$$$$
31
The SQL – Utilize Nested Common Table Expressions
Build common table expression for all
account error detail – AccnDetail
32
The SQL – Utilize Nested Common Table Expressions
With
Account Details
AccnDetail
(
Type Row
,Account
,Campus
,Operator
,Account Details
)
AS
(
Select
‘2D’ as Type Row
,Account
,Campus
,Operator
,Other Details
From { User Table_A }
Join { User Table_B }
Join { User Table_C }
)
Where {Account Detail Filtering}
,AccnSumm
,CampSumm
,OprtSumm
,HospSumm
( Continue … )
( Continue … )
( Continue … )
( Continue … )
33
The SQL – Utilize Nested Common Table Expressions
With
Account Summary
AccnDetail
( Previous … )
,AccnSumm
( Continue … )
(
Type Row
,Account
,Campus
,Operator
,Aggregated Account Details
)
AS
(
Select
‘1H’ as Type Row
,Account
,Campus
,Operator
, Aggregated Account Details
)
From { AccnDetail }
Group By
Operator
,Campus
,Account
,CampSumm
,OprtSumm
,HospSumm
( Continue … )
( Continue … )
( Continue … )
34
The SQL – Utilize Nested Common Table Expressions
With
Campus Summary
AccnDetail
( Previous … )
,AccnSumm
( Previous … )
,CampSumm
(
Type Row
,Account
,Campus
,Operator
,Aggregated Account Summary
)
AS
(
Select
‘3C’ as Type Row
,Null Account ,Campus
,Operator
, Aggregated Account Summary
)
From { AccnSumm }
Group By
Operator
,Campus
,OprtSumm
,HospSumm
( Continue … )
( Continue … )
35
The SQL – Utilize Nested Common Table Expressions
With
Operator Summary
AccnDetail
( Previous … )
,AccnSumm
( Previous … )
,CampSumm ( Previous … )
,OprtSumm
(
Type Row
,Account
,Campus
,Operator
,Aggregated Campus Summary
)
AS
(
Select
‘4O’ as Type Row
,Null Account ,Null Campus
,Operator
, Aggregated Campus Summary
)
From { CampSumm }
Group By
Operator
,HospSumm
( Continue … )
36
The SQL – Utilize Nested Common Table Expressions
With
Hospital Summary
AccnDetail
( Previous … )
,AccnSumm
( Previous … )
,CampSumm ( Previous … )
,OprtSumm
( Previous … )
,HospSumm
(
Type Row
,Account
,Campus
,Operator
,Aggregated Operator Summary
)
AS
(
Select
‘5T’ as Type Row
,Null Account ,Null Campus
,Null Operator
,Aggregated Operator Summary
From { OprtSumm }
)
37
The SQL – Utilize Nested Common Table Expressions
SELECT *
FROM
( SELECT Type Row , Account, Campus, Operator
, Account Details
FROM AccnDetail Where ShowDetail = ‘Y’ )
Union All
( SELECT Type Row , Account, Campus, Operator
,Aggregated Account Details
FROM AccnSumm Where ShowAccn = ‘Y’)
Union All
( SELECT Type Row , Account, Campus, Operator
,Aggregated Account Summary
FROM CampSumm Where ShowCampus = ‘Y’)
Union All
( SELECT Type Row , Account, Campus, Operator
,Aggregated Campus Summary
FROM OprtSumm )
Union All
( SELECT Type Row , Account, Campus, Operator
,Aggregated Operator Summary
FROM HospSumm )
Main SQL
ORDER BY Operator, Campus, Account, Type Row
38
Account Detail
Campus Summary
The Output
Row
Type
Operator
Campus Account
1H
#
Errors
3544
Account Summary
Operator Summary
Hospital Summary
Charges
$ 5,182,626.03
#
Accounts
Error Id
0
1760
1A
2D
2D
AGU2E0
01
22814252
1
$
213.00
0
183250672
183270843
1
0
0
1A
2D
AGU2E0
01
22814405
2
$
213.00
0
183250703
1
0
3C
AGU2E0
01
3
$
426.00
0
2
1A
2D
2D
AGU2E0
02
2
$
31,166.50
0
183249295
183270206
1
0
0
3C
AGU2E0
02
2
$
31,166.50
0
1
4O
AGU2E0
5
$
31,592.50
0
3
22799806
39
The Output
40
The Challenge
I need to be able to generate
current DDL for all of my objects.
41
The Breakdown & Steps
Florida Hospital DDL Generator
A collection of Rexx modules which
regenerates our DDL from the DB2 Catalog
Rexx
Modules
DDLAL01
DDLCT01
DDLDB01
DDLGR01
DDLGR02
DDLGR03
DDLGR04
DDLIX01
DDLLO01
DDLV
DB2 Object to Regenerate
Aliases
Create All Objects
Databases
Table Grants
Database Grants
Tablespace Grants
Sequence Grants
Indexes
LOBs
Online View of DDL
Rexx
Modules
DDLMQ01
DDLRT01
DDLSQ01
DDLST01
DDLTB01
DDLTR01
DDLTS01
DDLVW01
DDLWR01
DDLG
DB2 Object to Regenerate
MQTs
Routines
Sequences
Object Stats Data
Tables
Triggers
Tablespaces
Views
Output: File or Online View
Generates DDL to a File
42
The SQL
Uses
Recursive
SQL to
Locate All
Views
WITH VIEWLIST
( BTYPE
,LEVEL
,BCREATOR
,BNAME
,DCREATOR
,DNAME
) AS
(
SELECT
ROOT.BTYPE
,1
,ROOT.BCREATOR
,ROOT.BNAME
,ROOT.DCREATOR
,ROOT.DNAME
FROM SYSIBM.SYSVIEWDEP ROOT
WHERE BCREATOR
= :CREATOR
AND BNAME
= :TBNAME
UNION ALL
SELECT
CHILD.BTYPE
,PARENT.LEVEL + 1 ,CHILD.BCREATOR
,CHILD.BNAME
,CHILD.DCREATOR ,CHILD.DNAME
FROM VIEWLIST PARENT
JOIN SYSIBM.SYSVIEWDEP CHILD
ON PARENT.DCREATOR
= CHILD.BCREATOR
AND PARENT.DNAME
= CHILD.BNAME
WHERE PARENT.LEVEL < 6
)
SELECT
BTYPE
,BNAME
FROM VIEWLIST
WITH UR
,LEVEL
,DCREATOR
,BCREATOR
,DNAME
43
The Output
TSO DDLV
D B 2
D D L
13/02/21 21:30
DB2 ===> DSN2
Object ===> PCTL.TDA9700
DDL Options:
Entire DDL ===> _
Object Only ===> _
Tablespace
Indexes
Aliases
Grants
Table
Views
Triggers
LOB
===>
===>
===>
===>
X
_
_
_
===>
===>
===>
===>
_
_
_
_
Enter "X" to select option
PF1 for Help
COMMAND ===>
44
The Output
TSO DDLV
--- DDL EXEC GENERATION BY: AAT89A - 13/02/21
-------------------------------------------------------- DDL WAS BUILT USING TABLE PCTL.TDA9700 AS INPUT
------------------------------------------------------------------------------------------------------------- THIS MEMBER CONTAINS SQL STATEMENTS TO CREATE:
-TABLESPACE
-- FOR DDA97PRD.SDA9700
------------------------------------------------------SET CURRENT SQLID = 'DBSYSADM'
;
--- ========== S T A T I S T I C S ==========
--- PCTL.TDA9700 - DB2 APPLICATION TABLE RECOVERY PROFILE
-ROW COUNT
6,267
-SIZE
0.0021 GB
-ROW LENGTH
279
-INDEXES
5
-PACK DEPS
61
-45
The Output
TSO DDLV
-- ========== T A B L E S P A C E ==========
---DROP TABLESPACE DDA97PRD.SDA9700
--;
--COMMIT WORK
--;
-CREATE
TABLESPACE
SDA9700
IN
DDA97PRD
USING
STOGROUP
PCTL
PRIQTY
720
SECQTY
3600
ERASE
NO
FREEPAGE
30
PCTFREE
10
COMPRESS
NO
SEGSIZE
64
BUFFERPOOL
BP2
LOCKSIZE
PAGE
LOCKMAX
SYSTEM
MAXROWS
255
CCSID
EBCDIC
CLOSE
NO
;
--- ========== T S - G R A N T S ==========
--
46
Interesting SQL Solutions to
Real Life Problems
Anthony Tichonoff
anthony.tichonoff@flhosp.org
Florida Hospital Sr. DB2 DBA
Tampa Bay RUG Meeting
Download