(*) 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