Pro*C Oracle code
#define SIZEKEY 20
int CalculateSum(float *sum,int keyid,struct retinfo *ret)
{
char key[SIZEKEY+1];
/* Type equivalence key to the string external datatype.*/
EXEC SQL VAR key is string(SIZEKEY);
float sumk;
int failed = 0;
sprintf(key,"%u",keyid);
printf("Calculate sum for %s\n",key);
EXEC SQL WHENEVER SQLERROR DO sql_error("Calculate sum",&failed);
EXEC SQL select sum(num) into :sumk FROM numhistory WHERE numkey = :key ;
if (failed) return 0;
ret->keyid = keyid;
EXEC SQL select count(num) into :ret->no FROM numhistory WHERE numkey = :key ;
if (failed) return 0;
*sum = sumk;
return 1;
}
Two problems require attention here while migrating to DB2.First
EXEC SQL VAR key is string(SIZEKEY);DB2 Embedded SQL does not support it. All hosts variables should be enclosed in :
EXEC SQL BEGIN DECLARE SECTION; ..... EXEC SQL END DECLARE SECTION;Another
EXEC SQL select count(num) into :ret->no FROM numhistory WHERE numkey = :key ;DB2 does not support struct member as a host variable. So value should be firstly assigned to simple variable and secondly to struct member. So finally DB2 Embedded SQL code equivalent to Pro*C code
int CalculateSum(float *sum,int keyid,struct retinfo *ret) {
struct sqlca sqlca;
EXEC SQL BEGIN DECLARE SECTION;
char key[21];
float sumk;
int no;
EXEC SQL END DECLARE SECTION;
int error = 0;
sprintf(key,"%u",keyid);
printf("Calculate sum for %s\n",key);
EXEC SQL select sum(num) into :sumk FROM numhistory WHERE numkey = :key ;
EVALRESULT("Calculate sum");
if (error) return 0;
ret->keyid = keyid;
EXEC SQL select count(num) into :no FROM numhistory WHERE numkey = :key ;
EVALRESULT("Calculate num");
ret->no = no;
*sum = sumk;
return 1;
}
SP callingPro*C Oracle code
int CallProc(int *res,char* sou) {
int failed = 0;
printf("Call SP for %s\n",sou);
EXEC SQL WHENEVER SQLERROR DO sql_error("Call SP",&failed);
EXEC SQL EXECUTE
BEGIN
SIMPLEPROC( :res, to_number( :sou ) );
END;
END-EXEC;
if (failed) return 0;
return 1;
}
DB2 supports notation EXEC SQL EXECUTE ... END-EXEC after setting "Oracle Compatibile Mode" in db2 prep invocation (example) :db2 prep $1.sqc bindfile SQLWARN NO COMPATIBILITY_MODE ORA
Another problem is related to
SIMPLEPROC( :res, to_number( :sou ) );
DB2 does not support UDF invocation as SP parameter. So this launching sequence should be split into two : UDF invocation and consecutive SP calling.
DB2 equivalent to Pro*C code
int CallProc(int *res,char* sou) {
int error = 0;
struct sqlca sqlca;
EXEC SQL BEGIN DECLARE SECTION;
char psou[100];
int number;
int resp;
EXEC SQL END DECLARE SECTION;
printf("Call SP par=%s\n",sou);
strcpy(psou,sou);
EXEC SQL VALUES (TO_NUMBER(:psou)) INTO :number;
EVALRESULT("Call TO_NUMBER");
if (error) return 0;
EXEC SQL EXECUTE
BEGIN
SIMPLEPROC( :resp, :number );
END;
END-EXEC;
EVALRESULT("Call SP");
if (error) return 0;
*res = resp;
return 1;
}
UDF calling
Pro*C Oracle code
int CallFunc(int *res, int par) {
int failed = 0;
printf("Call Func for %u\n",par);
EXEC SQL WHENEVER SQLERROR DO sql_error("Call UDF",&failed);
EXEC SQL EXECUTE
BEGIN
:res := RETPROC( :par );
END;
END-EXEC;
if (failed) return 0;
return 1;
}
DB2 does not support this launching method even in Compatibility Mode. DB2 Embedded SQL equivalent
int CallFunc(int *res, int par) {
int error = 0;
struct sqlca sqlca;
EXEC SQL BEGIN DECLARE SECTION;
int resp;
int parp;
EXEC SQL END DECLARE SECTION;
printf("Call UDF par=%u\n",par);
parp = par;
EXEC SQL VALUES (RETPROC(:parp)) INTO :resp;
EVALRESULT("Call UDF");
if (error) return 0;
*res = resp;
return 1;
}
Additional remarks- Full source code (including makefiles and sql) can be found here.
- Next : BLOB handling
Brak komentarzy:
Prześlij komentarz