Monday, April 22, 2013

How to run dynamic SQL using creator's authorizations

How to run dynamic SQL using creator's authorizations

We can have 2 types of SQLs in a proc.
1) Static
2) Dynamic

One very important difference bw them is that while executing the procedure,for Static SQLs DB2 uses  authorization ID of the package owner as the value to be used for authorization  . But in dynamic SQL , DB2 uses authorization ID of the package executor as the value to be used for authorization.
We can override this behaviorfor dynamic SQLs by using dymanic rules bind.

Bind behavior
At run-time, DB2 uses all the rules that apply to static SQL for authorization and qualification.
That is, take the authorization ID of the package owner as the value to be used for authorization checking of dynamic SQL
statements and the package default qualifier for implicit qualification of unqualified object references within dynamic SQL statements.

call set_routine_opts(get_routine_opts() || ' DYNAMICRULES BIND')@
DROP PROCEDURE SCHEMA.REFRESH_MQT@

CREATE PROCEDURE SCHEMA.REFRESH_MQT(IN IN_TABLE_NAME VARCHAR(128),
                OUT o_sqlcode integer,
                OUT o_sqlstate CHAR(5),
                OUT o_MESSAGE VARCHAR(255))
LANGUAGE SQL
MODIFIES SQL DATA
DYNAMIC RESULT SETS 0
P1:BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT '     ';
DECLARE stmt VARCHAR(228) ;

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
EH: BEGIN
  get diagnostics EXCEPTION 1 o_MESSAGE = MESSAGE_TEXT;
        VALUES (SQLSTATE,SQLCODE) INTO o_sqlstate, o_sqlcode;
END EH;

SET stmt='SET INTEGRITY FOR
SCHEMA.'||TRIM(IN_TABLE_NAME)||' IMMEDIATE CHECKED';
EXECUTE IMMEDIATE stmt;

SET stmt='REFRESH TABLE
SCHEMA.R_'||TRIM(IN_TABLE_NAME);
EXECUTE IMMEDIATE stmt;

END P1
@

-- Restore the default bindrules
call set_routine_opts(NULL)@

How to pass parameters in command line

How to pass parameters in command line:

 We can use this to test procedure code from command prompt.

DECLARE GLOBAL TEMPORARY TABLE SESSION.MFS  (
    TABLE_ID                   INTEGER      NOT NULL,
    RUN_ID                     DECIMAL(10)  NOT NULL,
    BUSINESS_DATE              DATE         NOT NULL,
    LOAD_TIME_START            TIMESTAMP,
    LOAD_TIME_END              TIMESTAMP
    )
WITH REPLACE
ON COMMIT PRESERVE ROWS
NOT LOGGED;

BEGIN ATOMIC
  DECLARE busdate DATE ;
  SET busdate = '2013-01-31' ;
  insert into SESSION.MFS select table_id,run_id,business_date,load_time_start,load_time_end from liquidity.met_feed_status where business_date= busdate;
END

select * From SESSION.MFS

How to covert all date values with ISO date format

How to covert all date values with ISO date format "YYYY-MM-DD":

/user/home>db2 "values(current date)"
 1
----------
04/13/2011

  1 record(s) selected.
which db2
/root/ibmdb2/PROJ/sqllib/9.5.4/exec/sqllib/bin/db2
/user/home>cd /root/ibmdb2/PROJ/sqllib/9.5.4/exec/sqllib//bnd
/root/ibmdb2/PROJ/sqllib/9.5.4/exec/sqllib//bnd@>db2 bind @db2ubind.lst datetime ISO

LINE    MESSAGES FOR db2ubind.lst
------  --------------------------------------------------------------------
        SQL0061W  The binder is in progress.

LINE    MESSAGES FOR db2ueiwi.bnd
------  --------------------------------------------------------------------
2239   SQL0204N  "SYSTEM.SYSUSERAUTH" is an undefined name.
                  SQLSTATE=42704
2243   SQL0204N  "SYSTEM.SYSUSERAUTH" is an undefined name.
                  SQLSTATE=42704

LINE    MESSAGES FOR db2clpnc.bnd
------  --------------------------------------------------------------------
        SQL0595W  Isolation level "NC" has been escalated to "UR".
                  SQLSTATE=01526

LINE    MESSAGES FOR db2arxnc.bnd
------  --------------------------------------------------------------------
        SQL0595W  Isolation level "NC" has been escalated to "UR".
                  SQLSTATE=01526

LINE    MESSAGES FOR db2ats_sps.bnd
------  --------------------------------------------------------------------
1168   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1198   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1229   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1477   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1494   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1512   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1550   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1674   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1691   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1710   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1727   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1890   SQL0204N  "SYSTOOLS.ADMINTASKSTATUS" is an undefined name.
                  SQLSTATE=01532
1945   SQL0204N  "SYSTOOLS.ADMINTASKSTATUS" is an undefined name.
                  SQLSTATE=01532
1957   SQL0204N  "SYSTOOLS.ADMINTASKS" is an undefined name.
                  SQLSTATE=01532
1974   SQL0204N  "SYSTOOLS.ADMINTASKSTATUS" is an undefined name.
                  SQLSTATE=01532

LINE    MESSAGES FOR db2ubind.lst
------  --------------------------------------------------------------------
        SQL0091N  Binding was ended with "0" errors and "19"
                  warnings.


/user/home@>db2 "values(current date)"

1
----------
2011-04-13

  1 record(s) selected.

How to covert rows to columns

How to covert rows to columns:

We have created a sample table for this exercise:

CREATE TABLE SCHEMA.column_to_row (line# int, word varchar(100));
insert into SCHEMA.column_to_row values (1,'The'), (1,'Horse'),(1,'is'), (1,'white');
insert into SCHEMA.column_to_row values (2,'The'), (2,'Rose'),(2,'is'), (2,'Red');
select * from SCHEMA.column_to_row with ur;

You can use XML elements for converting rows to columns:
 
SELECT line#, replace(replace(xml2clob(xmlagg(xmlelement(NAME a, s.word))),'<A>',''),'</A>',' ,')
FROM SCHEMA.column_to_row s
where line#=1
GROUP BY line#