I have this relatively simple rpg program where the line exec sql workKeySocWorkCodesCur for 500 rows into:childWorkKeyArray;
is performing very slowly. It tales about 6 seconds to execute each time. What I dont understand is when I run this query interactively or when I tested this statement in a separate RPG containing only this statement (by substituting the host variable values), it seems to complete in less than a second. So what difference in this program might be causing it to slow down?
**FREE
// ******************************************************************
// Globals
// ******************************************************************
dcl-ds parentWorkKeyArray qualified dim(500);
workKey like(P_IacWrkKey.WorkKey) inz(0);
workIsRef char(1) inz (*blanks);
workKeyParentKey like(P_IacWrkKey.WorkKey) inz(0);
end-ds;
dcl-ds childWorkKeyArray qualified dim(500);
workKey like(P_IacWrkKey.WorkKey) inz(0);
workIsRef char(1) inz (*blanks);
mergedToWorkKey like(P_IacWrkKey.WorkKey) inz(0);
end-ds;
dcl-ds ISWCDUPDS Extname('POTISWCDUP') qualified;
end-ds;
dcl-s merged ind inz(*off);
dcl-s multipleActiveWorksPresent ind inz(*off);
dcl-s countOfNonReferencedWorks int(5);
dcl-s index int(5) inz(1);
dcl-s isChildWorkKeySameAsParent int(5);
dcl-s isChildWorkKeyMergedToParent int(5);
dcl-s socCodeFound ind inz(*off);
dcl-s socCodeTBMFound ind inz(*off);
dcl-s pos int(5);
dcl-s gCheckSqlKeyField varchar(128);
dcl-s check char(3);
dcl-s socWorkCodeString like(ISWCDUPDS.ISWCSOCWCD);
dcl-s iswcReference like(ISWCDUPDS.ISWC);
dcl-c firstElement const(1) ;
// ------------------------------------------------------------------------
// Program procedure flow
// ------------------------------------------------------------------------
dcl-pi *n end-pi;
exec sql SET OPTION COMMIT = *NONE ;
if not BeginProgram();
ErrorHandling();
return;
elseif not ProcessRequest();
ErrorHandling();
return;
endif;
*inlr = *On;
return ;
// ------------------------------------------------------------------------
// * Procedure name: ProcessRequest
// * Purpose: Process Request
// * Returns: True or False
// *------------------------------------------------------------------------
dcl-proc ProcessRequest;
dcl-pi *N ind end-pi;
dcl-s referenceType char(10);
exec sql close potiswccur;
exec sql open potiswccur;
exec sql fetch first from potiswccur into :ISWCDUPDS;
dow (sqlcod = 0);
if not GetIswcWorkKeys();
return cFalse;
endif;
referenceType = 'ISWC';
if not CheckIfISWCMergdToISWCTBM(referenceType);
return cFalse;
endif;
GetWorkKeyString(referenceType);
if not GetSocietyWorkCodeWorkKeys();
return cFalse;
endif;
referenceType = 'SOC';
if not CheckIfISWCMergdToISWCTBM(referenceType);
return cFalse;
endif;
GetWorkKeyString(referenceType);
UpdateRecord();
exec sql fetch next from potiswccur into :ISWCDUPDS;
enddo;
return cTrue;
end-proc ProcessRequest;
// ------------------------------------------------------------------------
// * Procedure name: getWorkKeyStringSocCode
// * Purpose: Combines all work keys into a string delimited by '|'
// * Returns: True or False
// *------------------------------------------------------------------------
dcl-proc getWorkKeyString;
dcl-pi *n ind ;
referenceType char(10);
end-pi;
index = 1;
dow (index < 500);
if ( parentWorkKeyArray(index).workKey <> 0);
if (referenceType = 'ISWC');
if (index > 1);
ISWCDUPDS.IWKEY_ISWC = %Trim(ISWCDUPDS.IWKEY_ISWC) + '|';
endif;
ISWCDUPDS.IWKEY_ISWC = %Trim(ISWCDUPDS.IWKEY_ISWC) + %char(parentWorkKeyArray(index).workKey);
else;
if (index > 1);
ISWCDUPDS.IWKEYSOCD = %Trim(ISWCDUPDS.IWKEYSOCD) + '|';
endif;
ISWCDUPDS.IWKEYSOCD = %Trim(ISWCDUPDS.IWKEYSOCD) + %char(parentWorkKeyArray(index).workKey);
endif;
endif;
if ( childWorkKeyArray(index).workKey <> 0);
if (referenceType = 'ISWC');
if (index > 1);
ISWCDUPDS.IWKEYMISWC = %Trim(ISWCDUPDS.IWKEYMISWC) + '|';
endif;
ISWCDUPDS.IWKEYMISWC = %Trim(ISWCDUPDS.IWKEYMISWC) + %char(childWorkKeyArray(index).workKey) ;
else;
if (index > 1);
ISWCDUPDS.IWKEYSOCDM = %Trim(ISWCDUPDS.IWKEYSOCDM) + '|' ;
endif;
ISWCDUPDS.IWKEYSOCDM = %Trim(ISWCDUPDS.IWKEYSOCDM) + %char(childWorkKeyArray(index).workKey) ;
endif;
endif;
index = index + 1;
enddo;
return cTrue;
end-proc;
dcl-proc GetSocietyWorkCodeWorkKeys;
dcl-pi *n ind ;
end-pi;
clear parentWorkKeyArray;
clear childWorkKeyArray;
// declare cursor for fetching work keys of ISWC
socWorkCodeString = ISWCDUPDS.ISWCSOCWCD ;
exec sql close workKeySocWorkCodesCur;
exec sql open workKeySocWorkCodesCur;
exsr checkSQLCodeSR;
exec sql fetch workKeySocWorkCodesCur for 500 rows into :parentWorkKeyArray;
exsr checkSQLCodeSR;
// declare cursor for fetching work keys of ISWC TBM
socWorkCodeString = ISWCDUPDS.TMSOCWRKCD ;
exec sql close workKeySocWorkCodesCur;
exec sql open workKeySocWorkCodesCur;
exsr checkSQLCodeSR;
exec sql fetch workKeySocWorkCodesCur for 500 rows into :childWorkKeyArray;
exsr checkSQLCodeSR;
return cTrue;
begsr checkSQLCodeSR;
if not CheckSqlCode(sqlcode:sqlwarn(1):gCheckSqlKeyField);
return cFalse;
endif;
endsr;
end-proc;
//----------------------------------------------------------------------------------------------
// Procedure name: GetIswcWorkKeys
// Purpose: Fetches work keys to which ISWC and ISWC_TBM are allocated and
// places them in parentWorkKeyArray and childWorkKeyArray respectively
// Returns: Successful/unsuccessful action
//----------------------------------------------------------------------------------------------
dcl-proc GetIswcWorkKeys;
dcl-pi *n ind ;
end-pi;
clear parentWorkKeyArray;
clear childWorkKeyArray;
// declare cursor for fetching work keys of ISWC
iswcReference = ISWCDUPDS.ISWC ;
exec sql close workKeyISWCCur;
exec sql open workKeyISWCCur;
exsr checkSQLCodeSR;
exec sql fetch workKeyISWCCur for 500 rows into :parentWorkKeyArray;
exsr checkSQLCodeSR;
// declare cursor for fetching work keys of ISWC TBM
iswcReference = ISWCDUPDS.ISWC_TBM ;
exec sql close workKeyISWCCur;
exec sql open workKeyISWCCur;
exsr checkSQLCodeSR;
exec sql fetch workKeyISWCCur for 500 rows into :childWorkKeyArray;
exsr checkSQLCodeSR;
return cTrue;
begsr checkSQLCodeSR;
if not CheckSqlCode(sqlcode:sqlwarn(1):gCheckSqlKeyField);
ErrorHandling();
return cFalse;
endif;
endsr;
end-proc;
//---------------------------------------------------------------------
// Procedure name: checkIfISWCMergdToISWCTBM
// Purpose: checks if both sides of the pair are merged
// Returns: Successful/unsuccessful action
//---------------------------------------------------------------------
dcl-proc checkIfISWCMergdToISWCTBM;
dcl-pi *n ind;
referenceType char(10);
end-pi;
dcl-s workKeysFound ind;
dcl-s workKeysTBMFound ind;
dcl-s multipleActiveWorksPresent ind;
dcl-s merged ind;
if not checkNumberOfActiveWorksOnISWC(multipleActiveWorksPresent);
return cFalse;
endif;
if not multipleActiveWorksPresent;
if not checkIfWorkCodesFound(workKeysFound: workKeysTBMFound: referenceType);
return cFalse;
endif;
if (workKeysFound and workKeysTBMFound);
checkIfChildCompletelyMergedToParent(merged);
endif;
if merged;
if referenceType = 'ISWC';
ISWCDUPDS.ISWCSORM = 'MERGED';
else;
ISWCDUPDS.SOCCSORM = 'MERGED';
endif;
else;
if referenceType = 'ISWC';
ISWCDUPDS.ISWCSORM = 'NOT MERGED';
else;
ISWCDUPDS.SOCCSORM = 'NOT MERGED';
endif;
endif;
endif;
return cTrue;
end-proc;
//------------------------------------------------------------------------------------------
// Procedure name: checkIfChildCompletelyMergedToParent
// Purpose: checks if child merged to parent
// Returns: Successful/unsuccessful action
//-------------------------------------------------------------------------------------------
dcl-proc checkIfChildCompletelyMergedToParent;
dcl-pi *n ind ;
merged ind;
end-pi;
clear isChildWorkKeyMergedToParent;
clear isChildWorkKeySameAsParent;
index = 1;
dow (index < 500 and childWorkKeyArray(index).workKey <> 0);
merged = *on;
// check if tbm work key is same as one of the parent work key
isChildWorkKeySameAsParent = %lookup(childWorkKeyArray(index).workKey : parentWorkKeyArray(*).workKey) ;
// if work key not same as one of parent work key, check if they are merged to parent ?
if (isChildWorkKeySameAsParent = 0);
if (childWorkKeyArray(index).mergedToWorkKey <> 0); //possible only if child work key is referenced
// check if the child is merged to a parent key - firstly check if child is merged to one of the parent keys.
isChildWorkKeyMergedToParent = %lookup(childWorkKeyArray(index).mergedToWorkKey : parentWorkKeyArray(*).workKey) ;
if (isChildWorkKeyMergedToParent > 0);
ISWCDUPDS.message = %trim(ISWCDUPDS.message) + 'ISWC TBM Work key ' + %char(childWorkKeyArray(index).workKey) + ' merged to ISWC work key ' + %char(childWorkKeyArray(index).mergedToWorkKey) + '||';
else;
// if not direclty merged to one of the parent keys, check if the child is merged to the parent of parent - parentWorkKeyArray(*).workKeyParentKey!
isChildWorkKeyMergedToParent = %lookup(childWorkKeyArray(index).mergedToWorkKey : parentWorkKeyArray(*).workKeyParentKey) ;
if ( isChildWorkKeyMergedToParent > 0 );
ISWCDUPDS.message = %trim(ISWCDUPDS.message) + 'ISWC TBM Work key ' + %char(childWorkKeyArray(index).workKey) + ' and ISWC Work key '+
%char(parentWorkKeyArray(isChildWorkKeyMergedToParent).workKey) + ' merged to '+ %char(parentWorkKeyArray(isChildWorkKeyMergedToParent).workKeyParentKey);
endif;
endif;
endif;
else; // if tbm work key and iswc work key are same, it means both iswc's present on same work key.
if ( check = 'SOC');
ISWCDUPDS.message = %trim(ISWCDUPDS.message) + 'Society work code and Society work code TBM both present on work key ' + %char(childWorkKeyArray(index).workKey) + '||';
else;
ISWCDUPDS.message = %trim(ISWCDUPDS.message) + 'ISWC and ISWC_TBM both present on work key ' + %char(childWorkKeyArray(index).workKey) + '||';
endif;
endif;
if ( isChildWorkKeySameAsParent = 0 and isChildWorkKeyMergedToParent = 0);
merged = *off ;
leave;
endif;
index = index + 1;
enddo;
return cTrue;
end-proc;
//------------------------------------------------------------------------------------------
// Procedure name: checkIfWorkCodesFound
// Purpose: checks if workkeys present for incoming and target references
// Returns: Successful/unsuccessful action
//-------------------------------------------------------------------------------------------
dcl-proc checkIfWorkCodesFound;
dcl-pi *n ind;
socCodeFound ind;
socCodeTBMFound ind;
referenceType char(10);
end-pi;
socCodeFound = *on;
socCodeTBMFound = *on;
if ( parentWorkKeyArray(firstElement) = *blanks );
socCodeFound = *off;
if referenceType = 'ISWC';
ISWCDUPDS.message = %trim(ISWCDUPDS.message) + ' ISWC not found in ICE ||' ;
else;
ISWCDUPDS.message = %trim(ISWCDUPDS.message) + ' Soc. work codes not found in ICE ||' ;
endif;
endif;
if ( childWorkKeyArray(firstElement) = *blanks );
socCodeTBMFound = *off;
if referenceType = 'ISWC';
ISWCDUPDS.message = %trim(ISWCDUPDS.message) + ' ISWC TBM not found in ICE ||' ;
else;
ISWCDUPDS.message = %trim(ISWCDUPDS.message) + ' Soc. work codes TBM not found in ICE ||' ;
endif;
endif;
return cTrue;
end-proc;
//---------------------------------------------------------------------
// Procedure name: checkNumberOfActiveWorksonISWC
// Purpose: checks if target ISWC has more than 1 active work.
// If it does, not considered merged.
// Returns: Successful/unsuccessful action
//---------------------------------------------------------------------
dcl-proc checkNumberOfActiveWorksonISWC;
dcl-pi *n ind;
multipleActiveWorksPresent ind;
end-pi;
index = 1;
countOfNonReferencedWorks = 0;
dow (index < 500 and parentWorkKeyArray(index).workKey <> 0);
if ( parentWorkKeyArray(index).workIsRef = 'N');
countOfNonReferencedWorks = countOfNonReferencedWorks + 1;
if (countOfNonReferencedWorks > 1);
multipleActiveWorksPresent = *On;
ISWCDUPDS.message = %trim(ISWCDUPDS.message) + 'Multiple Non-referenced work keys assigned same ISWC - Hence not considered merged||';
leave;
endif;
endif;
index = index + 1;
enddo;
return cTrue;
end-proc;
//---------------------------------------------------------------------------------
// Procedure name: BeginProgram
// Purpose: Init program
// Returns: Successful/unsuccessful action
//---------------------------------------------------------------------------------
dcl-proc BeginProgram;
dcl-pi *n ind end-pi;
if not DeclareCursors();
ErrorHandling();
return cFalse;
endif;
return cTrue;
end-proc BeginProgram;
//--------------------------------------------------------------------------------------
// Procedure name: DeclareCursors
// Purpose: Declares cursors for reading the input file and fetching work keys
// Returns: Nothing
//---------------------------------------------------------------------------------------
dcl-proc DeclareCursors;
dcl-pi *n ind end-pi;
//declare cursor for reading the input file
exec sql declare potiswccur dynamic scroll cursor for select * from potiswcdup;
// declare cursor for fetching work keys of ISWC
exec sql declare workKeyISWCCur cursor for
SELECT
WRK.WORKKEY,
WRKISREF,
COALESCE(WORKKEYM, 0) AS WORKKEYM FROM POTISWCDUP POT JOIN IACWXR WXR
ON WXR.WORKREF = :iswcReference AND WXR.WRKREFTYPE = 'ISWC'
JOIN IACWRK WRK ON WXR.WORKKEY = WRK.WORKKEY
LEFT JOIN IACWRM WRM ON WRM.WORKKEYR = WRK.WORKKEY AND WRKRELTYPE = 'MERG'
WHERE SLNUM = :ISWCDUPDS.SLNUM;
// declare cursor for fetching work keys of SOC Work codes
exec sql declare workKeySocWorkCodesCur cursor for
WITH WORKREF_SOCIETY AS (
SELECT SLNUM,
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 5) AS WORKREF ,
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) AS SOCIETY ,
CASE
WHEN
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) = '052' THEN 'ALLTC'
WHEN
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) IN ('023', '055') THEN 'SWREF'
WHEN
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) IN ('077', '079','089', '090', '110', '116', '112' ) THEN 'IWKEY'
END
AS WRKREFTYPE1,
CASE
WHEN
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) = '052' THEN 'DELTC'
END
AS WRKREFTYPE2
FROM POTISWCDUP ,
TABLE(SYSTOOLS.SPLIT(:socWorkCodeString,',') ) WHERE SLNUM = :ISWCDUPDS.SLNUM
AND SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) IN (SELECT SOCCODE FROM IACIAS) )
SELECT
WRK.WORKKEY,
WRKISREF,
COALESCE(WORKKEYM, 0) AS WORKKEYM FROM WORKREF_SOCIETY WSR JOIN IACWXR WXR
ON WXR.WORKREF = WSR.WORKREF AND WXR.WRKREFTYPE IN (WSR.WRKREFTYPE1, WSR.WRKREFTYPE2)
JOIN IACWRK WRK
ON WXR.WORKKEY = WRK.WORKKEY
LEFT JOIN IACWRM WRM
ON WRM.WORKKEYR = WRK.WORKKEY AND WRKRELTYPE = 'MERG'
UNION
SELECT WORKREF , WRKISREF, COALESCE (WORKKEYM, 0)
FROM WORKREF_SOCIETY JOIN IACWRK ON INT(WORKREF) = WORKKEY
LEFT JOIN IACWRM ON WORKKEYR = WORKKEY AND WRKRELTYPE = 'MERG'
WHERE WRKREFTYPE1 = 'IWKEY';
exec sql UPDATE thepav.POTISWCDUP SET
MESSAGE = ' ',
ISWCSORM = ' ',
SOCCSORM = ' ',
IWKEY_ISWC = ' ',
IWKEYMISWC = ' ' ,
IWKEYSOCDM = ' ',
IWKEYSOCD = ' ' ;
return cTrue;
end-proc DeclareCursors;
dcl-proc UpdateRecord;
dcl-pi *n ind end-pi;
if ( ISWCDUPDS.IWKEY_ISWC = ISWCDUPDS.IWKEYMISWC );
ISWCDUPDS.ISWCSORM = 'SAME';
endif;
if ( ISWCDUPDS.IWKEYSOCD = ISWCDUPDS.IWKEYSOCDM );
ISWCDUPDS.SOCCSORM = 'SAME';
endif;
exec sql
UPDATE POTISWCDUP
SET
IWKEY_ISWC = :ISWCDUPDS.IWKEY_ISWC ,
IWKEYMISWC = :ISWCDUPDS.IWKEYMISWC ,
ISWCSORM = :ISWCDUPDS.ISWCSORM ,
IWKEYSOCD = :ISWCDUPDS.IWKEYSOCD ,
IWKEYSOCDM = :ISWCDUPDS.IWKEYSOCDM ,
SOCCSORM = :ISWCDUPDS.SOCCSORM
WHERE SLNUM = :ISWCDUPDS.SLNUM;
return cTrue;
end-proc;
//---------------------------------------------------------------------
// Procedure name: Pgm_ErrorHandling
// Purpose: Process Error handling
// Returns: Nothing
//---------------------------------------------------------------------
dcl-proc ErrorHandling;
dump;
end-proc ErrorHandling;
I really dont understand why the same fetch into operation would work so fast in the below program. When I check in debug as soon as I press F10, it just moves on to the next line unlike the above one where it just gets stuck on the fetch for like 6 seconds.
**FREE
dcl-ds parentWorkKeyArray qualified dim(500);
//slnum like(ISWCDUPDS.slnum) inz(0);
workKey int(10);
workIsRef char(1) inz (*blanks);
workKeyParentKey int(10);
end-ds;
dcl-ds ISWCDUPDS Extname('POTISWCDUP') qualified;
end-ds;
dcl-s string char(5000);
dcl-s slnum int(5) inz(1);
string = '052|0010018E';
exec sql declare workKeySocWorkCodesCur cursor for
WITH WORKREF_SOCIETY AS (
SELECT SLNUM,
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 5) AS WORKREF ,
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) AS SOCIETY ,
CASE
WHEN
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) = '052' THEN 'ALLTC'
WHEN
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) IN ('023', '055') THEN 'SWREF'
WHEN
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) IN ('077', '079','089', '090', '110', '116', '112' ) THEN 'IWKEY'
END
AS WRKREFTYPE1,
CASE
WHEN
SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) = '052' THEN 'DELTC'
END
AS WRKREFTYPE2
FROM POTISWCDUP ,
TABLE(SYSTOOLS.SPLIT(:string,',') ) WHERE SLNUM = :slnum
AND SUBSTR (VARCHAR(TRIM(ELEMENT), 20) , 1, 3) IN (SELECT SOCCODE FROM IACIAS) )
SELECT
WRK.WORKKEY,
WRKISREF,
COALESCE(WORKKEYM, 0) AS WORKKEYM FROM WORKREF_SOCIETY WSR JOIN IACWXR WXR
ON WXR.WORKREF = WSR.WORKREF AND WXR.WRKREFTYPE IN (WSR.WRKREFTYPE1, WSR.WRKREFTYPE2)
JOIN IACWRK WRK
ON WXR.WORKKEY = WRK.WORKKEY
LEFT JOIN IACWRM WRM
ON WRM.WORKKEYR = WRK.WORKKEY AND WRKRELTYPE = 'MERG'
UNION
SELECT WORKREF , WRKISREF, COALESCE (WORKKEYM, 0)
FROM WORKREF_SOCIETY JOIN IACWRK ON INT(WORKREF) = WORKKEY
LEFT JOIN IACWRM ON WORKKEYR = WORKKEY AND WRKRELTYPE = 'MERG'
WHERE WRKREFTYPE1 = 'IWKEY';
clear parentworkkeyarray;
exec sql close workKeySocWorkCodesCur;
exec sql open workKeySocWorkCodesCur;
exec sql fetch workKeySocWorkCodesCur for 500 rows into :parentWorkKeyArray;
*inlr = *on;
Before I say anything else, there are two things you must know about embedded SQL. First is the SQL precompiler reads the source in sequential order and does not take into account the execution order of sub-procedures. The second is that declare cursor
is not an executable statement, that is, it is only used by the pre-compiler at compile time, and then commented out. It generates no code, but influences the code generated for other cursor statements.
I'm somewhat surprised this compiles, but not really. The reason is that you have all your declare cursor
statements at the end of the program in a sub-procedure. According to the documentation , declare cursor
must be physically located in the source before any statement that references it. In your program, all statements that reference the cursors precede their declarations, but the SQL preprocessor does not really understand procedures or program flow, and the declare cursor
statement is not executable, so it is not executed at run time, and therefore is not affected by the runtime call order of procedures. Since your declares are static and don't rely on procedure parameters, put them up in the beginning of your program with the variable declarations.
Also look at the compile listing for your program. Do the opens of the cursors which reference host variables actually have any lines that indicate they are using those host variables? Look at the opens, not the declares. The declares are just commented out with no generated code following them.
And while you are at it, set option
must be the first SQL statement that the precompiler encounters, or it will do nothing. So make sure you move that as well. The structure should be like this:
ctl-opt ....
dcl-* ...
exec sql set option ...
exec sql declare cursor ...
rest of the program
There is one exception to this, and that is when your declare cursor relies on procedure parameters as host variables. In that case I create separate procedures for OpenCursor, FetchCursor, and CloseCursor, these procedures are positioned in that order in the program, and the first thing the OpenCursor procedure does is declare its cursor. This is not so that the declare cursor runs before the open, but instead so that the procedure parameters that are used as host variables in the declare cursor statement are in scope for the declaration. The order of the cursor procedures is important to the precompiler. OpenCursor must come first (regardless of the order in which they are called) because the precompiler needs the definition of the cursor so that it can properly generate the code that executes the open cursor
, fetch cursor
, and close cursor
statements.
First thing, a difference in statement performance between interactive, via Run SQL Scripts I assume, and an embedded statement is usually because Run SQL Scripts defaults to using a query optimization goal of *FIRSTIO; whereas the embedded statement is run with *ALLIO.
Ensure you're testing the statement with *ALLIO, and look at the Explain output for your statement under that optimization goal.
Secondly, take a look at your use of %trim()
, you've got a lot of code like so: ISWCDUPDS.message = %trim(ISWCDUPDS.message) +...
Repeated trimming is very, very, very bad for performance..
Ensure that ISWCDUPDS.message
is a varchar field or use a temporary varchar to hold the value as you build it up. Additionally don't use %trim() unless you've got both leading and trailing blanks to worry about. myVarchar +=.... + %trimr(somechar);
If those two tips don't help, then you're going to want to start a DB monitor to see what's going on with the DB itself. You might also need to look at doing a Performance Explorer (PEX) to see where the program is spending it's time.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.