Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
Database Servers
DB2InformixIngresMS SQLOraclePervasive.SQLPostgreSQLProgressSybase
Desktop Databases
FileMakerFoxProMS AccessParadox
General
General DB TopicsDatabase Theory
Related Topics
Java Development.NET DevelopmentVB DevelopmentMore Topics ...

Database Forum / DB2 Topics / February 2006

Tip: Looking for answers? Try searching our database.

Using a PROCEDURE to EXECUTE other PROCEDUREs

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Brian Tkatch - 01 Feb 2006 18:58 GMT
[DB2/SUN 8.1.6]

I've been asked to time about forty PROCEDUREs in the database, and
keep a history of them for comaprison. So, i figured i'd quickly try it
in the database itself, so anyone could execute it easily. Here's the
basics:

CREATE TABLE Timings_Call
(
Id    INTEGER        GENERATED ALWAYS AS IDENTITY,
Group    VARCHAR(0050),
Name    VARCHAR(0050),
Text    VARCHAR(0256)
)

CREATE TABLE Timings_Log
(
Id        INTEGER        GENERATED ALWAYS AS IDENTITY,
Call        INTEGER,
Start        TIMESTAMP,
Stop        TIMESTAMP
)

In both cases, Id is the PK, and CALL is an FK.

Then tried this:

DROP PROCEDURE Test_Timings_Call

CREATE PROCEDURE Test_Timings_Call
(
OUT    OUT_SQLCODE    INTEGER,
OUT    OUT_SQLSTATE    CHAR(0005)
)
SPECIFIC Test_Timings_Call
BEGIN

DECLARE SQLCODE     INTEGER        DEFAULT 0;
DECLARE SQLSTATE    CHAR(0005)    DEFAULT '00000';
DECLARE Start_Time    TIMESTAMP;
DECLARE Stop_Time    TIMESTAMP;

DECLARE CONTINUE HANDLER FOR
 SQLEXCEPTION, SQLWARNING, NOT FOUND
  BEGIN
   SET OUT_SQLCODE  = SQLCODE;
   SET OUT_SQLSTATE = SQLSTATE;
  END;

FOR Current_Call AS SELECT Id, Text FROM Timings_Call
DO

 SET Start_Time = CURRENT TIMESTAMP;
 EXECUTE IMMEDIATE Current_Call.Text;
 SET Stop_Time = CURRENT TIMESTAMP;

 INSERT INTO Timings_Log(Call, Start, Stop)
  VALUES(Current_Call.Id, Start_Time, Stop_Time);

END FOR;

IF OUT_SQLSTATE IS NULL THEN

 SET OUT_SQLCODE = 0;
 SET OUT_SQLSTATE = '00000';

END IF;

END

Using the CLP: CALL Test_Timings_Call(?, ?)

The problem comes in when its done and i issue a COMMIT or CONNECT
RESET.

SQL0774N  The statement cannot be executed within an ATOMIC compound
SQL

TERMINATE works.

The other issue is speed. I know they don't run this quickly, the
PROCEDURE even took a few minutes, yet:

db2 => SELECT * FROM Timings_log

ID          CALL        START                      STOP
----------- ----------- --------------------------
--------------------------
        81           1 2006-02-01-13.23.16.773902
2006-02-01-13.23.36.204279
        82           2 2006-02-01-13.23.36.207569
2006-02-01-13.24.16.037312
        83           3 2006-02-01-13.24.16.038008
2006-02-01-13.24.16.196470
        84           4 2006-02-01-13.24.16.196978
2006-02-01-13.24.16.452116
        85           5 2006-02-01-13.24.16.452686
2006-02-01-13.24.19.762783
        86           6 2006-02-01-13.24.19.763450
2006-02-01-13.24.24.302802
        87           7 2006-02-01-13.24.24.303569
2006-02-01-13.24.27.670360
        88           8 2006-02-01-13.24.27.671175
2006-02-01-13.24.32.166419
        89           9 2006-02-01-13.24.32.167163
2006-02-01-13.24.34.127496
        90          10 2006-02-01-13.24.34.128259
2006-02-01-13.24.41.198766
        91          11 2006-02-01-13.24.41.199463
2006-02-01-13.24.41.213446
        92          12 2006-02-01-13.24.41.213939
2006-02-01-13.24.41.217095
        93          13 2006-02-01-13.24.41.217468
2006-02-01-13.24.41.254833
        94          14 2006-02-01-13.24.41.255385
2006-02-01-13.24.41.282525
        95          15 2006-02-01-13.24.41.283041
2006-02-01-13.24.41.286024
        96          16 2006-02-01-13.24.41.286396
2006-02-01-13.24.44.756141
        97          17 2006-02-01-13.24.44.756880
2006-02-01-13.24.44.757890
        98          18 2006-02-01-13.24.44.758297
2006-02-01-13.24.51.798671
        99          19 2006-02-01-13.24.51.799408
2006-02-01-13.24.55.223971
       100          20 2006-02-01-13.24.55.224786
2006-02-01-13.24.58.821576
       101          21 2006-02-01-13.24.58.822333
2006-02-01-13.24.58.842636
       102          22 2006-02-01-13.24.58.844363
2006-02-01-13.24.58.866712
       103          23 2006-02-01-13.24.58.867420
2006-02-01-13.24.58.893308
       104          24 2006-02-01-13.24.58.894157
2006-02-01-13.24.58.911025
       105          25 2006-02-01-13.24.58.911564
2006-02-01-13.24.59.689057
       106          26 2006-02-01-13.24.59.689840
2006-02-01-13.24.59.711142
       120          40 2006-02-01-13.24.59.799941
2006-02-01-13.24.59.806985

This is just odd.

B.
Brian Tkatch - 02 Feb 2006 17:38 GMT
I think i figured out the main part of the problem. Many of the
PROCEDUREs DECLARE a GLOBAL TEMPORARY TABLE, and by default i named the
first one Temp_1, and incrementing as required. They are just
intermediate steps, so i figured a better name would probably just be
more confusing.

Being the CURSORs are DECALREd WITH RETURN TO CLIENT, it is holding a
lock on the TABLE, and when the next PROCEDURE tries to DECLARE it with
the same name (WITH REPLACE), it causes an error that i am trying to
DROP a TABLE that is still needed.

As simple example:

DROP PROCEDURE AA
CREATE PROCEDURE AA()
BEGIN
DECLARE GLOBAL TEMPORARY TABLE A(A INT) NOT LOGGED WITH REPLACE;
BEGIN
 DECLARE A CURSOR WITH RETURN TO CLIENT FOR SELECT * FROM SESSION.A;
 OPEN A;
END;
END

DROP PROCEDURE BB
CREATE PROCEDURE BB() BEGIN CALL AA; CALL AA; END

CALL BB

DROP PROCEDURE AA
DROP PROCEDURE BB
COMMIT

results in

SQL0910N  The SQL statement cannot access an object on which a
modification is pending.  SQLSTATE=57007

Which is understandable.

Without renaming all the objects, is there a way to test this?

B.
Brian Tkatch - 03 Feb 2006 19:25 GMT
OK, got it to work. Changed the PROCEDURE to execute one comamnd at a
time, and used the shell.

DROP PROCEDURE Test_Timings_Call

CREATE PROCEDURE Test_Timings_Call(IN_Id INT)
SPECIFIC Test_Timings_Call
BEGIN

DECLARE Start_Time    TIMESTAMP;
DECLARE Stop_Time    TIMESTAMP;
DECLARE Query        VARCHAR(256);

SELECT    Text INTO Query FROM Timings_Call
WHERE Timings_Call.Id = IN_Id;

SET Start_Time = CURRENT TIMESTAMP;
EXECUTE IMMEDIATE Query;
SET Stop_Time = CURRENT TIMESTAMP;

INSERT INTO Timings_Log(Call, Start, Stop)
 VALUES(IN_Id, Start_Time, Stop_Time);

END

eval "$(db2 -x "SELECT 'db2 +o \"CALL Test_Timings_Call(' || CHAR(Id)
|| ')\"' FROM Timings_Call")"

B.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.