Presentation is loading. Please wait.

Presentation is loading. Please wait.

Oct 6, 2009 1:00 p.m. – 2:00 p.m. Platform: DB2 for LUW Serge Rielau IBM Canada Session: C06 SQL PL in DB2 9.7 all grown up.

Similar presentations


Presentation on theme: "Oct 6, 2009 1:00 p.m. – 2:00 p.m. Platform: DB2 for LUW Serge Rielau IBM Canada Session: C06 SQL PL in DB2 9.7 all grown up."— Presentation transcript:

1 Oct 6, 2009 1:00 p.m. – 2:00 p.m. Platform: DB2 for LUW Serge Rielau IBM Canada Session: C06 SQL PL in DB2 9.7 all grown up

2 2 Agenda Motivation Virtual tour Emphasis on value, not on syntax details

3 3 Evolution of SQL PL VersionFocus 7Initial release 8.1Performance 8.2Native SQL PL 9Performance 9.5App dev. 9.7Performance ?

4 4 What’s in it for me? Not just new syntax enhancements here and there Reducing TCO Where are the savings Application development cost Application maintenance cost Enablement cost

5 5 Audience Poll Where does it hurt ?

6 6 Overview Full SQL PL support across the board UDFs, Triggers, Blocks Data structures Rows Arrays of rows (local and global) Associative arrays Modules Cursor data type Data type anchoring Global named exceptions Built-in module library CALL statement CONSTANT

7 7 Full SQL PL across the board Inlined vs. compiled SQL PL Inlined: UDF and triggers inlined in SQL statement Compiled: SP is compiled into a separate object Inlined Performane advantage (no context switch between SQL and SQL PL) Several SQL PL language features not supported: Cursor and result set handling Error handling Dynamic SQL Compiled Full SQL PL Available so far in SPs only

8 8 Vnext: Full SQL PL in more places DB2 9.5DB2 9.7 SPs Scalar UDFsLimited DPF Table UDFs Row TriggersNon DPF Stmt Triggers Block

9 9 Scenario for running example -- Materials table CREATE TABLE materials (id INTEGER, name VARCHAR(100), description VARCHAR(256)) INSERT INTO materials VALUES (1, ‘2X4', ’12-feet long two by four’), (3, ‘nail', ’2 inch drywall nail’), (7, ‘drywall', ’ 8x12-feet drywall sheet’) @ -- Suppliers table CREATE TABLE suppliers (id INTEGER, name VARCHAR(100), email VARCHAR(100)) INSERT INTO suppliers VALUES (74, ‘Bob the builder', ’bob@bob.com’), (33, ‘Steel&Lumber', ’sales@sandl.com’) @ -- Supplier/Material table CREATE TABLE supProd (suppId INTEGER, prodId INTEGER, qty INTEGER) INSERT INTO supProd VALUES (74, 3, 12000), (74, 7, 850), (33, 7, 0) @ Problem statement “Define a trigger on materials table such that when a new material is inserted, the trigger will send email to each of the suppliers of that material to request a quote”

10 10 Full SQL PL: example CREATE TRIGGER sendQuoteReqs AFTER INSERT ON materials REFERENCING new AS new FOR EACH ROW BEGIN DECLARE suppId INTEGER; DECLARE suppName VARCHAR (128); DECLARE suppEmail VARCHAR (128); DECLARE cur1 CURSOR CONSTANT CURSOR FOR SELECT id, name, email FROM suppliers s, supProd sp WHERE s.id = sp.suppId AND new.id = sp.prodId; DECLARE CONTINUE HANDLER FOR email.EmalNotSent INSERT INTO errorLog VALUES (‘Failed to send email to supplier ‘ || suppName); OPEN cur1; -- Send email to each supplier of this product FETCH cur1 INTO suppId, suppName, suppEmail; WHILE cur1 IS FOUND DO CALL sendQuoteRequestEmail(suppId, suppName, suppEmail, new.id, new.name); FETCH cur1 INTO suppId, suppName, suppEmail; END WHILE; END @

11 11 ROW data type Ubiquitous “struct” or “record” type Even more natural in database procedural language What can be done with rows Single variable to fetch and insert Can pass a parameters and return from UDFs Can define global and module variables Can use them to build arrays of rows (lightweight tables + compact array syntax)

12 12 ROW data type In previous example, unit of info was supplier But supplier info split into several variables Must carry variables around on all operations on supplier However, when dealing with materials, DB2 didn’t create a variable per column. It created a variable for the whole row CREATE TRIGGER… REFERENCING new AS new … Row types let users do the same

13 13 ROW data type: example CREATE TYPE supplierType AS ROW ( suppId INTEGER, suppName VARCHAR (100), suppEmail VARCHAR (100) ) @ CREATE TRIGGER sendQuoteReqs AFTER INSERT ON materials REFERENCING new AS new FOR EACH ROW BEGIN DECLARE supp supplierType; DECLARE cur1 CURSOR CONSTANT CURSOR FOR SELECT id, name, email FROM suppliers s, supProd sp WHERE s.id = sp.suppId AND new.id = sp.prodId;... FETCH cur1 INTO supp; … CALL sendQuoteRequestEmail(supp, new.id, new.name); … END @

14 14 Anchored row type We didn’t have to specify a type for the trigger transition variable All DB2 needs to know is what table the trigger is associated with … AFTER INSERT ON materials … Why not let the user do the same for row types ? CREATE TYPE supplierType AS ROW ( suppId INTEGER, suppName VARCHAR (128), suppEmail VARCHAR (128) ) @ CREATE TYPE supplierRow1 AS ANCHOR ROW suppliers @

15 15 Anchored row type: example But… why define a type at all? CREATE TRIGGER sendQuoteReqs AFTER INSERT ON materials REFERENCING new AS new FOR EACH ROW BEGIN DECLARE supp ANCHOR ROW suppliers; … END @

16 16 Anchored row type Available in: Local variables Global variables Parameters and return types Value Less code to write Code automatically in-sync with data Can anchor on tables and or cursors

17 17 Anchored row type: cursor anchor New requirement: in addition to supplier data, must fetch quantity CREATE TRIGGER sendQuoteReqs AFTER INSERT ON materials REFERENCING new AS new FOR EACH ROW BEGIN DECLARE cur1 CURSOR CONSTANT CURSOR FOR SELECT id, name, email, qty FROM suppliers s, supProd sp WHERE s.id = sp.suppId AND new.id = sp.prodId; DECLARE suppAndQty ANCHOR ROW cur1; … FETCH cur1 INTO suppAndQty; … END

18 18 Scalar anchoring Same concept, but at scalar level Can anchor on a column or on another variable CREATE TYPE supplierType2 AS ROW ( suppId ANCHOR supplier.id, suppName ANCHOR supplier.name, suppEmail ANCHOR supplier.email ) @ CREATE VARIABLE id ANCHOR supplier.id @ CREATE FUNCTION getEmail(id ANCHOR supplier.id) RETURN ANCHOR supplier.id … @

19 19 Associative Arrays: example New requirement: keep track of how many quotes we’ve requested from each supplier CREATE TYPE reqList AS INT ARRAY[INT] @ CREATE VARIABLE reqsPerSupp reqList @... CREATE TRIGGER … … -- Send email to each supplier of this product FETCH cur1 INTO suppAndQty; WHILE cur1 IS FOUND DO CALL sendQuoteRequestEmail(suppAndQty, new.id, new.name); SET reqsPerSupp[suppId] = CASE WHEN reqsPerSupp[suppId] IS NULL THEN 1 ELSE reqsPerSupp[suppId] + 1 END CASE; FETCH cur1 INTO suppAndQty; END WHILE;

20 20 Associative Arrays Conventional arrays are “dense” CREATE TYPE arrTyp AS INT ARRAY[2000] @ … DECLARE a arrTyp; SET a[1500] = 100; /* a has now 1500 elements */ Associative arrays are “sparse” CREATE TYPE arrTyp AS INT ARRAY[INT] @ … DECLARE a arrTyp; SET a[1500] = 100; /* a has now 1 element */

21 21 Associative Arrays Index can be any integer type or VARCHAR of any length Element can be any scalar type or a row type CREATE TYPE arrType AS suppTyp ARRAY[VARCHAR(100)]; … DECLARE var arrType; SET var[‘Supplier One’] = supp; /* supp is a row */ Can use Scalar Anchoring on both element and index CREATE TYPE suppArr AS ANCHOR ROW suppliers ARRAY[ANCHOR suppliers.id]@ Can be used in variables, parameters, UDF return type and global/module variables

22 22 Modules Module = bundle of several related objects SPs, UDFs, global variables and cursors, types, conditions Similar to a class in OO languages (but single instance) Bundle canned applications, libraries Impose structure on medium-sized and large apps Use module to “hide” implementation

23 23 Modules: example CREATE OR REPLACE MODULE hideArray @ ALTER MODULE hideArray ADD TYPE reqList AS INT ARRAY[ANCHOR TO suppliers.id] @ ALTER MODULE hideArray ADD VARIABLE reqsPerSupp reqList @ ALTER MODULE hideArray PUBLISH PROCEDURE incSuppCount(IN suppId ANCHOR suppliers.id) BEGIN SET reqsPerSupp[suppId] = CASE WHEN reqsPerSupp[suppId] IS NULL THEN 1 ELSE reqsPerSupp[suppId] + 1 END CASE; END @

24 24 Modules - benefits Code organization/structure Related routines share variables, types and conditions Scoping Possibilities of name conflicts CALL mySchema.myModule.myProc() Several users can deploy same module under different schema, with no name clashes Information hiding Each object can be “public” or “private” Global privilege control Instead of granting/revoking on each SP, UDF or variable

25 25 Modules: module specification CREATE OR REPLACE MODULE myMod @ ALTER MODULE myMod PUBLISH CONDITION badCode @ ALTER MODULE myMod PUBLISH FUNCTION myFunc(val1 ANCHOR myTab.col1) RETURNS myRowTyp @ ALTER MODULE myMod PUBLISH PROCEDURE myProc(OUT parm1 ANCHOR myTab.col2) @ GRANT EXECUTE ON MODULE myMod TO joe @ Grants user joe execute privilege on all routines and access to all variables and types in myMod

26 26 Modules: module implementation ALTER MODULE myMod DROP BODY @ ALTER MODULE myMod ADD VARIABLE pkgVar ANCHOR myTab.col1 @ ALTER MODULE myMod ADD FUNCTION myFunc() RETURNS INT BEGIN DECLARE var1 INT; SELECT * INTO var1 FROM myTab WHERE col1 < pkgVar; IF (var1 > maxVal) THEN SIGNAL badCode; END IF; RETURN var1; END @ ALTER MODULE myMod ADD PROCEDURE myProc(OUT parm1 ANCHOR myTab.col2) BEGIN DECLARE var1 INT; DECLARE EXIT HANDLER FOR badCode BEGIN END; SET var1 = myFunc(); END @

27 27 CURSOR data type Cursors are values Pass cursors as parameters Cursor global variable Function that returns a cursor Cursor OUT parameters can be returned to JDBC clients Parameterized cursors Cursor predicates Can open cursor in a procedure and assign to global variable. Cursor becomes a global cursor. Closed when there are no variables referencing it.

28 28 CURSOR data type: example CREATE FUNCTION getSupps(prodId IN ANCHOR materials.id) RETURNS CURSOR BEGIN DECLARE cur CURSOR; SET cur = CURSOR FOR SELECT id, name, email FROM suppliers s, supProd sp WHERE s.id = sp.suppId AND sp.prodId = prodId; OPEN cur; RETURN cur; END % CREATE PROCEDURE sendEmails (cur CURSOR) BEGIN DECLARE varCur myCurTyp; DECLARE supp ANCHOR ROW suppliers; -- Send email to each supplier of this product FETCH cur INTO supp; WHILE cur IS FOUND DO CALL sendQuoteRequestEmail(supp); FETCH cur INTO supp; END WHILE; END %

29 29 CURSOR data type: example CREATE TRIGGER sendQuoteReqs AFTER INSERT ON materials REFERENCING new AS new FOR EACH ROW BEGIN DECLARE CONTINUE HANDLER FOR email.EmalNotSent INSERT INTO errorLog VALUES (‘Failed to send email to supplier ‘ || suppName); DECLARE cur CURSOR; SET cur = getSupps(new.id); CALL sendEmails(cur); END @

30 30 Anonymous blocks Server-side SQL scripting One-time maintenance operations on the db Quick reports Example: validate shipments and report errors BEGIN FOR s IN SELECT * FROM localShipments DO BEGIN DECLARE CONTINUE HANDLER FOR shipments.invalidOrigin CALL print('ERROR: Bad shipment. Date =' || s.date || ', Origin = ' || s.origin); CALL validateShipment (‘|’ || s.origin || s.description); END; END FOR; END Cached on first execution Can use parameter markers

31 31 CALL enhancements Default values for parameters CREATE PROCEDURE logError (id INT, message VARCHAR(200) DEFAULT ‘No message’) … The following statements are equivalent CALL logError(10) CALL logError(12, DEFAULT) Named parameters CALL logError(message => ‘limit exceeded’, id => 31)

32 32 CONSTANT Constant global variables: application-wide constants CREATE VARIABLE maxWithdrawal FLOAT CONSTANT 500 @ Module version: ALTER MODULE atm PUBLISH VARIABLE maxWithdrawal FLOAT CONSTANT 500 @ Constant local variables DECLARE maxArrSize INT CONSTANT 256;

33 33 Conclusions SQL PL evolving from simple procedural control language to full programming language Reduced app dev, app maintenance and app enablement Note: DB2 also provides full PL/SQL support

34 34 Q&A ?

35 35 Serge Rielau IBM Canada srielau@ca.ibm.com Session: C06 SQL PL in DB2 9.7 all grown up


Download ppt "Oct 6, 2009 1:00 p.m. – 2:00 p.m. Platform: DB2 for LUW Serge Rielau IBM Canada Session: C06 SQL PL in DB2 9.7 all grown up."

Similar presentations


Ads by Google