DB2 V9 News bei SQL

Werbung
(*)
IBM DB2 for z/OS
DB2 Version 9 - Übersicht
(DB2_Version9_SQLnews.ppt)
(*) ist eingetragenes Warenzeichen der IBM International Business Machines Inc.
Oktober, 2010
1
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
MERGE
INTERSECT & EXCEPT
SELECT FROM UPDATE, DELETE, MERGE
TRUNCATE
FETCH FIRST & ORDER BY in Subselect und Fullselect
Neue „built-in functions“
INSTEAD OF TRIGGER
BIGINT, VARBINARY, DECIMAL FLOAT
Index auf Ausdrücke, caseless comparisons
XML (eig. Kapitel)
„Optimistic locking“
Verbesserte DDL Konsistenz
Oktober, 2010
2
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
LIKE – Abfragen (gibt es schon länger…)
• Der “escape character” in einem LIKE Statement ermöglicht die Suche nach Prozentzeichen (!)
und Unterstrichen im Suchstring.
• Wenn EC’s eingesetzt werden, so werden sie einem '%' bzw. '_' vorangestellt und zeigen so an,
dass diese der aktuelle Suchwert und nicht ein spezielles Zeichen zur Prüfung des weiteren
“search” ist. Für OLTP-Anwendungen, wie SAP gilt:
Oktober, 2010
LIKE STATEMENT TEXT
===========================
WHAT VALUES MATCH
======================
LIKE 'AB%'
LIKE 'AB%' ESCAPE '+'
LIKE 'AB+%' ESCAPE '+'
LIKE 'AB++' ESCAPE '+'
LIKE 'AB+%%' ESCAPE '+'
LIKE 'AB++%' ESCAPE '+'
LIKE 'AB+++%' ESCAPE '+'
LIKE 'AB+++%%' ESCAPE '+'
LIKE 'AB+%+%%' ESCAPE '+'
LIKE 'AB++++' ESCAPE '+'
LIKE 'AB+++++%' ESCAPE '+‚
LIKE 'AB++++%' ESCAPE '+'
LIKE 'AB+%++%' ESCAPE '+'
Finds AB, any string
Finds AB, any string
Finds AB%
Finds AB+
Finds AB%, any string
Finds AB+, any string
Finds AB+%
Finds AB+%, any string
Finds AB%%, any string
Finds AB++
Finds AB++%
Finds AB++, any string
Finds AB%+, any string
SELECT
FROM
WHERE
AND
AND
AND
AND
id
staff
id = 10
'ABC' LIKE 'AB%'
'A%C' LIKE 'A/%C' ESCAPE '/'
'A_C' LIKE 'A\_C' ESCAPE '\'
'A_$' LIKE 'A$_$$' ESCAPE '$';
ERGEBNIS
==========
ID
--10
3
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
SELECT - Änderungen
Syntax
Table Typen
•
•
•
OLD: gibt die Status der Daten VOR dem Ablauf des Statement zurück. Möglich für UPDATE und DELETE
NEW: gibt die Status der Daten NACH dem Ablauf des Statement zurück. Gilt für alle AFTER Triggers bzw.
RI . Möglich für INSERT und UPDATE
FINAL: gibt den endgültigern Status der Daten zurück. Existiert ein AFTER Trigger, der die daten NACH der
Änderung nochmals ändert, wird ein Fehler erzeugt. Dasselbe gilt für einen View, der mit einem INSTEAD
OF Trigger versehen ist. Möglich für INSERT und UPDATE
Zeige die gelöschten Datenzeilen….
SELECT
,
FROM
projno AS prj
actno AS act
OLD TABLE
(DELETE
FROM emp_act
WHERE empno = '300000')
ERGEBNIS
==========
PRJ ACT
------ -----VVV 111
ZZZ
999
ORDER BY 1,2;
Oktober, 2010
4
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
SELECT FROM UPDATE, INSERT, DELETE, MERGE
Select von „rows“ in der INSERT - Reihenfolge…
SELECT
empno
,
projno AS prj
,
actno AS act
,
ROW_NUMBER() OVER() AS r#
FROM
FINAL TABLE
( INSERT INTO emp_act_copy (empno, projno, actno)
VALUES ('400000','ZZZ',999) ,('400000','VVV',111) )
ORDER BY INPUT SEQUENCE;
ANSWER
=================
EMPNO PRJ ACT R#
----------- ----- ----- -400000 ZZZ 999 1
400000 VVV 111 2
Select von einem INSERT mit unbekannten Werten…
SELECT
,
,
empno
projno AS prj
actno AS act
ROW_NUMBER() OVER() AS r#
FROM
NEW TABLE
(INSERT INTO emp_act_copy (empno, actno, projno)
SELECT LTRIM(CHAR(id + 600000))
,
SECOND(CURRENT TIME)
,
CHAR(SMALLINT(RAND(1) * 1000))
FROM
staff
WHERE id < 40)
ORDER BY INPUT SEQUENCE;
Oktober, 2010
ERGEBNIS
=================
EMPNO PRJ ACT R# ,
----------- ----- ------ --600010 1 59 1
600020 563 59 2
600030 193 59 3
5
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
SELECT FROM UPDATE, DELETE (mit INCLUDE = „temp column“)
Select von einem UPDATE mit „alten“ und „neuen“ Werten… (die „alten“ Werte über eine „temp“-Spalte….)
SELECT
,
,
FROM
projno
AS prj
old_t
AS old_t
emptime
AS new_t
NEW TABLE
(UPDATE emp_act
INCLUDE (old_t DECIMAL(5,2))
SET emptime = emptime * RAND(1) * 10
,
old_t = emptime
WHERE empno = '200000')
ERGEBNIS
==================
PRJ OLD_T NEW_T
------ ---------- ----------ABC 2.00
0.02
DEF 2.00
11.27
ORDER BY 1;
Select jeder zweiten „row“, die gelöscht werden soll… (das Prädikat im SELECT hat keinen Einfluss auf den DELETE)
SELECT
,
,
,
FROM
empno
ERGEBNIS
projno
====================
actno
AS act
EMPNO PROJNO ACT R#
row#
AS r#
----------- ----------- ------ --OLD TABLE
000260 AD3113 70 2
(DELETE FROM emp_act
000260 AD3113 80 4
INCLUDE (row# SMALLINT)
000260 AD3113 180 6
SET row# = ROW_NUMBER() OVER()
WHERE empno = '000260')
WHERE
row# = row# / 2 * 2
ORDER BY 1,2,3;
Oktober, 2010
6
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
SELECT FROM UPDATE, DELETE (als CURSOR)
Select FROM DELETE Statement, um die „analysts“ aus der Tabelle EMP zu löschden und aber die Erfahrung der
Analysten zu erhalten.
DECLARE
CS1 CURSOR FOR
SELECT YEAR(CURRRENT DATE - HIREDATE)
FROM
OLD TABLE
(DELETE FROM EMP WHERE JOB = ’ANALYST’);
…
FETCH CS1 INTO :years_of_service;
Angenommen, man will berechnete Daten aus einer Tabelle erhalten, deren Daten ganz oder teilweise gelöscht werden
sollen, deren Ergebnisse aber nicht in eíner Spalte der Ziel-Tabelle abgelegt werden sollen:
Man will Manager aus der Tabelle EMP löschen, aber geleichzeitig Gehalt und Anzahl Jahre Betriebszugehörigkeit
anzeigen. Hier das SELECT FROM DELETE Statement :
DECLARE
Oktober, 2010
CS2 CURSOR FOR
SELECT
LASTNAME, SALARY,
years_employed FROM OLD TABLE
(DELETE FROM EMP INCLUDE(years_employed INTEGER)
SET years_employed = YEAR(CURRENT DATE - HIREDATE)
WHERE JOB = ’MANAGER’);
7
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
ORDER BY und FETCH FIRST im Subselect
In DB2 V8 sind ORDER BY und FETCH FIRST n ROWS ONLY Klauseln nur auf Statementebene als Teil eines
“select-statement “ bzw. eines SELECT INTO Statements erlaubt Man kann also folgende Formulierung
verwenden:
SELECT * FROM T ORDER BY c1 FETCH FIRST 1 ROW ONLY
Man kann aber folgende Formulierung nicht nutzen:
INSERT INTO T1 (SELECT * FROM T2 ORDER BY c1 FETCH FIRST 1 ROW ONLY)
Angenommen, man hat nun eine grosse Tabelle aus der man nur die ersten 2000 “rows” sortiert in eine
andere Tabelle einfügen wollte, so würde man einen SELECT gefolgt von FETCH FIRST und ORDER BY
Klausel schreiben. Die schlechte Nachricht ist: Der SORT wird VOR dem FETCH durchgeführt.
Das verursacht einen riesigen SORT - umsonst. Ein “work around” wäre eine “temp table” zu verwenden. Das
aber erfordert weit mehr, als nur einen einfachen SELECT.
DB2 V9 löst das Problem:
SELECT
FROM
WHERE
T1.EMPNO, T1.PROJNO
DSN8910.EMPPROJACT T1
T1.EMPNO IN
(SELECT
T2.EMPNO
FROM
DSN8910.EMP T2
ORDER BY SALARY DESC
FETCH FIRST 3 ROWS ONLY)
ORDER BY T1.PROJNO;
Oktober, 2010
ERGEBNIS
============================
EMPNO
PROJNO
--------------------------------------000010
AD3100
000010
MA2100
000110
MA2100
000010
MA2110
8
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
ORDER BY and FETCH FIRST im Subselect (Kontrolle)
SELECT
T2.EMPNO,T2.SALARY
FROM
DSN8910.EMP T2
ORDER BY SALARY DESC ;
---------+---------+---------+-EMPNO
SALARY
---------+---------+---------+-000010
52750.00
200010
46500.00
000110
46500.00
000020
41250.00
000050
40175.00
..............
..............
..............
000310
15900.00
200310
15900.00
000290
15340.00
SELECT
FROM
WHERE
T1.EMPNO, T1.PROJNO
DSN8910.EMPPROJACT T1
T1.EMPNO IN
(SELECT
T2.EMPNO
FROM
DSN8910.EMP T2
ORDER BY SALARY DESC
FETCH FIRST 3 ROWS ONLY)
ORDER BY T1.PROJNO;
Oktober, 2010
SELECT
T1.EMPNO,T1.PROJNO
FROM
DSN8910.EMPPROJACT T1
ORDER BY EMPNO;
---------+----------------+------EMPNO
PROJNO
---------+----------------+------000010
MA2100
000010
MA2110
000010
AD3100
000020
PL2100
000030
IF1000
000030
IF2000
000050
OP1000
000050
OP2010
000070
AD3110
000090
OP1010
000100
OP2010
000110
MA2100
.............
............
.............
............
.............
............
000330
OP2012
000340
OP2013
000340
OP2013
9
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
MERGE
Oktober, 2010
•
kombiniert UPDATE und INSERT Operation gegen eine Zieltabelle / -view

Als Quelle dienen “host-variable-arrays” angelegt, wie eine “source
table”

Wenn die “source rows” im Ziel existieren, erfolgt ein UPDATE auf die
betroffenen “rows”

ansonsten erfolgt ein INSERT der “rows” aus der Quellumgebung in die
Zielumgebung
•
Restriktionen

es gibt keine MERGE Trigger

MERGE ist nicht zulässig auf einen View mit INSTEAD OF
TRIGGER
10
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
MERGE
• Für UPDATE und INSERT Operationen
• Für OLTP Anwendungen wie SAP…
MERGE
INTO account AS T
USING VALUES (:hv_id, :hv_amt) FOR 5 ROWS AS S(id,amt)
ON T.id = S.id
WHEN MATCHED THEN
UPDATE SET balance = T.balance + S.amt
WHEN NOT MATCHED THEN
INSERT (id, balance) VALUES (S.id, S.amt)
NOT ATOMIC CONTINUE ON SQLEXCEPTION
Oktober, 2010
11
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
MERGE
SELECT
FROM
WHERE
ORDER BY
QBLOCKNO,QBLOCK_TYPE,PLANNO,SUBSTR(TNAME,1,2) AS TNAME,
TABLE_TYPE,JOIN_TYPE,METHOD,ACCESSTYPE
PLAN_TABLE
QUERYNO = 1
QUERYNO, QBLOCKNO, PLANNO;
Beispiel EXPLAIN für MERGE
1* : TABLE_TYPE "B" wird auch in V8 unterstützt.
2* : ACCESSTYPE "V" " wird auch in V8 unterstützt.
3* : wegen "update in place", wird Nested Loop Join angenommen.
4* : wegen "update in place“: wird ene IX–Spalte “upgedated”, wird der IX nicht für Tabellenzugriff verwendet, um Probleme zu
vermeiden
RID Zugriff ("I" with prefetch="L") und/oder “Sparse index access” ("T") ist nicht geplant
Für MERGE gibt es keine Paralleverarbeitungsoption.
Oktober, 2010
12
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
MERGE
Versucht man eine oder mehrere “rows” mit MERGE in eine Table einzubringen, so kann man
gleichzeitig folgende Informationen erhalten:
• den Wert einer automatisch generierten Spalte, wie ROWID oder “identity column”
• Beliebige “default”-Werte für Spalten
• Alle Werte einer “merged row”, ohne die einzelnen “column names” anzugeben
• berechnete Werte auf Änderungen an “merged rows”
SELECT
FROM
Oktober, 2010
id, balance, status
FINAL TABLE (
MERGE INTO account AS T INCLUDE (status, char(3) )
USING VALUES ((:hv_id, :hv_amt) FOR 5 ROWS) AS S (id,amt)
ON T.id = S.id
WHEN MATCHED THEN
UPDATE SET balance = T.balance + S.amt, status = ‘upd’
WHEN NOT MATCHED THEN
INSERT (id, balance,status) VALUES (S.id, S.amt, ‘ins’ )
NOT ATOMIC CONTINUE ON SQLEXCEPTION )
13
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
TRUNCATE
TRUNCATE ersetzt einen DELETE FROM --- ohne WHERE Klausel („Massen-DELETE“)
Das TRUNCATE TABLE Statement bietet einen effizienten Mechanismus, um alle “data rows” in einer
anzugebenden Tabelle zu löschen, ohne die “delete triggers” zu aktivieren, oder die bestehenden
Tabellenattribute der Tabelle im DB2 Katalog zu verändern. Das Statement bietet auch eine IMMEDIATE
Option, die eine Tabelle nachhaltig leert, ohne COMMIT absetzen zu müssen und eine Fun ktion REUSE
STORAGE, die die Wiederverwendung des “deallocated storage” ermöglicht.
Die Tabelle kann sich in einem “simple table space”, “segmented table space”, “partitioned table space,” oder
einem “ universal tablespace“ befinden.
Syntax
TRUNCATE TABLE emp;
---------+---------+---------+---------+-------------------------DSNE615I NUMBER OF ROWS AFFECTED IS 45147
TRUNCATE ist eine Alternative zum LOAD REPLACE…
Oktober, 2010
14
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
TRUNCATE
TRUNCATE INVENTORY_TABLE . . . DROP STORAGE
INVENTORY_TAB
• Der Speicher wird geleert und freigegeben und kann
entweder von der INVENTORY:TABLE, TABLE_2 oder
TABLE_3 wiederverwendet werden
TRUNCATE INVENTORY_TABLE . . . REUSE
STORAGE
• Der Speicher wird geleert und kann von der
INVENTORY:TABLE wiederverwendet werden
TABLE_2
TABLE_3
TRUNCATE INVENTORY_TABLE . . . IMMEDIATE
• TRUNCATE wird SOFORT durchgeführt und kann nicht
rückgängig gemacht werden…
• Die Tabelle darf KEINE “uncommitted updates” zum Zeitpunkt des TRUNCATE
enthalten.
• Die “truncated table “ wird unmittelbar wieder für die Nutzung in derselben “unit of
work“ verfügbar
• Ein ROLLBACK Statement NACH dem TRUNCATE Statement bleibt unwirksam
• Daten, die NACH dem TRUNCATE geändert wurden, werden “rollbacked”
Oktober, 2010
15
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
INTERSECT, EXCEPT & Erweiterung
INTERSECT
INTERSECT gibt ALLE Schnittstellenwerte zurück (ohne Duplikate) – INTERSECT ALL liefert auch die Duplikate….
SELECT R1
FROM
R1
INTERSECT
SELECT R2
FROM
R2
ORDER BY 1;
SELECT R1
FROM
R1
INTERSECT ALL
SELECT R2
FROM
R2
ORDER BY 1;
Oktober, 2010
R1
--A
A
A
B
B
C
C
C
E
R2
--A
a
B
b
C
c
D
INTERSECT
=========
A
B
C
INTERSECT ALL
=============
A
A
A
B
B
C
C
C
16
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
INTERSECT, EXCEPT & Erweiterung
EXCEPT
EXCEPT gibt ALLE „Nicht-Schnittstellenwerte“ zurück (ohne Duplikate) – EXCEPT ALL liefert auch die Duplikate….
SELECT R1
FROM
R1
EXCEPT
SELECT R2
FROM
R2
ORDER BY 1;
SELECT R1
FROM
R1
EXCEPT ALL
SELECT R2
FROM
R2
ORDER BY 1;
R1
--A
A
A
B
B
C
C
C
E
R2
--A
a
B
b
C
c
D
R1 EXCEPT R2
============
E
R1 EXCEPT ALL R2
================
A
A
B
C
C
E
Natürlich besteht ein Unterschied im Ergebnis bezüglich der ersten (Ausgangs-) Relation….
Oktober, 2010
17
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
INSERT – „multi table „ Nutzung
INSERT INTO
INSERT INTO
us_customer (cname, frst_sale, #sales)
VALUES
('FRED','2002-10-22',1)
,
('JOHN','2002-10-23',1);
intl_customer (cname, frst_sale, #sales)
VALUES
('SUE','2002-11-12',2)
,
('DEB','2002-11-13',2);
VALUES 6
VALUES (6)
VALUES (6, 7, 8)
VALUES (6), (7), (8)
VALUES (6,66), (7,77), (8,NULL)
<= 1 row, 1 column
<= 1 row, 1 column
<= 1 row, 3 columns
<= 3 rows, 1 column
<= 3 rows, 2 columns
COMMIT;
Oktober, 2010
SELECT
FROM
ORDER BY
*
us_customer
cust#
SELECT
FROM
ORDER BY
*
intl_customer
cust#;
ERGEBNIS
=============================
CUST# CNAME FRST_SALE #SALES
---------- ---------- ---------------- ----------1
FRED 10/22/2002
1
2
JOHN 10/23/2002
1
CUST# CNAME FRST_SALE #SALES
--------- ----------- ---------------- ----------3
SUE
11/12/2002
2
4
DEB
11/13/2002
2
18
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
„common table“-Expressions
Das maximale durchschnittliche Gehalt pro Abteilung…. als „common table expression“
WITH
temp1 AS
(SELECT dept
,
AVG(salary) AS avg_sal
FROM staff
GROUP BY dept),
temp2 AS
(SELECT MAX(avg_sal) AS max_avg
FROM temp1)
SELECT
*
FROM
temp2;
ANSWER
==========
MAX_AVG
----------------20865.8625
Das maximale durchschnittliche Gehalt pro Abteilung…. als „nested table expression“
SELECT
FROM
Oktober, 2010
*
(SELECT MAX(avg_sal) AS max_sal
FROM ( SELECT dept
,
AVG(salary) AS avg_sal
FROM staff
GROUP BY dept) AS temp1
) AS temp2;
ANSWER
==========
MAX_AVG
----------------20865.8625
19
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
„common table“-Expressions
Nutzung im INSERT (mit „common table expression“)…
INSERT INTO
WITH
SELECT
FROM
staff
temp1 (max1) AS
( SELECT MAX(id) + 1
FROM
staff )
max1, ' A', 1 , 'B‘ , 2 , 3 , 4
temp1;
OHNE „common table expression“
INSERT INTO
SELECT
FROM
staff
MAX(id) + 1
,' A', 1,'B', 2, 3, 4
staff
Nested „column function“
SELECT
,
FROM
division , DEC(AVG(dept_avg),7,2) AS div_dept
COUNT(*) AS #dpts , SUM(#emps) AS #emps
( SELECT division , dept , AVG(salary) AS dept_avg
,
COUNT(*) AS #emps
FROM staff
ERGEBNIS
,
org
==============================
WHERE dept = deptnumb
DIVISION DIV_DEPT #DPTS #EMPS
GROUP BY division
-------------- -------------- --------- ----------,dept
Corporate 20865.86
1
4
) AS xxx
Eastern
15670.32
3
13
GROUP BY division;
Midwest
15905.21
2
9
Western
17946.40
2
11
Oktober, 2010
20
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
CASE-Nutzung
CASE Ausdrücke wirken wie “do if-then-else” Konstrukte in einem Programm - innerhalb eines SQL Statements.
WARNING: Die Folge der CASE Bedingungen kann die Antwortmenge beeinflussen. Das erste WHEN, das
passt, ist auch das, das angewendet wird.
Syntax
Nutzung von CASE um eine Division durch Null zu vermeiden….
WITH temp1 (c1,c2) AS (VALUES (88,9) , (44,3) , (22,0) , (0,1))
SELECT c1 , c2
,
CASE c2
WHEN 0 THEN NULL
ELSE c1/c2
END AS c3
FROM
temp1;
ERGEBNIS
==========
C1 C2 C3
88 9 9
44 3 14
22 0
0
1 0
Nutzung von CASE um mehrfach zu zählen – in einem SQL-Durchlauf….
SELECT
,
,
FROM
WHERE
Oktober, 2010
COUNT(*) AS tot
SUM(CASE sex WHEN 'F' THEN 1 ELSE 0 END) AS #f
SUM(CASE sex WHEN 'M' THEN 1 ELSE 0 END) AS #m
employee
lastname LIKE 'J%';
ERGEBNIS
==========
TOT #F #M
------ --- --3 1 2
21
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
CAST-Nutzung
Die CAST Funktion dient zur Konvertierung eines Datentyps in einen anderen. Siekann mit anderen “field-type “
Funktionen verglichen werden (z.B. CHAR, SMALLINT), kann aber zusättzlich NULL Werte behandeln und “hostvariable“, sowie „parameter markers“
Syntax
Nutzung von CAST zur Konvertierung des Gehalts auf INTEGER….
SELECT id
,
salary
,
CAST(salary AS INTEGER) AS sal2
FROM
staff
WHERE
id < 30
ORDER BY id;
ERGEBNIS
=================
ID SALARY SAL2
---- -------------- -------10 18357.50 18357
20 18171.25 18171
Nutzung von CAST um „strings“ abzuschneiden….
SELECT
id
,
job
,
CAST(job AS CHAR(3)) AS job2
FROM
staff
WHERE
id < 30
ORDER BY id;
Oktober, 2010
ERGEBNIS
=================
ID JOB
JOB2
--- -------------- ------10 Mgr
Mgr
20 Sales
Sal
22
DB2 Version 9 (Überblick)
DB2 V9 – DISTINCT u.a.
DISTINCT
Sort Vermeidung bei “non-unique” Index
VOR DB2 9, konnte ein DISTINCT nur dann einen SORT vermeiden, wenn ein “unique index” genutzt wurde .
Nun kann ein DISTINCT / GROUP BY auch einen “duplicate index” verwenden, um SORTs zu vermeiden. Bei DB2 V9
wird kein SORT erforderlich, um Duplikates zu eliminieren.
SELECT DISTINCT LASTNAME FROM EMP
GROUP BY Zusammenlegung bei “non-unique” Indexen
In DB2 V8 passiert das “grouping” NACH dem Sort. In DB2 V9, erfolgt das Gruppieren für GROUP BY und für
DISTINCT ohne Spaltenfunktion; d.h. weniger “getpages” auf der “workfile” und weniger CPU-Zeitverbrauch.
Anm: Das Vermeiden des GROUP BY und DISTINCT SORT ist bereits im “compatibility mode” verfügbar,
benötigt aber einen REBIND.
„Global query optimization“
Der Sinn einer “global query optimization” ist es, die3 Queryperformance dadurch zu steigern, dass in DB2 V9 dem
Optimizer die Möglichkeit gegeben wird, mehr effiziente, potentielle Zugriffspfade zu generieren, die mehrere
Queryteile berücksichtigen.
Diese Änderungen befinden sich innerhalb des DB2 Optimizers und der DB2 “runtime” Komponenten. Es gibt
keine externe Funktion dazu.
select * from dept t1 where exists (select * from emp t2 where t1.deptno = t2.workdept and t2.lastname like 'M%')
“Global query optimization” erlaubt DB2 eine Query als eine Einheit zu betrachten, denn als voneinander
unabhängige Teile (einzelne “query blocks”). Dies wiederum hilft dem Optimizer, indem
o Die Auswirkung eines “query blocks” auf einen anderen betrachtet werden kann
o Eine Neuanordnung/neue Reihenfolge der „query blocks“ berücksichtigt werden kann
Oktober, 2010
23
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
„caseless comparisons“ - haben zu tun mit „INDEX on expressions“
CREATE INDEX EMPL_X1 ON EMPL (lastname);
SELECT
FROM
WHERE
EMPNO, FIRSTNME, LASTNAME, SALARY, BONUS, COMM
EMPL
UPPER(lastname) = ‘COLEMAN’
Kein Treffer: In diesem Beispiel kann DB2 den Index EMPL_X1, da die Nutzung der skalaren Funktion
UPPER eine Indexnutzung verhindert. Dieses Problem kann mit DB2 9 ein fach gelöst werden, indem man
eine “expression” nutzt, um die Daten im Index ausschliesslich in Grosbuchstaben zu speichern.
CREATE INDEX EMPL_X2 ON EMPL UPPER(lastname);
SELECT
FROM
WHERE
EMPNO, FIRSTNME, LASTNAME, SALARY, BONUS, COMM
EMPL
lastname = ‘COLEMAN’
Nun kann DB2 den Index EMPL_X2 nutzen und positive Resultate in der Query erzeugen.
Oktober, 2010
24
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
INDEX on <expression>
CREATE TABLE employee ( id
lastname
firstname
salary
bonus
INTEGER NOT NULL,
VARCHAR(20) NOT NULL,
VARCHAR(20) NOT NULL,
DEC(15,2) NOT NULL,
FLOAT)
Folgender Index:
CREATE INDEX
(
SELECT
WHERE
upper_empname ON employee
UPPER(lastname, 'EN_US'),
UPPER(firstname, 'EN_US'), id )
id FROM
employee
bonus + salary > 100000 ;
CREATE INDEX total_compensation ON employee (salary + bonus)
Restriktionen:
• Jede „key-expression“ muss eine Referenz auf eine Tabellenspalte haben
• Alle Tabellenreferenzen müssen unqualifiziert angegeben sein
• Referenzierte Spalten können nicht vom Typ LOB, XML, DECFLOAT sein.
• Referenzierte Spalten können keine FIELDPROCs oder ein SECURITY LABEL enthalten.
• Eine „Key-expression“ darf folgendes NICHT enthalten: „subquery“, „aggregate function“, eine „not
deterministic function“, eine Funktion mit einer externen Aktion, eine „user-defined function“, eine Referenz auf
eine Sequenz, eine „host variable“, einen „parameter marker“ ein Spezialregister, einen „CASE“-Ausdruck…. usw.
Oktober, 2010
25
DB2 Version 9 (Überblick)
DB2 V9 – Neue Funktionen
Funktionsname
Beschreibung
ADMIN_TASK_LIST
Returns a table with one row for each of the tasks that are defined in the
task list of the administrative task scheduler.
Returns a table with one row for each task in the task list of the
administrative task scheduler that contains the status for the last time the
task was run
Returns the character that corresponds to the ASCII code value that is
specified by the argument
Returns the ASCII version of the character or graphic string argument
Returns a string that represents the collation key of the argument in the
specified collation
Returns a SMALLINT value that indicates whether two arguments are equal
or unordered, or whether one argument is greater than the other
Returns the coefficient of the correlation of a set of number pairs
ADMIN_TASK_STATUS
ASCII_CHR
ASCII_STR
COLLATION_KEY
COMPARE_DECFLOAT
CORRELATION
COVARIANCE or
COVARIANCE_SAMP
DECFLOAT
DECFLOAT_SORTKEY
DECRYPT_BINARY
DIFFERENCE
EBCDIC_CHR
Oktober, 2010
Returns the covariance (population) of a set of number pairs
Returns a DECFLOAT representation of its argument
Returns a binary value that can be used when sorting DECFLOAT values
Returns the decrypted value of an encrypted argument
Returns a value that represents the difference between the sound of two
strings based on applying the SOUNDEX function to the strings
Returns the character that corresponds to the EBCDIC code value that is
specified by the argument
26
DB2 Version 9 (Überblick)
DB2 V9 – Neue Funktionen
Funktionsname
Beschreibung
EBCDIC_STR
EXTRACT
GENERATE_UNIQUE
Returns an EBCDIC version of the string argument
Returns a portion of a date or timestamp based on its arguments
Returns a character string of bit data that is unique compared to any other
execution of the function
Returns a varying-length character string representation of the value of a
session variable
Returns a string that consists of the specified number of leftmost bytes or
the specified string length units
Returns the position at which the first occurrence of an argument starts
within a specified string
Returns a string that is padded on the left with blanks or a specified string
Returns an estimate of the number of months between two arguments
Returns a DECFLOAT value that is the result of normalizing the input
argument
Returns a string value that is the result of normalizing the input Unicode
value OVERLAY Returns a string that is composed of an argument
inserted into another argument at the same position where some number of
bytes have been deleted
Returns a DECFLOAT value that is equal in value (except for any
rounding) and sign to one argument and which has an exponent set to be
equal to the exponent of the second argument
Returns the RID of a row
GETVARIABLE
LEFT
LOCATE_IN_STRING
LPAD
MONTH_BETWEEN
NORMALIZE_DECFLOAT
NORMALIZE_STRING
QUANTIZE
RID
Oktober, 2010
27
DB2 Version 9 (Überblick)
DB2 V9 – Neue Funktionen
Funktionsname
Beschreibung
RIGHT
Returns a string that consists of the specified number of rightmost bytes or
specified code units of a string
Returns a string that is padded on the right with blanks or a specified string
Returns a value that represents the sound of the words in the argument
Returns a timestamp derived from adding the specified interval to a timestamp
Returns an estimated number of intervals of the type defined by the
first argument, based on the difference between two timestamps
Returns a timestamp derived from its arguments
Returns a SMALLINT value that indicates the comparison order of two args
Returns the Unicode (UTF-16) code value of the leftmost character of the
argument as an integer
Returns a string in Unicode (UTF-8 or UTF-16) that represents a Unicode
encoding of the argument
Returns a varying-length character string representation of a timestamp, with
the string in a specified format
Returns an XML sequence that contains an XQuery attribute node for each
non-null argument
Returns an XML value with a single comment node from a string expression
Returns an XML value with a single document node and zero or more nodes
as its children
Returns an XML value from parsing the argument as an XML document
Returns an XML value with a single processing instruction node
RPAD
SOUNDEX
TIMESTAMPADD
TIMESTAMPDIFF
TIMESTAMP_ISO
TOTALORDER
UNICODE
UNICODE_STR
VARCHAR_FORMAT
XMLATTRIBUTES
XMLCOMMENT
XMLDOCUMENT
XMLPARSE
XMLPI
Oktober, 2010
28
DB2 Version 9 (Überblick)
DB2 V9 – Neue Funktionen
Funktionsname
Beschreibung
XMLQUERY
Returns an XML value from the evaluation of an XPath expression against a
set of arguments
Returns an SQL character string or a BLOB value from an XML value
Returns an XML value with a single text node that contains the value of the
argument
XMLSERIALIZE
XMLTEXT
Beispiele:
SELECT
FROM
WHERE
BIRTHDATE, EXTRACT (DAY FROM BIRTHDATE) AS DAY,
EXTRACT (MONTH FROM BIRTHDATE) AS MONTH,
EXTRACT (YEAR FROM BIRTHDATE) AS YEAR
DSN8910.EMP
LASTNAME = 'HAAS' ;
SELECT EMPNO, LASTNAME
FROM
DSN910.EMP
WHERE SOUNDEX(LASTNAME) = SOUNDEX(’Loucesy’);
SELECT
FROM
Oktober, 2010
ERGEBNIS
============================
BIRTHDATE DAY MONTH YEAR
----------------- ------- ----------- -------1933-08-14
14
8
1933
ERGEBNIS
============================
EMPNO
LASTNAME
--------------------------------------000110
LUCCHESI;
SUBSTR(NAME,1,8) AS NAME,
ERGEBNIS
VARCHAR_FORMAT(CREATEDTS,'YYYY-MM-DD-HH24:MI:SS') ============================
SYSIBM.SYSSTOGROUP;
NAME
CREATED_TS
-----------------------------------------SYSDEFLT
2006-08-29-10:16:15
DSN8G910
2006-08-29-11:17:06
………
29
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
OLAP Funktionen / „ranking“
RANK()
liefert eine Anzahl vorangehender “rows” + 1 ( für einen vorgegebenen Wert)
Haben > 1 “rows” denselben Wert, so werden sie alle auf denselben Rang gesetzt
- die nächste “row” zählt alle vorhergehenden Zeilen mit
- es können in der Reihenfolge auch Lücken auftreten
DENSE_RANK() liefert eine Anzahl von unterschiedlichen vorangehendern“rows” + 1
Haben > 1 “rows” denselben Wert, so werden sie alle auf denselben Rang gesetzt
- die nächste “row” zählt alle vorhergehenden Zeilen mit
- es können in der Reihenfolge KEINE Lücken auftreten
ROW_NUMBER() liefert die „row number . ORDER BY liefert die “row number” innerhalb der
angegebebenen Feld(er)
Die Spaltenfunktion OVER() nutzt die Standard DB2 Spaltenfunktionen. Sie liefert kumulative Summen
und/oder laufende Durchschnitte
SELECT
s1.job, s1.id, s1.salary
,
SUM(salary) OVER(ORDER BY job, id) AS sumsal
,
ROW_NUMBER() OVER(ORDER BY job, id) AS R
FROM
staff
s1
ERGEBNIS
WHERE
s1.name LIKE '%s%'
============================
AND
s1.id < 90
JOB ID SALARY SUMSAL R
ORDER BY s1.job , s1.id;
------ --- ------------- ------------ -Clerk 80 13504.60 13504.60 1
Mgr 10 18357.50 31862.10 2
Mgr 50 20659.80 52521.90 3
Oktober, 2010
30
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
OLAP Funktionen / „ranking“
SELECT
,
,
,
FROM
WHERE
AND
ORDER BY
id , years , salary
RANK() OVER(ORDER BY years)
AS rank#
DENSE_RANK() OVER(ORDER BY years)
AS dense#
ROW_NUMBER() OVER(ORDER BY years)
AS row#
staff
id < 100
years IS NOT NULL
ERGEBNIS
years;
====================================
ID YEARS SALARY RANK# DENSE# ROW#
--- ---------- ------------ ---------- ----------- --------30
5
17506.75
1
1
1
40
6
18006.00
2
2
2
90
6
18001.75
2
2
3
10
7
18357.50
4
3
4
70
7
16502.83
4
3
5
20
8
18171.25
6
4
6
50 10
20659.80
7
5
7
•
ORDER BY ist Pflicht
•
ORDER BY beinhaltet auch die “ranking sequence”
•
ORDER BY in der Funktion hat nichts mit dem ORDER BY in der Query zu tun
Oktober, 2010
31
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
OLAP Funktionen / „ranking“
SELECT job , years , id , name
,
SMALLINT( RANK() OVER(ORDER BY job ASC) ) AS asc1
,
SMALLINT( RANK() OVER(ORDER BY job ASC , years ASC) ) AS asc2
,
SMALLINT( RANK() OVER(ORDER BY job ASC´, years ASC,id ASC)) AS asc3
,
SMALLINT( RANK() OVER(ORDER BY job DESC) ) AS dsc1
,
SMALLINT( RANK() OVER(ORDER BY job DESC ,years DESC) ) AS dsc2
,
SMALLINT( RANK() OVER(ORDER BY job DESC ,years DESC ,id DESC) ) AS dsc3
,
SMALLINT( RANK() OVER(ORDER BY job ASC ,years DESC ,id ASC) ) AS mix1
,
SMALLINT( RANK() OVER(ORDER BY job DESC ,years ASC ,id DESC) ) AS mix2
FROM
staff
WHERE
id < 150
AND
years IN (6,7)
AND
job > 'L'
ORDER BY job
ERGEBNIS
,years
========================================================
,id;
JOB Y ID NAME ASC1 ASC2 ASC3 DSC1 DSC2 DSC3 MIX1 MIX2
------- -- --- ---------- ------- -------- ------- ------- -------- -------- ------- -------Mgr 6 140 Fraye
1
1
1
4
6
6
3
4
Mgr 7 10 Sanders 1
2
2 4
4
5
1
6
Mgr 7 100 Plotz
1
2
3 4
4
4
2
5
Sales 6 40 O'Brien 4
4
4 1
2
3
5
2
Sales 6 90 Koonitz 4
4
5
1
2
2
6
1
Sales 7 70 Rothman 4
6
6
1
1
1
4
3
Oktober, 2010
32
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
OLAP Funktionen / „ranking“
id
salary
dept AS dp
(SELECT S1.*
,
RANK() OVER(PARTITION BY dept
ORDER BY salary DESC) AS r1
FROM
staff s1
WHERE id < 80 AND years IS NOT NULL )
WHERE
r1 = 1
ORDER BY dp;
ERGEBNIS
===============
ID SALARY DP
---- ------------- ---50 20659.80 15
10 18357.50 20
40 18006.00 38
SELECT
,
,
FROM
AS
xxx
Hier wird “rank” bestimmt und anschliessend ausgefiltert: “Bestimme das höchste Gehalt je Abteilung”
Nutzung von Partitions („ranking“ über Gehalt innerhalb der Jahre)
SELECT
,
,
id , years
AS YR
salary
RANK() OVER(PARTITION BY years
ORDER BY salary) AS r1
FROM
staff
WHERE
id < 80
AND
years IS NOT NULL
ORDER BY years , salary;
Oktober, 2010
ERGEBNIS
=================
ID YR SALARY R1
---- ---- ------------- ---30 5 17506.75 1
40 6 18006.00 1
70 7 16502.83 1
10 7 18357.50 2
20 8 18171.25 1
50 0 20659.80 1
33
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
OLAP Funktionen / „Row number“
SELECT
,
,
,
,
FROM
WHERE
AND
ORDER BY
•
•
•
id
name
ROW_NUMBER()
ROW_NUMBER()
ROW_NUMBER()
staff
id < 50
years IS NOT
id;
OVER() AS r1
OVER(ORDER BY id) AS r2
OVER(ORDER BY name) AS r3
NULL
ERGEBNIS
====================
ID NAME R1 R2 R3
---- ---------- --- --- --10 Sanders 1 1 4
20 Pernal
2 2 3
30 Marenghi 3 3 1
40 O'Brien
4 4 2
ORDER BY in der Funktion hat nichts mit dem ORDER BY im Output zu tun
ORDER BY ist nicht erforderlich, aber sinnvoll
Wenn nicht eingesetzt, kann das Ergebnis sinnlos sein…
Suche die ersten 3 “rows” – mit der Funktion ROW_NUMBER
SELECT *
FROM
(SELECT
,
,
FROM
WHERE
AND
WHERE r <= 3
ORDER BY id;
Oktober, 2010
id
name
ROW_NUMBER() OVER(ORDER BY id) AS r
staff
id < 100
years IS NOT NULL )AS XXX
ERGEBNIS
==============
ID NAME R
---- ----------- --10 Sanders 1
20 Pernal
2
30 Marenghi 3
34
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
OLAP Funktionen / „Row number“
Suche die ersten 3. bis 6te “row” – mit der Funktion ROW_NUMBER
SELECT *
FROM
(SELECT id
,
name
,
ROW_NUMBER() OVER(ORDER BY id) AS r
FROM
staff
WHERE
id < 100
AND
years IS NOT NULL ) AS XXX
WHERE r BETWEEN 3 AND 6
ORDER BY id;
ERGEBNIS
==============
ID NAME R
---- ----------- --30 Marenghi 3
40 O’Brian 4
50 Hanes
5
70 Rothman 6
Suche die letzten zwei “rows” – mit der Funktion ROW_NUMBER
SELECT *
FROM
(SELECT
,
FROM
WHERE
AND
WHERE r <= 2
ORDER BY id;
•
•
Oktober, 2010
id , name
ROW_NUMBER() OVER(ORDER BY id DESC) AS r
staff
ERGEBNIS
id < 200
==============
years IS NOT NULL ) AS XXX
ID NAME
R
---- ----------- --180 Abrahams 2
200 Schneider 1
ROW_NUMBER ist sinnvoller als die FIRST FETCH Notation
Beware selecting "n" rows if "n+1" row has the same value as "n"
35
DB2 Version 9 (Überblick)
DB2 V9 – Neue Datentypen
BIGINT
SELECT
FROM
BINARY
SQL BIGINT Datentyp(8 Bytes Speicher für Integer Werte) . Eingeführt aus
Kompatibilitätsgründen zu Sprachen wie JAVA, C, C++ und dem SQL Standard.
BIGINT(‘00123456789012’)
SYSIBM.SYSDUMMY1;
Liefert:123456789012
BINARY ist ein binärer String fixer Länge (1 bis 255 Bytes) und VARBINARY ist ein binärer
String variabler Länge (1 bis 32704 Bytes). BINARY und VARBINARY erweitern dei
Unterstützung bestehender Binärstrings(BLOB) und sind mit dem Datentyp BLOB kompatibel.
SELECT
FROM
BINARY(“,1)
SYSIBM.SYSDUMMY1
Liefert: Länge 1 und Wert BX’00’.
SELECT
FROM
BINARY(‘KBH’,5)
SYSIBM.SYSDUMMY1
Liefert: Länge 5 und Wert BX’D2C2C80000’.
DECFLOAT DB2 9 unterstützt “Decimal Floating Point “(DECFLOAT) Datentypen. Somit können
DECFLOAT Daten in DB2 Tabellen geladen und dort verarbeitet werden. Die Regeln dafür
gleichen denen für PackedDecimal.
DECFLOAT (oder “distinct types” basierend auf DECFLOAT) können nicht für “primary key”,
“unique key”, “foreign key “ / “parent key”, als IDENTITY Column, als Spalte in einem
“partitioning key” (PARTITION BY RANGE), als Spalte in einem “index on expression” und
Spalten mit einer FIELDPROC verwendet werden.
Die “scalar functions” COMPARE_DECFLOAT, DECFLOAT, DECFLOAT_SORTKEY,
NORMALIZE_DECFLOAT, QUANTIZE und TOTALORDER wurden eingeführt.
DECFLOAT wird derzeit in Java, Assembler, und REXX™ unterstützt.
Oktober, 2010
36
DB2 Version 9 (Überblick)
DB2 V9 – INSTEADOF Triggers
INSTEAD OF Triggers bieten einen Mechanismus, das Ziel aller “read/write”-Zugriffe einer Applikation zu
vereinheitlichen, indem separate und voneinander verschiedene Aktionen für individuelle “read” und „write“
Aufgaben eingeleitet werden können.
INSTEAD OF Triggers sind Triggers die ANSTATT(INSEAD OF) eines Update, Delete, bzw. eines Insert,
die allesamt den Trigger aktivieren, ablaufen. Im Gegensatz zu anderen Formen von Triggers, die alle auf
Tabellen definiert werden, können INSTEAD OF Triggers nur auf Views definiert werden.
CREATE
CREATE
CREATE
CREATE
TABLE WEATHER (CITY VARCHAR(25), TEMPF DECIMAL(5,2));
VIEW CELSIUS_WEATHER (CITY, TEMPC) AS
SELECT CITY, (TEMPF-32)/1.8 FROM WEATHER
TRIGGER CW_INSERT INSTEAD OF INSERT ON CELSIUS_WEATHER
REFERENCING NEW AS NEWCW FOR EACH ROW
MODE DB2SQL
INSERT INTO WEATHER VALUES (NEWCW.CITY, 1.8*NEWCW.TEMPC+32)
TRIGGER CW_UPDATE INSTEAD OF UPDATE ON CELSIUS_WEATHER
REFERENCING NEW AS NEWCW OLD AS OLDCW FOR EACH ROW
MODE DB2SQL
UPDATE WEATHER W
SET W.CITY = NEWCW.CITY
, W.TEMPF = 1.8*NEWCW.TEMPC+32
WHERE W.CITY = OLDCW.CITY
Die Tabelle WEATHER speichert die Temperaturwerte in Fahrenheit. Der View CELSIUS_WEATHER
ist für die User, die es vorziehen in Celsius Graden zu arbeiten. Der INSTEAD OF Trigger konvertiert die Daten
im CELSIUS_WEATHER View auf Fahrenheit Werte und fügt diese dann in die Tabelle WEATHER ein.
Oktober, 2010
37
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
„optimistic locking“
Fetch
row1
Lock row1
Unlock row1
Fetch
row2
Lock row2
Unlock row2
UPDATE WHERE
CURRENT OF…
Lock row2
Compare by VALUE
UPDATE row2
If values match
Will die Applikation eine FETCH Operation ausführen, um den CURSOR auf eine bestimmte Row zu
positionieren, so führt DB2 folgende Schritte durch:
a. Lock der Row
b. Ausführen des FETCH
c. Freigabe (Release) des Lock
Bei einem „positioned update / delete“ auf der Row passiert folgendes:
a. Lock der Row
b. Neu-Evaluation der Prädikate, um sicherzustellen, dass die Row immer noch zur Resultatstabelle gehört
Oktober, 2010
38
DB2 Version 9 (Überblick)
DB2 V9 – SQL Erweiterungen
DB2 9 – Schema Evolution
•
•
•
•
•
•
•
•
ALTER TABLE RENAME column
ALTER TABLE RENAME index
ALTER index BUFFERPOOL
ALTER column SET DEFAULT
ALTER TABLESPACE LOG NO/YES
ALTER TABLE APPEND YES/NO
CLONE Table
RENAME SCHEMA, OWNER, VCAT und CREATOR
Data Definition on Demand
•
•
•
•
•
•
•
Schnelles Ersetzen einer Tabelle mit einer anderen
Zufügen von Partitions an einen Tablespace je nach Wachstum
Verbesserung des Index-REBUILD Online
Online Reorganisation ohne BUILD2 Phase
Modifikation von “early code” OHNE IPL
ALTER TABLE SET COLUMN default
CREATE und ALTER von STOGROUP SMS Konstrukten
Data warehousing und Reporting
Oktober, 2010
39
DB2 Version 9 (Überblick)
DB2 V9 – Literatur
IBM Redbooks
For information about ordering these publications, see “How to get IBM Redbooks”
Note that some of the documents referenced here may be available in softcopy only.
DB2 9 for z/OS Performance Topics,
SG24-7473
Securing DB2 and Implementing MLS on z/OS,
SG24-6480
LOBs with DB2 for z/OS: Stronger and Faster,
SG24-7270
DB2 UDB for z/OS Version 8 Performance Topics,
SG24-6465
Disaster Recovery with DB2 UDB for z/OS,
SG24-6370
DB2 for z/OS Stored Procedures: Through the CALL and Beyond,
SG24-7083
DB2 UDB for z/OS Version 8: Everything You Ever Wanted to Know, ... and More,
SG24-6079
Communications Server for z/OS V1R8 TCP/IP Implementation Volume 1: Base
Functions, Connectivity, and Routing,
SG24-7339
DB2 9 for z/OS Technical Overview
SG-247330
Oktober, 2010
40
Herunterladen