Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Compile a Pro* C application using Microsoft VC++ 6

Posted on 2007-11-20
9
652 Views
Last Modified: 2013-12-18
Hi All,

I want to be able to compile a Pro* C application using Microsoft VC++ 6, successfully.

Ho would you handle the embedded SQL?

See attached source code.

Kind Regards
darrylf290567
0
Comment
Question by:darrylf290567
  • 5
  • 3
9 Comments
 
LVL 74

Expert Comment

by:sdstuber
ID: 20329656
you didn't attach any source.

but regardless, pro*c is a pre-compiler.

you run proc on your c files and it converts the embedded sql and pl/sql to c, then you run your normal c compiler on those files
0
 

Author Comment

by:darrylf290567
ID: 20331946
Hi sdstuber,

I will attache 1 file with source. This file will include embedded SQL inside it. Couldn't I use some Oracle Library files and embed the SQL inside the C code. I could use ODBC for Oracle and then call Oracle Stored Procedures to do the work via the Oracle ODBC driver. This would work would it not?

Could you please give me an example of calling a Oracle Stored Procedure via C code calling an Oracle Stored Procedure or even embedded SQL to do insert and upates.

Kind Regards
darrylf290567

/**************************************************************************
||
||	File:			odgditpl.pc
||	Description:	ODSS GDI Source file that provides a set of functions
||			        that perform the transaction processing as part of the
||          		transaction processing subsystem.
||	
||
||	Version Control:
||	Who		When		What
||	----	--------	------------------------------------------
||	B.D		01/07/96 	Initial program release.
||	L.R 	18/06/98 	Rea Update flag check to stop/allow for updates of
||						existing readings.
||
**************************************************************************/
 
/* Includes */
#include "odgdicmn.h"
#include "odgdilgr.h"
#include "odgditpl.h"
#include "odgditrl.h"
 
/* SQL Variable declarations */
EXEC SQL BEGIN DECLARE SECTION;
    char       oJobname[9];
    char       oProcid[9];
    char       oSqlStmt[1025];
    char       oIOParm[41];
    int        oCount;
	int        oCount2;
    int        oOffset;
    int        oLength;
 
    char       oDelimiter[2];
    char       oType[50];
 
    short      oDelimiterNull;
    char       oTransFormat[121];
    int        oRecordNumber;
    char       oPattern[41];
    short      oPatternNull;
    int        oPatternOffset;
    char       oStipulation[2];
    short      oStipulationNull;
    char       oName[9];
    int        oValueOffset;
    int        oValueLength;
    char       oIdentifier[41];
    char       oIdentifier1[41];
    char       oIdentifier2[41];
    short      oIdentifierNull;
    int        oFieldNumber;
    char       oSourcePattern[41];
    short      oSourcePatternNull;
    char       oTargetPattern[41];
    short      oTargetPatternNull;
    char       oDescription[41];
    int        oOccurance;
    char       oFormulaName[41];
    int        oSITEId;
    int        oFTYPId;
    int        oUNITId;
    int        oUNITDef;
    int        oUNITRep;
    int        oUNITBase;
    int        oUNITDisp;
    int        oUCATDef;
    int        oUCATId;
    char       oUOMIsBase[1];
    int        oMONPId;
    int        oMEASId;
    int        oRTYPId;
    int        oREADId;
    int        oFORMId;
    int        oSITECode;
    char       oFTYPCode[11];
    char       oMONPCode[11];
    char       oUNITCode[11];
    char       oMEASCode[11];
    char       oRTYPCode[11];
    double     oLowRange;
    double     oHighRange;
    double     oValue;
    double     oBase_uom_id;
    double     oDisplay_uom_id;
    double     oConv;
    char       oDateTime[20];
    char       oQualType[2];
    char       oOrigin[21];
    char       oReadStat[19];
    char       oInactive[2];
    char       oIFlag[2];
    char       oDatecomponent[10];
    char       oTimecomponent[10];
	char       oDateFormatMask[10];
EXEC SQL END DECLARE SECTION;
 
/* SQL Control Area */
#define SQLCA_STORAGE_CLASS extern
EXEC SQL INCLUDE sqlca;
 
/* Numeric definitions */
#define REJECTED           1
#define NO_VALUE          -1
#define MAX_VARVAL_L       40
#define NOT_USED           0x00
#define INP_VALUE_L        100
#define ALL_OCCURANCES     0
#define NO_MATR            -1
#define MAX_TRANS_L        500
#define MAX_REC_L          500
#define MAX_VARNAME_L      8
#define MIN_IDX            0
#define MAX_IDX            1
 
/* Character definitions */
#define PRESENT            "P"
 
/* Marc test */
#undef GDI_DEBUG
 
/* Log and debug definitions */
#define LOG_MSG_L          1024
char    LogMsg[LOG_MSG_L];
#ifdef GDI_DEBUG
#define Debug(msg);        JobLog(oJobname,INFO_T,msg);
#else
#define Debug(msg);
#endif
 
/* Structure definitions */
int TransValidX[EXPECTED_ITEM_CNT][2] =
{   1,    1,    /* Transaction type         */
    1,    20,   /* Origin                   */
    9,    14,   /* DateTime YYYYMMDDHHMMSS  */
    0,    18,   /* Value/Min range          */
    0,    18,   /* Status/Max range         */
    0,    1,    /* Quality code/Range type  */
    1,    40,   /* Site Asset Id/ID1        */
    1,    40,   /* Facility Type/ID2        */
    0,    10,   /* Monitoring point         */
    0,    10,   /* Facility Measurement/ID1 */
    0,    10 }; /* Facility Measurement2    */
 
struct TPInput
{
    int      Offset;
    int      Length;
    char     Delimiter[2];
    char     Value[INP_VALUE_L];
};
 
struct TPOutput
{
    char     TransFormat[121];
    char     Delimiter[2];
    char     Transaction[MAX_TRANS_L+1];
    int      Success;
};
 
struct TPRejects
{
    int      RecordNumber;
    int      FieldNumber;
    char     Pattern[41];
    int      PatternOffset;
    char     Stipulation[2];
};
 
struct TPVariables
{
    char     Name[9];
    int      RecordNumber;
    int      ValueOffset;
    int      ValueLength;
    char     Identifier[21];
    char     Stipulation[2];
    char     VarValue[41];
};
 
struct TPTrans
{
    int     FieldNumber;
    char    SourcePattern[41];
    char    TargetPattern[41];
    int     Occurance;
};
 
struct TPFormulae
{
    int     FieldNumber;
    char    FormulaName[41];
};
 
/* Function prototypes */
void              ApplyTransVariables  ( char *, int );
int               ApplyTransRejects    ( char *, int );
int               ApplyTransInput      ( char * );
void              ApplyTransFormulae   ( void );
void              ApplyTransPreTrans   ( void );
void              ApplyTransOutput     ( void );
void              ApplyTransPostTrans  ( void );
 
/* Global Variables */
struct TPInput *TPInputX;
int    TPInputCnt;
int    TPInputDel;
struct TPOutput *TPOutputX;
int    TPOutputCnt;
struct TPRejects *TPRejectsX;
int    TPRejectsCnt;
struct TPVariables *TPVariablesX;
int    TPVariablesCnt;
struct TPTrans *TPTransX;
int    TPTransCnt;
struct TPFormulae *TPFormulaeX;
int    TPFormulaeCnt;
int    Initialised;
int   *ErrSeq;
char  *CurProc;
char  *CurTrans;
char  *CurRec;
 
 
/**************************************************************************
 *
 *   Function:      TransProcInitialise
 *   Description:   This function initialises the transaction process
 *                  subsystem service. Initialisation involves building
 *                  the matrices used by the transaction process.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int TransProcInitialise( char *Jobname, char *Procid )
{
    Initialised = TRUE;
 
    strcpy(oJobname, Jobname);
    strcpy(oProcid, Procid);
    CurProc = oProcid;
 
    if ( BuildTPInputMatrix() )
        return(FAILURE);
    if ( BuildTPOutputMatrix() )
        return(FAILURE);
    if ( BuildTPRejectsMatrix() )
        return(FAILURE);
    if ( BuildTPVariablesMatrix() )
        return(FAILURE);
    if ( BuildTPTranslationsMatrix() )
        return(FAILURE);
    if ( BuildTPFormulaeMatrix() )
        return(FAILURE);
 
    Debug("TransProc initialisation successful");
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      BuildTPInputMatrix
 *   Description:   This function builds the transaction input matrix. The
 *                  matrix is built by counting the number of input
 *                  rows, allocating the appropriate memory and then
 *                  loading the memory with input details.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int BuildTPInputMatrix( void )
{
    EXEC SQL SELECT COUNT(*)
             INTO   :oCount
             FROM   Trans_Proc_Input
             WHERE  Proc_Id = :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "TransProc failed to count Input [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
    if ( oCount == 0 )
    {
        JobLog(oJobname, ERROR_T, "TransProc has no input definition(s)");
        return(FAILURE);
    }
#ifdef GDI_DEBUG
sprintf(LogMsg, "TransProc Input count is [%d]", oCount);
Debug(LogMsg);
#endif
 
    TPInputCnt = oCount;
    TPInputX = (struct TPInput *)malloc(sizeof(struct TPInput) *
                                        oCount);
    if ( TPInputX == NULL )
    {
        JobLog(oJobname, ERROR_T,
	       "TransProc Input matrix could not be allocated");
        return(FAILURE);
    }
 
    if ( LoadTPInputMatrix() )
    {
        free(TPInputX);
        return(FAILURE);
    }
 
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      BuildTPOutputMatrix
 *   Description:   This function builds the transaction output matrix. The
 *                  matrix is built by counting the number of output
 *                  rows, allocating the appropriate memory and then
 *                  loading the memory with output details.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int BuildTPOutputMatrix( void )
{
    EXEC SQL SELECT COUNT(*)
             INTO   :oCount
             FROM   Trans_Proc_Output
             WHERE  Proc_Id = :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "TransProc failed to count Output [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
    if ( oCount == 0 )
    {
        JobLog(oJobname, ERROR_T, "TransProc has no output definition(s)");
        return(FAILURE);
    }
#ifdef GDI_DEBUG
sprintf(LogMsg, "TransProc Output count is [%d]", oCount);
Debug(LogMsg);
#endif
 
    TPOutputCnt = oCount;
    TPOutputX = (struct TPOutput *)malloc(sizeof(struct TPOutput) *
                                          oCount);
    if ( TPOutputX == NULL )
    {
        JobLog(oJobname, ERROR_T,
               "TransProc Output matrix could not be allocated");
        return(FAILURE);
    }
 
    if ( LoadTPOutputMatrix() )
    {
        free(TPOutputX);
        return(FAILURE);
    }
 
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      BuildTPRejectsMatrix
 *   Description:   This function builds the transaction rejects matrix.
 *                  The matrix is built by counting the number of reject
 *                  rows, allocating the appropriate memory and then
 *                  loading the memory with reject details.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int BuildTPRejectsMatrix( void )
{
    EXEC SQL SELECT COUNT(*)
             INTO   :oCount
             FROM   Trans_Proc_Reject
             WHERE  Proc_Id = :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "TransProc failed to count Rejects [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
#ifdef GDI_DEBUG
sprintf(LogMsg, "TransProc Rejects count is [%d]", oCount);
Debug(LogMsg);
#endif
 
    TPRejectsX = NULL;
    TPRejectsCnt = oCount;
    if ( oCount > 0 )
    {
        TPRejectsX = (struct TPRejects *)malloc(sizeof(struct TPRejects) *
                                                oCount);
        if ( TPRejectsX == NULL )
        {
            JobLog(oJobname, ERROR_T,
                   "TransProc Rejects matrix could not be allocated");
            return(FAILURE);
        }
        if ( LoadTPRejectsMatrix() )
        {
            free(TPRejectsX);
            return(FAILURE);
        }
    }
 
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      BuildTPVariablesMatrix
 *   Description:   This function builds the transaction variables matrix.
 *                  The matrix is built by counting the number of variable
 *                  rows, allocating the appropriate memory and then
 *                  loading the memory with variable details.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int BuildTPVariablesMatrix( void )
{
    EXEC SQL SELECT COUNT(*)
             INTO   :oCount
             FROM   Trans_Proc_Variable
             WHERE  Proc_Id = :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "TransProc failed to count Variables [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
#ifdef GDI_DEBUG
sprintf(LogMsg, "TransProc Variable count is [%d]", oCount);
Debug(LogMsg);
#endif
 
    TPVariablesX = NULL;
    TPVariablesCnt = oCount;
    if ( oCount > 0 )
    {
        TPVariablesX = (struct TPVariables *)malloc(sizeof(struct TPVariables) *
                                                    oCount);
        if ( TPVariablesX == NULL )
        {
            JobLog(oJobname, ERROR_T,
                   "TransProc variables matrix could not be allocated");
            return(FAILURE);
        }
        if ( LoadTPVariablesMatrix() )
        {
            free(TPVariablesX);
            return(FAILURE);
        }
    }
 
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      BuildTPTranslationsMatrix
 *   Description:   This function builds the trans translations matrix.
 *                  The matrix is built by counting the number of transl
 *                  rows, allocating the appropriate memory and then
 *                  loading the memory with translation details.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int BuildTPTranslationsMatrix( void )
{
    EXEC SQL SELECT COUNT(*)
             INTO   :oCount
             FROM   Trans_Proc_Translation
             WHERE  Proc_Id = :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "TransProc failed to count Translations [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
#ifdef GDI_DEBUG
sprintf(LogMsg, "TransProc translations count is [%d]", oCount);
Debug(LogMsg);
#endif
 
    TPTransX = NULL;
    TPTransCnt = oCount;
    if ( oCount > 0 )
    {
        TPTransX = (struct TPTrans *)malloc(sizeof(struct TPTrans) *
                                            oCount);
        if ( TPTransX == NULL )
        {
            JobLog(oJobname, ERROR_T,
                   "TransProc Translations matrix could not be allocated");
            return(FAILURE);
        }
        if ( LoadTPTransMatrix() )
        {
            free(TPTransX);
            return(FAILURE);
        }
    }
 
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      BuildTPFormulaeMatrix
 *   Description:   This function builds the transaction formulae matrix.
 *                  The matrix is built by counting the number of formula
 *                  rows, allocating the appropriate memory and then
 *                  loading the memory with formula details.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 ***********************************************************************/
int BuildTPFormulaeMatrix( void )
{
    EXEC SQL SELECT COUNT(*)
             INTO   :oCount
             FROM   Trans_Proc_Formula
             WHERE  Proc_Id = :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "TransProc failed to count Formulae [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
#ifdef GDI_DEBUG
sprintf(LogMsg, "TransProc Formulae count is [%d]", oCount);
Debug(LogMsg);
#endif
 
    TPFormulaeX = NULL;
    TPFormulaeCnt = oCount;
    if ( oCount > 0 )
    {
        TPFormulaeX = (struct TPFormulae *)malloc(sizeof(struct TPFormulae) *
                                                  oCount);
        if ( TPFormulaeX == NULL )
        {
            JobLog(oJobname, ERROR_T,
                   "TransProc formulae matrix could not be allocated");
            return(FAILURE);
        }
        if ( LoadTPFormulaeMatrix() )
        {
            free(TPFormulaeX);
            return(FAILURE);
        }
    }
 
    return(SUCCESS);
}
 
/**************************************************************************
 *
 *   Function:      LoadTPInputMatrix
 *   Description:   This function uses dynamic SQL to build a cursor
 *                  to select all transaction input rows from the
 *                  database. These rows are inserted into the transaction
 *                  input matrix.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int LoadTPInputMatrix( void )
{
    int    FetchCnt;
    int    MoreToFetch;
 
    strcpy(oSqlStmt, "SELECT NVL(Offset,-1),");
    strcat(oSqlStmt, "       NVL(Length,-1),");
    strcat(oSqlStmt, "       Delimiter ");
    strcat(oSqlStmt, "FROM   Trans_Proc_Input ");
    strcat(oSqlStmt, "WHERE  Proc_Id = :oProcid ");
    strcat(oSqlStmt, "ORDER BY Offset");
 
    EXEC SQL PREPARE JTInputPrep FROM :oSqlStmt;
    EXEC SQL DECLARE JTInputCurs CURSOR FOR JTInputPrep;
    EXEC SQL OPEN JTInputCurs USING :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "JTInputCurs cursor failed [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
 
    FetchCnt = 0;
    MoreToFetch = TRUE;
    while ( MoreToFetch )
    {
        EXEC SQL FETCH JTInputCurs
                 INTO  :oOffset,
                       :oLength,
                       :oDelimiter :oDelimiterNull;;
        if ( sqlca.sqlcode != SQL_OK )
        {
            MoreToFetch = FALSE;
            if ( sqlca.sqlcode != END_OF_CURSOR )
            {
                sprintf(LogMsg, "JTInputCurs cursor fetch failed [%d]",
                        sqlca.sqlcode);
                JobLog(oJobname, ERROR_T, LogMsg);
                EXEC SQL CLOSE JTInputCurs;
                return(FAILURE);
            }
        }
	else
	{
            if ( oDelimiterNull == SQL_NULL )
                oDelimiter[0] = NULL;
            TPInputX[FetchCnt].Offset = oOffset;
            TPInputX[FetchCnt].Length = oLength;
            strcpy(TPInputX[FetchCnt].Delimiter, oDelimiter);
            TPInputX[FetchCnt].Value[0] = NULL;
#ifdef GDI_DEBUG
sprintf(LogMsg, "Input [%d,%d,%s]",
		TPInputX[FetchCnt].Offset,
		TPInputX[FetchCnt].Length,
		TPInputX[FetchCnt].Delimiter);
Debug(LogMsg);
#endif
            FetchCnt++;
        }
    }
 
    EXEC SQL CLOSE JTInputCurs;
 
    if ( TPInputCnt == 1 )
        TPInputDel = (int)TPInputX[0].Delimiter[0];
    else
        TPInputDel = NO_VALUE;
 
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      LoadTPOutputMatrix
 *   Description:   This function uses dynamic SQL to build a cursor
 *                  to select all transaction output rows from the
 *                  database. These rows are inserted into the transaction
 *                  output matrix.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int LoadTPOutputMatrix( void )
{
    int    FetchCnt;
    int    MoreToFetch;
 
    strcpy(oSqlStmt, "SELECT Trans_Format,");
    strcat(oSqlStmt, "       Delimiter ");
    strcat(oSqlStmt, "FROM   Trans_Proc_Output ");
    strcat(oSqlStmt, "WHERE  Proc_Id = :oProcid");
 
    EXEC SQL PREPARE JTOutputPrep FROM :oSqlStmt;
    EXEC SQL DECLARE JTOutputCurs CURSOR FOR JTOutputPrep;
    EXEC SQL OPEN JTOutputCurs USING :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "JTOutputCurs cursor failed [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
 
    FetchCnt = 0;
    MoreToFetch = TRUE;
    while ( MoreToFetch )
    {
        EXEC SQL FETCH JTOutputCurs
                 INTO  :oTransFormat,
                       :oDelimiter;
        if ( sqlca.sqlcode != SQL_OK )
        {
            MoreToFetch = FALSE;
            if ( sqlca.sqlcode != END_OF_CURSOR )
            {
                sprintf(LogMsg, "JTOutputCurs cursor fetch failed [%d]",
                        sqlca.sqlcode);
                JobLog(oJobname, ERROR_T, LogMsg);
                EXEC SQL CLOSE JTOutputCurs;
                return(FAILURE);
            }
        }
	else
        {
	    RemoveTrailingBlanks(oTransFormat, oTransFormat);
            strcpy(TPOutputX[FetchCnt].TransFormat, oTransFormat);
            strcpy(TPOutputX[FetchCnt].Delimiter, oDelimiter);
            TPOutputX[FetchCnt].Transaction[0] = NULL;
            TPOutputX[FetchCnt].Success = FALSE;
#ifdef GDI_DEBUG
sprintf(LogMsg, "Output [%s,%s]",
		TPOutputX[FetchCnt].TransFormat,
		TPOutputX[FetchCnt].Delimiter);
Debug(LogMsg);
#endif
            FetchCnt++;
        }
    }
 
    EXEC SQL CLOSE JTOutputCurs;
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      LoadTPRejectsMatrix
 *   Description:   This function uses dynamic SQL to build a cursor
 *                  to select all transaction reject rows from the
 *                  database. These rows are inserted into the transaction
 *                  reject matrix.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int LoadTPRejectsMatrix( void )
{
    int    FetchCnt;
    int    MoreToFetch;
 
    strcpy(oSqlStmt, "SELECT NVL(Record_Number,-1),");
    strcat(oSqlStmt, "       NVL(Field_Number,-1),");
    strcat(oSqlStmt, "       Pattern,");
    strcat(oSqlStmt, "       NVL(Pattern_Offset, -1),");
    strcat(oSqlStmt, "       Stipulation ");
    strcat(oSqlStmt, "FROM   Trans_Proc_Reject ");
    strcat(oSqlStmt, "WHERE  Proc_Id = :oProcid");
 
    EXEC SQL PREPARE JTRejectsPrep FROM :oSqlStmt;
    EXEC SQL DECLARE JTRejectsCurs CURSOR FOR JTRejectsPrep;
    EXEC SQL OPEN JTRejectsCurs USING :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "JTRejectsCurs cursor failed [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
 
    FetchCnt = 0;
    MoreToFetch = TRUE;
    while ( MoreToFetch )
    {
        EXEC SQL FETCH JTRejectsCurs
                 INTO  :oRecordNumber,
                       :oFieldNumber,
                       :oPattern :oPatternNull,
                       :oPatternOffset,
                       :oStipulation :oStipulationNull;
        if ( sqlca.sqlcode != SQL_OK )
        {
            MoreToFetch = FALSE;
            if ( sqlca.sqlcode != END_OF_CURSOR )
            {
                sprintf(LogMsg, "JTRejectsCurs cursor fetch failed [%d]",
                        sqlca.sqlcode);
                JobLog(oJobname, ERROR_T, LogMsg);
                EXEC SQL CLOSE JTRejectsCurs;
                return(FAILURE);
            }
        }
        else
        {
            if ( oPatternNull == SQL_NULL )
    	        oPattern[0] = NULL;
            if ( oStipulationNull == SQL_NULL )
                oStipulation[0] = NULL;
	    RemoveTrailingBlanks(oPattern, oPattern);
            TPRejectsX[FetchCnt].RecordNumber  = oRecordNumber;
            TPRejectsX[FetchCnt].FieldNumber   = oFieldNumber;
            TPRejectsX[FetchCnt].PatternOffset = oPatternOffset;
            strcpy(TPRejectsX[FetchCnt].Pattern, oPattern);
            strcpy(TPRejectsX[FetchCnt].Stipulation, oStipulation);
#ifdef GDI_DEBUG
sprintf(LogMsg, "Rejects [%d,%d,%d,%s,%s]",
		TPRejectsX[FetchCnt].RecordNumber,
		TPRejectsX[FetchCnt].FieldNumber,
		TPRejectsX[FetchCnt].PatternOffset,
		TPRejectsX[FetchCnt].Pattern,
		TPRejectsX[FetchCnt].Stipulation);
Debug(LogMsg);
#endif
            FetchCnt++;
        }
    }
 
    EXEC SQL CLOSE JTRejectsCurs;
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      LoadTPVariablesMatrix
 *   Description:   This function uses dynamic SQL to build a cursor
 *                  to select all transaction variable rows from the
 *                  database. These rows are inserted into the transaction
 *                  variable matrix.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int LoadTPVariablesMatrix( void )
{
    int    FetchCnt;
    int    MoreToFetch;
 
    strcpy(oSqlStmt, "SELECT Name,");
    strcat(oSqlStmt, "       NVL(Record_Number,-1),");
    strcat(oSqlStmt, "       Value_Offset,");
    strcat(oSqlStmt, "       Value_Length,");
    strcat(oSqlStmt, "       Identifier,");
    strcat(oSqlStmt, "       Stipulation ");
    strcat(oSqlStmt, "FROM   Trans_Proc_Variable ");
    strcat(oSqlStmt, "WHERE  Proc_Id = :oProcid");
 
    EXEC SQL PREPARE JTVariablesPrep FROM :oSqlStmt;
    EXEC SQL DECLARE JTVariablesCurs CURSOR FOR JTVariablesPrep;
    EXEC SQL OPEN JTVariablesCurs USING :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "JTVariablesCurs cursor failed [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
 
    FetchCnt = 0;
    MoreToFetch = TRUE;
    while ( MoreToFetch )
    {
        EXEC SQL FETCH JTVariablesCurs
                 INTO  :oName,
                       :oRecordNumber,
                       :oValueOffset,
                       :oValueLength,
                       :oIdentifier :oIdentifierNull,
                       :oStipulation :oStipulationNull;
        if ( sqlca.sqlcode != SQL_OK )
        {
            MoreToFetch = FALSE;
            if ( sqlca.sqlcode != END_OF_CURSOR )
            {
                sprintf(LogMsg, "JTVariablesCurs cursor fetch failed [%d]",
                        sqlca.sqlcode);
                JobLog(oJobname, ERROR_T, LogMsg);
                EXEC SQL CLOSE JTVariablesCurs;
                return(FAILURE);
            }
        }
        else
        {
            if ( oIdentifierNull == SQL_NULL )
                oIdentifier[0] = NULL;
            if ( oStipulationNull == SQL_NULL )
                oStipulation[0] = NULL;
	    RemoveTrailingBlanks(oName, oName);
	    RemoveTrailingBlanks(oIdentifier, oIdentifier);
            TPVariablesX[FetchCnt].RecordNumber = oRecordNumber;
            TPVariablesX[FetchCnt].ValueOffset = oValueOffset;
            TPVariablesX[FetchCnt].ValueLength = oValueLength;
            strcpy(TPVariablesX[FetchCnt].Name, oName);
            strcpy(TPVariablesX[FetchCnt].Identifier, oIdentifier);
            strcpy(TPVariablesX[FetchCnt].Stipulation, oStipulation);
            TPVariablesX[FetchCnt].VarValue[0] = NULL;
#ifdef GDI_DEBUG
sprintf(LogMsg, "Variables [%d,%d,%d,%s,%s,%s]",
		TPVariablesX[FetchCnt].RecordNumber,
		TPVariablesX[FetchCnt].ValueOffset,
		TPVariablesX[FetchCnt].ValueLength,
		TPVariablesX[FetchCnt].Name,
		TPVariablesX[FetchCnt].Identifier,
		TPVariablesX[FetchCnt].Stipulation);
Debug(LogMsg);
#endif
            FetchCnt++;
        }
    }
 
    EXEC SQL CLOSE JTVariablesCurs;
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      LoadTPTransMatrix
 *   Description:   This function uses dynamic SQL to build a cursor
 *                  to select all transaction translation rows from the
 *                  database. These rows are inserted into the transaction
 *                  translation matrix.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int LoadTPTransMatrix( void )
{
    int    FetchCnt;
    int    MoreToFetch;
 
    strcpy(oSqlStmt, "SELECT NVL(Field_Number,-1),");
    strcat(oSqlStmt, "       Source_Pattern,");
    strcat(oSqlStmt, "       Target_Pattern,");
    strcat(oSqlStmt, "       NVL(Occurance,0) ");
    strcat(oSqlStmt, "FROM   Trans_Proc_Translation ");
    strcat(oSqlStmt, "WHERE  Proc_Id = :oProcid ");
    strcat(oSqlStmt, "ORDER BY Field_Number, Source_Pattern ");
 
    EXEC SQL PREPARE JTTransPrep FROM :oSqlStmt;
    EXEC SQL DECLARE JTTransCurs CURSOR FOR JTTransPrep;
    EXEC SQL OPEN JTTransCurs USING :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "JTTransCurs cursor failed [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
 
    FetchCnt = 0;
    MoreToFetch = TRUE;
    while ( MoreToFetch )
    {
        EXEC SQL FETCH JTTransCurs
                 INTO  :oFieldNumber,
                       :oSourcePattern :oSourcePatternNull,
                       :oTargetPattern :oTargetPatternNull,
                       :oOccurance;
        if ( sqlca.sqlcode != SQL_OK )
        {
            MoreToFetch = FALSE;
            if ( sqlca.sqlcode != END_OF_CURSOR )
            {
                sprintf(LogMsg, "JTTransCurs cursor fetch failed [%d]",
                        sqlca.sqlcode);
                JobLog(oJobname, ERROR_T, LogMsg);
                EXEC SQL CLOSE JTTransCurs;
                return(FAILURE);
            }
        }
        else
        {
            if ( oSourcePatternNull == SQL_NULL )
                oSourcePattern[0] = NULL;
            if ( oTargetPatternNull == SQL_NULL )
                oTargetPattern[0] = NULL;
	    RemoveTrailingBlanks(oSourcePattern, oSourcePattern);
	    RemoveTrailingBlanks(oTargetPattern, oTargetPattern);
            TPTransX[FetchCnt].FieldNumber = oFieldNumber;
            TPTransX[FetchCnt].Occurance = oOccurance;
            strcpy(TPTransX[FetchCnt].SourcePattern, oSourcePattern);
            strcpy(TPTransX[FetchCnt].TargetPattern, oTargetPattern);
#ifdef GDI_DEBUG
sprintf(LogMsg, "Translations [%d,%d,%s,%s]",
		TPTransX[FetchCnt].FieldNumber,
		TPTransX[FetchCnt].Occurance,
		TPTransX[FetchCnt].SourcePattern,
		TPTransX[FetchCnt].TargetPattern);
Debug(LogMsg);
#endif
            FetchCnt++;
        }
    }
 
    EXEC SQL CLOSE JTTransCurs;
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      LoadTPFormulaeMatrix
 *   Description:   This function uses dynamic SQL to build a cursor
 *                  to select all transaction formula rows from the
 *                  database. These rows are inserted into the transaction
 *                  formula matrix.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int LoadTPFormulaeMatrix( void )
{
    int    FetchCnt;
    int    MoreToFetch;
 
    strcpy(oSqlStmt, "SELECT Field_Number,");
    strcat(oSqlStmt, "       Formula_Name ");
    strcat(oSqlStmt, "FROM   Trans_Proc_Formula ");
    strcat(oSqlStmt, "WHERE  Proc_Id = :oProcid");
 
    EXEC SQL PREPARE JTFormulaePrep FROM :oSqlStmt;
    EXEC SQL DECLARE JTFormulaeCurs CURSOR FOR JTFormulaePrep;
    EXEC SQL OPEN JTFormulaeCurs USING :oProcid;
    if ( sqlca.sqlcode != SQL_OK )
    {
        sprintf(LogMsg, "JTFormulaeCurs cursor failed [%d]",
                sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
        return(FAILURE);
    }
 
    FetchCnt = 0;
    MoreToFetch = TRUE;
    while ( MoreToFetch )
    {
        EXEC SQL FETCH JTFormulaeCurs
                 INTO  :oFieldNumber,
                       :oFormulaName;
        if ( sqlca.sqlcode != SQL_OK )
        {
            MoreToFetch = FALSE;
            if ( sqlca.sqlcode != END_OF_CURSOR )
            {
                sprintf(LogMsg, "JTFormulaeCurs cursor fetch failed [%d]",
                        sqlca.sqlcode);
                JobLog(oJobname, ERROR_T, LogMsg);
                EXEC SQL CLOSE JTFormulaeCurs;
                return(FAILURE);
            }
        }
        else
        {
            RemoveTrailingBlanks(oFormulaName, oFormulaName);
            TPFormulaeX[FetchCnt].FieldNumber = oFieldNumber;
            strcpy(TPFormulaeX[FetchCnt].FormulaName, oFormulaName);
#ifdef GDI_DEBUG
sprintf(LogMsg, "Formulae [%d,%s]",
TPFormulaeX[FetchCnt].FieldNumber,
TPFormulaeX[FetchCnt].FormulaName);
Debug(LogMsg);
#endif
            FetchCnt++;
        }
    }
 
    EXEC SQL CLOSE JTFormulaeCurs;
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      TransProcBuildTrans
 *   Description:   This function uses the matrices created in the
 *                  previous functions to produce a set of transactions.
 *                  This function expects an input data record which is
 *                  used as the base against which the matrices are
 *                  applied.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int TransProcBuildTrans( char *Record, int RecCnt )
{
    if ( !Initialised )
	return(FAILURE);
 
    CurRec = Record;
 
    ApplyTransVariables(Record, RecCnt);
 
    if ( ApplyTransInput(Record) )
        return(FAILURE);
 
    ApplyTransPreTrans();
 
    if ( ApplyTransRejects(Record, RecCnt) )
        return(REJECTED);
 
    ApplyTransFormulae();
    ApplyTransOutput();
    ApplyTransPostTrans();
 
    Debug("TransProcBuildTrans successful");
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      ApplyTransVariables
 *   Description:   This function uses the Variables matrix to identify
 *                  and maintain transaction variables.  The values for
 *                  transaction variables are extracted from the input
 *                  record by a given offset and length.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 * 	 D.R  06/07/98  SR#83562, Variables now have leading blanks stripped.
 *
 **************************************************************************/
void ApplyTransVariables ( char *Record, int RecCnt )
{
    int    i;
    int    Proceed;
    char  *IdLoc;
 
    for ( i=0; i<TPVariablesCnt; i++ )
    {
        if ( TPVariablesX[i].RecordNumber != NO_VALUE )
        {
            if ( TPVariablesX[i].RecordNumber == RecCnt )
            {
                memset(TPVariablesX[i].VarValue, 0, MAX_VARVAL_L+1);
                strncpy(TPVariablesX[i].VarValue,
                        Record+(TPVariablesX[i].ValueOffset)-1,
                        TPVariablesX[i].ValueLength);
				/* Strip the variable value of leading and traling blanks */
				RemoveLeadingBlanks(TPVariablesX[i].VarValue,
                                     TPVariablesX[i].VarValue);
                RemoveTrailingBlanks(TPVariablesX[i].VarValue,
                                     TPVariablesX[i].VarValue);
#ifdef GDI_DEBUG
sprintf(LogMsg, "Variable [%s] is [%s]",
		TPVariablesX[i].Name, TPVariablesX[i].VarValue);
Debug(LogMsg);
#endif
            }
        }
        else
        {
            IdLoc = strstr(Record, TPVariablesX[i].Identifier);
            Proceed = FALSE;
            if ( !strcmp(TPVariablesX[i].Stipulation, PRESENT) )
            {
                if ( IdLoc != NULL )
                    Proceed = TRUE;
            }
            else
            {
                if ( IdLoc == NULL )
                    Proceed = TRUE;
            }
            if ( Proceed )
            {
                memset(TPVariablesX[i].VarValue, 0, MAX_VARVAL_L+1);
                strncpy(TPVariablesX[i].VarValue,
                        Record+(TPVariablesX[i].ValueOffset)-1,
                        TPVariablesX[i].ValueLength);
                RemoveTrailingBlanks(TPVariablesX[i].VarValue,
                                     TPVariablesX[i].VarValue);
#ifdef GDI_DEBUG
sprintf(LogMsg, "Variable [%s] is [%s]",
		TPVariablesX[i].Name, TPVariablesX[i].VarValue);
Debug(LogMsg);
#endif
            }
        }
    }
}
 
 
/**************************************************************************
 *
 *   Function:      ApplyTransRejects
 *   Description:   This function uses the Rejects matrix to identify
 *                  input records that are to be rejected from the
 *                  transaction process.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int ApplyTransRejects(char *Record, int RecCnt)
{
    int    i;
    int    Proceed;
    int    Rejected;
    char  *PatLoc;
 
    Rejected = FALSE;
    for ( i=0; (i<TPRejectsCnt) && (!Rejected); i++ )
    {
        if ( TPRejectsX[i].RecordNumber != NO_VALUE )
        {
            if ( TPRejectsX[i].RecordNumber == RecCnt )
	    {
                Rejected = TRUE;
#ifdef GDI_DEBUG
sprintf(LogMsg, "Record [%d] rejected",
		TPRejectsX[i].RecordNumber);
Debug(LogMsg);
#endif
            }
        }
        else
        {
            if ( TPRejectsX[i].FieldNumber != NO_VALUE )
            {
                if ( TPRejectsX[i].FieldNumber < TPInputCnt )
                    PatLoc = strstr(TPInputX[TPRejectsX[i].FieldNumber-1].Value,
                                    TPRejectsX[i].Pattern);
                else
                    PatLoc = NULL;
            }
            else
            {
                PatLoc = strstr(Record, TPRejectsX[i].Pattern);
            }
            Proceed = FALSE;
            if ( !strcmp(TPRejectsX[i].Stipulation, PRESENT) )
            {
                if ( PatLoc != NULL )
                {
                    if ( TPRejectsX[i].PatternOffset == NO_VALUE )
                    {
                        Proceed = TRUE;
                    }
                    else
                    {
                        if ( TPRejectsX[i].FieldNumber != NO_VALUE )
                        {
                            PatLoc = strstr(TPInputX[TPRejectsX[i].
                                                FieldNumber-1].Value +
                                            TPRejectsX[i].PatternOffset - 1,
                                            TPRejectsX[i].Pattern);
                            if ( (int)(PatLoc -
                                 TPInputX[TPRejectsX[i].FieldNumber-1].Value
                                 + 1) == TPRejectsX[i].PatternOffset )
                                Proceed = TRUE;
                        }
                        else
                        {
                            PatLoc = strstr(Record +
                                            TPRejectsX[i].PatternOffset - 1,
                                            TPRejectsX[i].Pattern);
                            if ( (int)(PatLoc - Record + 1) ==
                                 TPRejectsX[i].PatternOffset )
                                Proceed = TRUE;
                        }
                    }
                }
            }
            else
            {
                if ( PatLoc == NULL )
                {
                    Proceed = TRUE;
                }
                else
                {
                    if ( TPRejectsX[i].PatternOffset == NO_VALUE )
                    {
                        Proceed = TRUE;
                    }
                    else
                    {
                        if ( TPRejectsX[i].FieldNumber != NO_VALUE )
                        {
                            PatLoc = strstr(TPInputX[TPRejectsX[i].
                                                FieldNumber-1].Value +
                                            TPRejectsX[i].PatternOffset - 1,
                                            TPRejectsX[i].Pattern);
                            if ( (int)(PatLoc -
                                 TPInputX[TPRejectsX[i].FieldNumber-1].Value
                                 + 1) != TPRejectsX[i].PatternOffset )
                                Proceed = TRUE;
                        }
                        else
                        {
                            PatLoc = strstr(Record +
                                            TPRejectsX[i].PatternOffset - 1,
                                            TPRejectsX[i].Pattern);
                            if ( (int)(PatLoc - Record + 1) !=
                                 TPRejectsX[i].PatternOffset )
                                Proceed = TRUE;
                        }
                    }
                }
            }
            if ( Proceed )
            {
                Rejected = TRUE;
#ifdef GDI_DEBUG
sprintf(LogMsg, "Record identified by [%s] rejected",
		TPRejectsX[i].Pattern);
Debug(LogMsg);
#endif
            }
        }
    }
 
    return(Rejected);
}
 
 
/**************************************************************************
 *
 *   Function:      ApplyTransInput
 *   Description:   This function uses the Input matrix to identify
 *                  and extract input fields from input records.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int ApplyTransInput ( char *Record )
{
    int    i;
    char  *Del;
    char  *Field;
    int    RecLen;
 
 
    if ( TPInputDel == NO_VALUE )
    {
	RecLen = strlen(Record);
        for ( i=0; i<TPInputCnt; i++ )
        {
            memset(TPInputX[i].Value, 0, INP_VALUE_L);
            if ( (TPInputX[i].Offset+TPInputX[i].Length-1) > RecLen )
            {
                TPInputX[i].Value[0] = NOT_USED;
            }
            else
            {
                memcpy(TPInputX[i].Value,
                       Record+TPInputX[i].Offset-1,
                       TPInputX[i].Length);
                RemoveTrailingBlanks(TPInputX[i].Value, TPInputX[i].Value);
                RemoveLeadingBlanks(TPInputX[i].Value, TPInputX[i].Value);
            }
#ifdef GDI_DEBUG
sprintf(LogMsg, "Input element [%d] is [%s]",
	i+1, TPInputX[i].Value);
Debug(LogMsg);
#endif
        }
    }
    else
    {
        free(TPInputX);
        TPInputCnt = 1;
        Del = Record;
        while ( (Del = strchr(Del, TPInputDel)+1) > (char *)1 )
            TPInputCnt++;
        TPInputX = (struct TPInput *)malloc(sizeof(struct TPInput) *
                                            TPInputCnt);
        if ( TPInputX == NULL )
        {
            JobLog(oJobname, ERROR_T,
		   "Delimiter matrix could not be allocated");
            return(FAILURE);
        }
        Field = Del = Record;
        for ( i=0; i<TPInputCnt; i++ )
        {
            memset(TPInputX[i].Value, 0, INP_VALUE_L);
            if ( (Del = strchr(Field, TPInputDel)) != NULL )
                *Del = NULL;
            strcpy(TPInputX[i].Value, Field);
            RemoveTrailingBlanks(TPInputX[i].Value, TPInputX[i].Value);
            Field = Del + 1;
#ifdef GDI_DEBUG
sprintf(LogMsg, "Input element [%d] is [%s]",
		i+1, TPInputX[i].Value);
Debug(LogMsg);
#endif
        }
    }
 
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      ApplyTransFormulae
 *   Description:   This function uses the Formulae matrix to identify
 *                  input fields that need a forula applied to them.
 *                  Formulae are applied using stored database procedures.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
void ApplyTransFormulae( void )
{
    int    i;
 
    for ( i=0; i<TPFormulaeCnt; i++ )
    {
        if ( TPFormulaeX[i].FieldNumber <= TPInputCnt )
        {
            sprintf(oSqlStmt, "BEGIN %s(:oIOParm); END;",
                    TPFormulaeX[i].FormulaName);
            strcpy(oIOParm, TPInputX[TPFormulaeX[i].FieldNumber-1].Value);
            EXEC SQL PREPARE FormulaCall FROM :oSqlStmt;
            EXEC SQL EXECUTE FormulaCall USING :oIOParm;
            RemoveTrailingBlanks(oIOParm, oIOParm);
 
            if ( sqlca.sqlcode != SQL_OK )
            {
                sprintf(LogMsg, "Formula execution failed for [%s]",
                        TPFormulaeX[i].FormulaName);
                JobLog(oJobname, WARNING_T, LogMsg);
                sprintf(LogMsg, "Call was [%s]", oSqlStmt);
                JobLog(oJobname, WARNING_T, LogMsg);
                sprintf(LogMsg, "Return Code was [%d] Parm was [%s]",
	             sqlca.sqlcode, oIOParm);
                JobLog(oJobname, WARNING_T, LogMsg);
            }
            else
            {
                strcpy(TPInputX[TPFormulaeX[i].FieldNumber-1].Value, oIOParm);
#ifdef GDI_DEBUG
sprintf(LogMsg, "Formula [%s] produced [%s]",
		TPFormulaeX[i].FormulaName,
		TPInputX[TPFormulaeX[i].FieldNumber-1].Value);
Debug(LogMsg);
#endif
            }
        }
    }
}
 
 
/**************************************************************************
 *
 *   Function:      ApplyTransPreTrans
 *   Description:   This function uses the Translations matrix to identify
 *                  input fields that require string translations.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
void ApplyTransPreTrans ( void )
{
    int    i, j;
    int    PatternCnt;
    char  *Pattern;
    char  *ScanPoint;
    char   TempFld[INP_VALUE_L+1];
 
 
    for ( i=0; i<TPInputCnt; i++ )
    {
        for ( j=0; j<TPTransCnt; j++ )
        {
            if ( TPTransX[j].FieldNumber == (i+1) )
            {
                if ( TPTransX[j].SourcePattern[0] == NOT_USED )
                {
#ifdef GDI_DEBUG
sprintf(LogMsg, "Translating [%s] to [%s]",
		TPInputX[i].Value,
		TPTransX[j].TargetPattern);
Debug(LogMsg);
#endif
                    strcpy(TPInputX[i].Value,
                           TPTransX[j].TargetPattern);
                }
                else
                {
                    PatternCnt = 0;
                    ScanPoint = TPInputX[i].Value;
                    memset(TempFld, 0, INP_VALUE_L+1);
                    while ( (Pattern = strstr(ScanPoint,
                                          TPTransX[j].SourcePattern)) != NULL )
                    {
                        PatternCnt++;
                        if ( (TPTransX[j].Occurance == ALL_OCCURANCES) ||
                             (TPTransX[j].Occurance == PatternCnt) )
                        {
#ifdef GDI_DEBUG
sprintf(LogMsg, "Translating [%s] to [%s]",
		TPTransX[j].SourcePattern,
		TPTransX[j].TargetPattern);
Debug(LogMsg);
#endif
                            strncat(TempFld,
                                    ScanPoint,
                                    Pattern-ScanPoint);
                            strcat(TempFld, TPTransX[j].TargetPattern);
                        }
                        else
                        {
                            strncat(TempFld,
                                    ScanPoint,
                                    Pattern-ScanPoint);
                            strcat(TempFld, TPTransX[j].SourcePattern);
                        }
                        ScanPoint = Pattern + strlen(TPTransX[j].SourcePattern);
                    }
                    strcat(TempFld, ScanPoint);
                    strcpy(TPInputX[i].Value, TempFld);
                }
            }
        }
    }
}
 
 
/**************************************************************************
 *
 *   Function:      ApplyTransPostTrans
 *   Description:   This function uses the Translations matrix to identify
 *                  string patterns in a built transaction that require
 *                  translation to another string pattern.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
void ApplyTransPostTrans ( void )
{
    int    i, j;
    int    PatternCnt;
    char  *Pattern;
    char  *ScanPoint;
    char   TempTrans[MAX_TRANS_L+1];
 
 
    for ( i=0; i<TPOutputCnt; i++ )
    {
        for ( j=0; j<TPTransCnt; j++ )
        {
            if ( TPTransX[j].FieldNumber == NO_VALUE )
            {
                if ( TPTransX[j].SourcePattern[0] != NOT_USED )
                {
                    PatternCnt = 0;
                    ScanPoint = TPOutputX[i].Transaction;
                    memset(TempTrans, 0, MAX_TRANS_L+1);
                    while ( (Pattern = strstr(ScanPoint,
                                          TPTransX[j].SourcePattern)) != NULL )
                    {
                        PatternCnt++;
                        if ( (TPTransX[j].Occurance == ALL_OCCURANCES) ||
                             (TPTransX[j].Occurance == PatternCnt) )
                        {
#ifdef GDI_DEBUG
sprintf(LogMsg, "Translating [%s] to [%s]",
		TPTransX[j].SourcePattern,
		TPTransX[j].TargetPattern);
Debug(LogMsg);
#endif
                            strncat(TempTrans,
                                    ScanPoint,
                                    Pattern-ScanPoint);
                            strcat(TempTrans,
                                   TPTransX[j].TargetPattern);
                        }
                        else
                        {
                            strncat(TempTrans,
                                    ScanPoint,
                                    Pattern-ScanPoint);
                            strcat(TempTrans, TPTransX[j].SourcePattern);
                        }
                        ScanPoint = Pattern + strlen(TPTransX[j].SourcePattern);
                    }
                    strcat(TempTrans, ScanPoint);
                    strcpy(TPOutputX[i].Transaction, TempTrans);
                }
            }
        }
    }
}
 
 
/**************************************************************************
 *
 *   Function:      ApplyTransOutput
 *   Description:   This function uses the Output matrix to identify
 *                  input fields, variables and constants to be built
 *                  into a transaction.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
void ApplyTransOutput ( void )
{
    int    i, j;
    char   Del;
    char  *Field;
    char  *FieldEnd;
    char  *ScanPoint;
    char   TempTrans[MAX_TRANS_L+1];
    char   VarName[MAX_VARNAME_L+1];
    int    VarNum;
 
    for ( i=0; i<TPOutputCnt; i++ )
    {
        Del = TPOutputX[i].Delimiter[0];
        ScanPoint = TPOutputX[i].TransFormat;
        memset(TempTrans, 0 , MAX_TRANS_L+1);
        while ( (Field = strchr(ScanPoint, Del)) != NULL )
        {
            strncat(TempTrans, ScanPoint, Field-ScanPoint);
            if ( (FieldEnd = strchr(Field+1, Del)) != NULL )
            {
                memcpy(VarName, Field+1, FieldEnd-(Field+1));
                VarName[FieldEnd-(Field+1)] = NULL;
                VarNum = atoi(VarName);
				if ( VarNum > TPInputCnt )
				{
                    ErrLog(E104M, ERROR_L);
					return;
				}
 
                if ( VarNum > 0 )
                {
                    VarNum--;
                    strcat(TempTrans, TPInputX[VarNum].Value);
#ifdef GDI_DEBUG
sprintf(LogMsg, "Substituting [%d] with [%s]",
		VarNum+1, TPInputX[VarNum].Value);
Debug(LogMsg);
#endif
                }
                else
                {
                    for ( j=0; j<TPVariablesCnt; j++ )
                    {
                        if ( !strcmp(TPVariablesX[j].Name, VarName) )
                        {
                            strcat(TempTrans, TPVariablesX[j].VarValue);
#ifdef GDI_DEBUG
sprintf(LogMsg, "Substituting [%s] with [%s]",
		VarName, TPVariablesX[j].VarValue);
Debug(LogMsg);
#endif
                        }
                    }
                }
                ScanPoint = Field + strlen(VarName) + 2;
            }
            else
            {
                ScanPoint++;
            }
        }
        strcat(TempTrans, ScanPoint);
        strcpy(TPOutputX[i].Transaction, TempTrans);
        TPOutputX[i].Success = TRUE;
#ifdef GDI_DEBUG
sprintf(LogMsg, "Output transaction is [%s]",
		TPOutputX[i].Transaction);
Debug(LogMsg);
#endif
    }
}
 
 
/**************************************************************************
 *
 *   Function:      TransProcApplyTrans
 *   Description:   This function processes the transactions build by the
 *                  ApplyTrans functions by splitting the transaction into
 *                  elements and calling a function appropriate to the
 *                  transaction type.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int TransProcApplyTrans( void )
{
    int    i;
    int    ItemCnt;
    char   TranType;
    int    ErrSequence;
    struct TransElem *TI;
 
    Debug("TransProcApplyTrans begins");
 
    if ( !Initialised )
        return(FAILURE);
 
    ErrSeq = &ErrSequence;
    for ( i=0; i<TPOutputCnt; i++ )
    {
        ErrSequence = 0;
        if ( TPOutputX[i].Success )
        {
            CurTrans = TPOutputX[i].Transaction;
            if ( (TI = SplitTransaction(TPOutputX[i].Transaction,
                                        &ItemCnt)) != NULL )
            {
                if ( ItemCnt != EXPECTED_ITEM_CNT )
                {
                    ErrLog(E104M, ERROR_L);
                }
                if ( ErrSequence == 0 )
                {
                    TranType = TI[TYPE_IDX].Item[0];
                    switch ( TranType )
                    {
                        case ALIAS:
                        case SWRIS:
                        case READING:
                            CreateReading(TI, TRUE);
                            break;
                        case RANGE:
                            AssignRange(TI);
                            break;
/*
                        case DEACTIVATE:
                            DeactivateMATR(TI);
                            break;
*/
                        default:
                            ErrLog(E100M, ERROR_L);
                    }
                }
                free(TI);
            }
        }
    }
 
    Debug("TransProcApplyTrans successful");
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      CreateReading
 *   Description:   This function applies a reading entry to the database.
 *                  The Measurable Attribute of the Reading is identified
 *                  by its components or by its alias. The reading range
 *                  and Inactive flag is checked for validation purposes.
 *                  If the reading already exists, an update is applied
 *                  to the database.
 *
 *	Version Control:
 *
 *	Who		When     	What
 *	------- ---------	---------------------------------------------------
 *	B.D		01/07/96	Initial program release.
 *	D.R		25/02/98	Rejects reading transactions with no value.
 *						Bug fix to SWRIS Transaction loading.
 *  M.T     03/03/98    Added code to Local UOM conversion to come in to
 *                      line with the oduom package.
 *
 **************************************************************************/
void CreateReading( struct TransElem *TransItem, int ForceWarnings )
{
    int    ReadRange;
    int    DAMIS;
    char   TranType;
    char   DBAction[32];
    double LastAct;
    double LastDeact;
	char   ErrorCat[1024];
 
  	char   RAWREAD[50];
 
	ErrorCat[0] = '\0';
    strcpy (DBAction,"I");
   	strcpy (RAWREAD,"R");
 
    TranType = TransItem[TYPE_IDX].Item[0];
 
	/*
	|| Check to see if the reading has an actual value or is just a blank
	|| Readings that are simply blank, with no value will not be loaded
	|| into the database.
	|| No error is generated in this case.
	*/
 
	if (strlen(TransItem[VALU_IDX].Item) == 0 )
	{
		Debug("REJECT : Reading transaction has no value");
		return;
	}
 
    EXEC SQL
		COMMIT;
 
    switch ( TranType )
    {
 
    case SWRIS:
	/*
	|| Reading is identified in terms of SWRIS Station # and SWRIS Param
	/*
		Debug("Reading ID : SWRIS transaction");
 
		/* Transfer Built Transaction Item */
        strcpy(oIdentifier1, 	TransItem[ID1_IDX].Item);	/* SWRIS Station Number */
        strcpy(oIdentifier2, 	TransItem[ID2_IDX].Item);	/* SWRIS Parameter */
        strcpy(oDateTime, 		TransItem[DTIM_IDX].Item);	/* Reading Date Primary */
        strcpy(oQualType, 		TransItem[QUAL_IDX].Item);	/* Reading Quality Indicator */
        strcpy(oOrigin,   		TransItem[ORIG_IDX].Item);	/* Reading Origin */
        strcpy(oReadStat, 		TransItem[STAT_IDX].Item);	/* Reading Status */
        oValue = atof(TransItem[VALU_IDX].Item);			/* Reading Value */
 
 
		/* Search for readings monitoring point by SWRIS Station Number */
        EXEC SQL
			SELECT monp_id,
					NVL(monp_inactive_flg, 'N')
            INTO   :oMONPId,
                   :oInactive
            FROM   monitoring_point
            WHERE  UPPER(monp_swris_station_nmbr) = UPPER(:oIdentifier1);
 
		/* Check the success of the Monitoring Point search */
        if ( sqlca.sqlcode != SQL_OK )
        {
			/* Debug messages */
			sprintf(LogMsg, "Monp Lookup : Station[%s]\n", oIdentifier1);
			sprintf(LogMsg, "Sqlcode was [%d]\n", sqlca.sqlcode);
 
            if ( sqlca.sqlcode != SQL_NOT_FOUND )
            {
				ErrLog(E140M, DATABASE_L);
                return;
            }
 
			strcpy(ErrorCat, E103M);
			strcat(ErrorCat, " :SMonp ");
			strcat(ErrorCat, oIdentifier1);
            ErrLog(ErrorCat, WARNING_L);
			/*EXEC SQL COMMIT; /* Remove this for production */
            return;
		}
		Debug("Success : Monitoring Point Found");
		/*EXEC SQL COMMIT; /* Remove this for production */
 
		/* Search for the readings measurement by SWRIS parameter */
        EXEC SQL
			SELECT	mea_id,
					mea_uom_id_base
            INTO   	:oMEASId,
					:oBase_uom_id
            FROM   	measurement
            WHERE  	UPPER(mea_swris_param) = UPPER(:oIdentifier2);
 
		/* Check the success of the Measurement Search */
        if ( sqlca.sqlcode != SQL_OK )
        {
            if ( sqlca.sqlcode != SQL_NOT_FOUND )
			{
			    Debug("E140M- meas error");
                ErrLog(E140M, DATABASE_L);
				/*EXEC SQL COMMIT; /* Remove this for production */
                return;
            }
 
			strcpy(ErrorCat, E103M);
			strcat(ErrorCat, " :SMea ");
			strcat(ErrorCat, oIdentifier2);
            ErrLog(ErrorCat, WARNING_L);
			/*EXEC SQL COMMIT; /* Remove this for production */
            return;
		}
		Debug("Success : Measurement Found");
 
 
		/* Check the Active status of the measurement */
        EXEC SQL
			SELECT 	NVL(mea_inactive_flg, 'N'),
					mea_uom_id_base
            INTO   	:oInactive,
					:oBase_uom_id
            FROM   	measurement
            WHERE  	mea_id = :oMEASId;
 
		/* Check the success of the measurement search */
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E170M, DATABASE_L);
			/*EXEC SQL COMMIT; /* Remove this for production */
            return;
        }
 
 
		/* Search for a local UOM for the Measurement Point */
        EXEC SQL
			SELECT 	lmea_uom_id
			INTO 	:oDisplay_uom_id
			FROM	local_measurement lmeas
			WHERE  	lmea_mea_id = :oMEASId
			AND 	lmea_monp_id = :oMONPId;
 
		/* Check the success of the Local UOM Search */
        if ( sqlca.sqlcode != SQL_OK )
        {
            if ( sqlca.sqlcode == SQL_NOT_FOUND )
            {
	  			oDisplay_uom_id = oBase_uom_id;
		    }
		    else
		    {
	            ErrLog(E178M, DATABASE_L);
				/*EXEC SQL COMMIT; /* Remove this for production */
	            return;
		    }
        }
		Debug("Success : Searched for local UOM.");
		/*EXEC SQL COMMIT; /* Remove this for production */
 
 
		/* Check If This is a derived or Constant entry  */
		oType[0] = '\0';
		EXEC SQL
			SELECT	fmea_type
			INTO 	:oType
			FROM   	formula_measurement
			WHERE  	fmea_mea_id = :oMEASId
		 	AND 	fmea_monp_id = :oMONPId;
 
		/* Check the success of the formula measurement search */
        if ( sqlca.sqlcode != SQL_OK )
        {
            if ( sqlca.sqlcode == SQL_NOT_FOUND )
            {
	        	strcpy(oType, "D");
	    	}
	    	else
	    	{
            	ErrLog(E177M, DATABASE_L);
				/*EXEC SQL COMMIT; /* Remove this for production */
            	return;
	    	}
        }
 
		Debug("COMPLETE : SWRIS Transaction type processing.");
		/*EXEC SQL COMMIT; /* Remove this for production */
 
	/*
	|| End of SWRIS Measurement point identification
	*/
	break;
 
 
	/* We are identifying a measurable attribute by an alias : an alias consists of two identifiers */
    case ALIAS:
 
        strcpy(oIdentifier1, TransItem[ID1_IDX].Item);
        strcpy(oIdentifier2, TransItem[ID2_IDX].Item);
 
        EXEC SQL
			SELECT mpa_monp_id, mpa_mea_id
			INTO   :oMONPId, :oMEASId
			FROM   Measurement_point_Alias
			WHERE  upper(mpa_identifier1) = upper(:oIdentifier1)
			AND    upper(mpa_identifier2) = upper(:oIdentifier2);
 
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E102M, DATABASE_L);
            return;
        }
 
 
        EXEC SQL
			SELECT 	NVL(MEA_INACTIVE_fLG, 'N'),
					MEA_UOM_ID_BASE
			INTO   	:oInactive,
					:oBase_uom_id
			FROM   measurement
			WHERE  mea_id = :oMEASId;
 
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E170M, DATABASE_L);
            return;
        }
 
 
        EXEC SQL
			SELECT lmea_uom_id
			INTO 	:oDisplay_uom_id
			FROM 	local_measurement lmeas
			WHERE	lmea_mea_id = :oMEASId
			AND 	lmea_monp_id = :oMONPId;
 
        if ( sqlca.sqlcode != SQL_OK )
        {
            if ( sqlca.sqlcode == SQL_NOT_FOUND )
            {
				oDisplay_uom_id = oBase_uom_id;
			}
			else
			{
				ErrLog(E178M, DATABASE_L);
				return;
			}
        }
 
	break;
 
 
    case MEASPOINT:
		/*
		|| We are identifying a measuraement point by its key fields.
		|| The Monitroing Point Can belong to A Scheme or A site
		|| The above code was removed in favour of a strcopy with no %
		|| as the % was only causing errors in the SQL search.
		*/
 
		strcpy(oMEASCode, TransItem[FMNT_IDX].Item);
        strcpy(oFTYPCode, TransItem[FTYP_IDX].Item);
		strcpy(oReadStat, TransItem[STAT_IDX].Item);
        strcpy(oMONPCode, TransItem[MONP_IDX].Item);
        oSITECode = atoi(TransItem[SITE_IDX].Item);
        strcpy(oDateTime, TransItem[DTIM_IDX].Item);
        strcpy(oQualType, TransItem[QUAL_IDX].Item);
        strcpy(oOrigin,   TransItem[ORIG_IDX].Item);
        strcpy(oReadStat, TransItem[STAT_IDX].Item);
        oValue = atof(TransItem[VALU_IDX].Item);
 
 
        EXEC SQL
			SELECT 	monp_id,
					NVL(monp_inactive_flg, 'N')
			INTO  	:oMONPId,
					:oInactive
			FROM  	monitoring_point  A, site D,
					facility_type b
			WHERE 	UPPER(monp_code) = UPPER(:oMONPCode)
			AND   	site_id  = monp_site_id
			AND   	UPPER(site_asset_id) = UPPER(:oSITECode)
			AND   	ftyp_id = monp_ftyp_id
			AND   	UPPER(ftyp_code) = UPPER(:oFTYPCode);
 
        if ( sqlca.sqlcode != SQL_OK )
        {
			if ( sqlca.sqlcode != SQL_NOT_FOUND )
			{
				EXEC SQL
					SELECT	MONP_ID,
							NVL(MONP_Inactive_Flg, 'N')
					INTO  	:oMONPId,
                       		:oInactive
					FROM  	monitoring_point  A,
							scheme 	D,
		       				facility_type b
                 	WHERE 	UPPER(monp_code) = UPPER(:oMONPCode)
		 			AND   	schm_id  = monp_schm_id
		 			AND   	UPPER(schm_code) = UPPER(:oSITECode)
	         		AND   	ftyp_id = monp_ftyp_id
		 			AND   	UPPER(ftyp_code) = UPPER(:oFTYPCode);
 
                if ( sqlca.sqlcode != SQL_OK )
                {
                    if ( sqlca.sqlcode != SQL_NOT_FOUND )
                    {
                        ErrLog(E140M, DATABASE_L);
                        return;
                    }
				}
            }
 
            sprintf(ErrorCat, "%s :S/S %i", E103M, oSITECode);
            ErrLog(ErrorCat, WARNING_L);
			strcpy(ErrorCat, "Monp = ");
			strcat(ErrorCat, oMONPCode);
            ErrLog(ErrorCat, WARNING_L);
			strcpy(ErrorCat, "Ftyp = ");
			strcat(ErrorCat, oFTYPCode);
            ErrLog(ErrorCat, WARNING_L);
 
            return;
		}
 
        EXEC SQL
			SELECT	mea_id,
					mea_uom_id_base
			INTO	:oMEASId,
					:oBase_uom_id
			FROM   measurement
			WHERE  UPPER(mea_code) = UPPER(:oMEASCode);
 
        if ( sqlca.sqlcode != SQL_OK )
        {
            if ( sqlca.sqlcode != SQL_NOT_FOUND )
            {
                ErrLog(E140M, DATABASE_L);
                return;
            }
			strcpy(ErrorCat, E103M);
			strcat(ErrorCat, " :Mea ");
			strcat(ErrorCat, oMEASCode);
            ErrLog(ErrorCat, WARNING_L);
            return;
		}
 
        EXEC SQL
			SELECT	NVL(mea_inactive_flg, 'N'),
					mea_uom_id_base
			INTO	:oInactive,
					:oBase_uom_id
			FROM	measurement
			WHERE	mea_id = :oMEASId;
 
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E170M, DATABASE_L);
            return;
        }
 
        EXEC SQL
			SELECT	lmea_uom_id
	  	 	INTO	:oDisplay_uom_id
			FROM   	local_measurement lmeas
			WHERE  	lmea_mea_id = :oMEASId
		 	AND 	lmea_monp_id = :oMONPId;
 
        if ( sqlca.sqlcode != SQL_OK )
        {
            if ( sqlca.sqlcode == SQL_NOT_FOUND )
            {
		  		oDisplay_uom_id = oBase_uom_id;
		    }
		    else
		    {
	            ErrLog(E178M, DATABASE_L);
	            return;
		    }
        }
	break;
 
	/*
	|| Default is to try and load it by Meas Alias, IT ASSUMES THAT ONLY 1 IDENTIFIER
	|| EXISTS and is repeated into 2 - Will need addressing in V4
	*/
      default:
        strcpy(oMEASCode, TransItem[FMNT_IDX].Item);
        strcpy(oFTYPCode, TransItem[FTYP_IDX].Item);
        strcpy(oMEASCode, TransItem[FMNT_IDX].Item);
        strcpy(oMONPCode, TransItem[MONP_IDX].Item);
        strcpy(oMONPCode, TransItem[MONP_IDX].Item);
        oSITECode = atoi(TransItem[SITE_IDX].Item);
        strcpy(oDateTime, TransItem[DTIM_IDX].Item);
        strcpy(oQualType, TransItem[QUAL_IDX].Item);
        strcpy(oOrigin,   TransItem[ORIG_IDX].Item);
        strcpy(oReadStat, TransItem[STAT_IDX].Item);
        oValue = atof(TransItem[VALU_IDX].Item);
 
        EXEC SQL SELECT MEA_ID,
			MEA_UOM_ID_BASE
                 INTO  :oMEASId,
		       :oBase_uom_id
                 FROM   MEASUREMENT       MEAS,
			MEASUREMENT_ALIAS ALIAS
                 WHERE  MEAA_ASRC_ID      = ALIAS.ASRC_ID
                 AND    MEAS.MEA_ID       = ALIAS.MEA_ID
                 AND    MEAS.IDENTIFIER1  = :oMEASCode
                 AND    MEAS.IDENTIFIER2  = :oMEASCode
	         AND    ASRC_CODE = :TranType;
 
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E170M, DATABASE_L);
            return;
    	}
        EXEC SQL SELECT MONP_ID,
                        NVL(MONP_Inactive_Flg, 'N')
                 INTO   :oMONPId,
                        :oInactive
                 FROM   Monitoring_Point, Site, Scheme
                 WHERE  UPPER(MONP_CODE) = UPPER(:oMONPCode)
                 AND ((  SITE_ID  = MONP_SITE_ID
		 AND     UPPER(SITE_ASSET_ID) = UPPER(:oSITECode))
		 OR   (  SCHM_ID  = MONP_SCHM_ID
		 AND     UPPER(SCHM_CODE) = UPPER(:oSITECode)));
 
        if ( sqlca.sqlcode != SQL_OK )
        {
            if ( sqlca.sqlcode != SQL_NOT_FOUND )
            {
                ErrLog(E140M, DATABASE_L);
                return;
            }
 
			sprintf(ErrorCat, "%s :!M/S! %i", E103M, oSITECode);
			ErrLog(ErrorCat, WARNING_L);
			strcpy(ErrorCat, " Monp = ");
			strcat(ErrorCat, oMONPCode);
			ErrLog(ErrorCat, WARNING_L);
			return;
		}
 
        EXEC SQL SELECT NVL(MEA_INACTIVE_fLG, 'N'),
			MEA_UOM_ID_BASE
                 INTO   :oInactive,
			:oBase_uom_id
                 FROM   Measurement
                 WHERE  MEA_ID = :oMEASId;
 
            ErrLog(E170M, DATABASE_L);
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E170M, DATABASE_L);
            return;
        }
 
        EXEC SQL SELECT LMEA_uom_id
	  	 INTO 	:oDisplay_uom_id
                 FROM   LOCAL_MEASUREMENT LMEAS
                 WHERE  LMEA_MEA_ID = :oMEASId
		 AND 	LMEA_MONP_ID = :oMONPId;
 
        if ( sqlca.sqlcode != SQL_OK )
        {
           if ( sqlca.sqlcode == SQL_NOT_FOUND )
    		{
	 		oDisplay_uom_id = oBase_uom_id;
			}
	    else
	 		{
            ErrLog(E178M, DATABASE_L);
            return;
	 		}
        }
 
	break;
 
	/*
	|| End of Transaction Type processing.
	|| ************************************************************************
	*/
    }
 
	/*
	|| ************************************************************************
	|| Start of common reading loading routine.
	*/
 
	/*
	|| Check if the reading is a RAW trigger for a formula.
	*/
	EXEC SQL
		SELECT	fmea_type
		INTO	:oType
		FROM	formula_measurement
		WHERE	fmea_mea_id = :oMEASId
		AND		fmea_monp_id = :oMONPId;
 
	if ( sqlca.sqlcode != SQL_OK )
	{
		if ( sqlca.sqlcode == SQL_NOT_FOUND )
		{
			strcpy(oType, "D");
		}
		else
		{
            ErrLog(E177M, DATABASE_L);
            return;
		}
	}
 
	/* Check if any part of the readings record is inactive */
    if ( strcmp(oInactive, "N") )
    {
        ErrLog(E171M, ERROR_L);
        return;
    }
 
	/* Transfer the reading transaction details into the load variables  */
    strcpy(oDateTime, TransItem[DTIM_IDX].Item);
    strcpy(oQualType, TransItem[QUAL_IDX].Item);
    strcpy(oOrigin,   TransItem[ORIG_IDX].Item);
    strcpy(oReadStat, TransItem[STAT_IDX].Item);
    oValue = atof(TransItem[VALU_IDX].Item);
 
	Debug("STATUS : Transfered record details.");
	/*EXEC SQL COMMIT; /* Remove this for production */
 
 
	/* Check to see if the reading value has to be converted to the base UOM */
    if ( oBase_uom_id != oDisplay_uom_id )
    {
    	EXEC SQL
			SELECT	UOM_CONV_FCTR
			INTO	:oConv
			FROM	UNIT_OF_MEASURE
			WHERE	UOM_ID  = :oDisplay_uom_id;
 
    	if ( sqlca.sqlcode != SQL_OK )
    	{
            sprintf(ErrorCat, "%s :U %d", E175M, oDisplay_uom_id);
       	    ErrLog(ErrorCat, DATABASE_L);
            return;
		}
 
        oValue = oValue * oConv;
 
    	EXEC SQL
			SELECT	UOM_CONV_FCTR
			INTO	:oConv
			FROM	UNIT_OF_MEASURE
			WHERE	UOM_ID  = :oBase_uom_id;
 
    	if ( sqlca.sqlcode != SQL_OK )
    	{
            sprintf(ErrorCat, "%s :U %d", E175M, oBase_uom_id);
       	    ErrLog(ErrorCat, DATABASE_L);
            return;
		}
 
        oValue = oValue / oConv;
    }
 
 
	/* Check the Reading transaction Quality indicator */
    EXEC SQL
		SELECT	COUNT(*)
		INTO	:oCount
		FROM	CG_Ref_Codes
		WHERE	RV_Domain = 'READING QUALITIES'
		AND		RV_Low_Value = :oQualType;
    if ( sqlca.sqlcode != SQL_OK )
    {
        ErrLog(E173M, DATABASE_L);
        return;
    }
    else
    {
        if ( oCount == 0 )
        {
            ErrLog(E174M, ERROR_L);
            return;
        }
    }
 
 
	/* Check the reading transaction for a valid range */
    EXEC SQL
		SELECT	rdgr_low_range,
				rdgr_high_range
		INTO	:oLowRange,
				:oHighRange
		FROM	Reading_range rrng,
				range_type    rngt
		WHERE  	rdgr_mea_id = :oMEASId
		AND    	rdgr_monp_id = :oMONPId
		AND    	rrng.rdgr_rtyp_id   = rngt.rtyp_id
		AND    	rngt.rtyp_code = 'V';
 
    if ( sqlca.sqlcode != SQL_OK )
    {
        if ( sqlca.sqlcode != SQL_NOT_FOUND )
        {
            ErrLog(E105M, DATABASE_L);
            return;
        }
    }
    else
    {
        if ( (oValue < oLowRange) ||
             (oValue > oHighRange) )
        {
            sprintf(LogMsg, "Reading outside Validation range [%lf to %lf]",
                oLowRange,oHighRange);
            LogError( ErrSeq, CurProc, LogMsg, ERROR_L, CurRec, CurTrans );
            return;
        }
    }
 
    EXEC SQL
		SELECT	rdgr_low_range,
				rdgr_high_range
		INTO	:oLowRange,
				:oHighRange
		FROM   	reading_range rrng,
				range_type    rngt
		WHERE	rdgr_mea_id = :oMEASId
		AND		rdgr_monp_id = :oMONPId
		AND		rrng.rdgr_rtyp_id   = rngt.rtyp_id
		AND		rngt.rtyp_code = 'O';
    if ( sqlca.sqlcode != SQL_OK )
    {
        if ( sqlca.sqlcode != SQL_NOT_FOUND )
        {
            ErrLog(E105M, DATABASE_L);
            return;
        }
    }
    else
    {
        if ( (oValue < oLowRange) ||
             (oValue > oHighRange) )
        {
           if ( !ForceWarnings )
           {
            sprintf(LogMsg, "Reading outside Operational range [%lf to %lf]",
            oLowRange,oHighRange);
            LogError( ErrSeq, CurProc, LogMsg, ERROR_L, CurRec, CurTrans );
            return;
           }
        }
    }
 
	/*
	|| Check to see if the reading measurement point is part of a
	|| formula measurement.
	*/
    EXEC SQL
		SELECT	fmea_id
		INTO	:oFORMId
		FROM	formula_measurement
		WHERE	fmea_mea_id = :oMEASId
		AND		fmea_monp_id = :oMONPId;
 
    if ( sqlca.sqlcode != SQL_OK )
    {
        if ( sqlca.sqlcode != SQL_NOT_FOUND )
        {
            ErrLog(E177M, DATABASE_L);
            return;
        }
		oFORMId = 0;
    }
 
    /*
	|| Use date conversion routine to convert incoming date to
	|| standard GDI YYYYMMDDHH24MISS format
	*/
 
		/*
		|| Prepare the parameter string for the datecon package.
		*/
		/*
		-- if DateTime string is not the standard GDI format
		-- or if it contains characters, then send entire string
		-- to date conversion routine
		-- if DateTime is DDDHHMISS then grab DDD component only.
		--    (or in DDDHH:MI:SS)
		*/
#ifdef GDI_DEBUG
		Debug(oDateTime);
#endif
 
        oDatecomponent[0] = '\0';
		oTimecomponent[0] = '\0';
		oDateFormatMask[0] = '\0';
 
		if (strlen(oDateTime) < 12)
		{
			if (strlen(oDateTime) < 10)
			{
				EXEC SQL
					SELECT	substr(:oDateTime,1,3)
						   ,substr(:oDateTime,4)
					INTO	:oDatecomponent
						   ,:oTimecomponent
					FROM	DUAL;
 
				if ( sqlca.sqlcode != SQL_OK )
				{
					ErrLog(E178M, DATABASE_L);
					return;
				}
 
			}
			else 	/* (strlen(oDateTime) == 11) */
			{
				EXEC SQL
					SELECT	lpad(substr(:oDateTime,1,instr(:oDateTime,':')-3),3,'0')
						   ,substr(:oDateTime,instr(:oDateTime,':')-2,2)||
						    substr(:oDateTime,instr(:oDateTime,':')+1,2)||
						    substr(:oDateTime,instr(:oDateTime,':')+4,2)
					INTO	:oDatecomponent
						   ,:oTimecomponent
					FROM	DUAL;
 
				if ( sqlca.sqlcode != SQL_OK )
				{
					ErrLog(E178M, DATABASE_L);
					return;
				}
			}
 
			sprintf(oIOParm, "%s\0", oDatecomponent);
			sprintf(oDateFormatMask,"YYYYMMDD\0");
			RemoveTrailingBlanks(oIOParm, oIOParm);
 
			EXEC SQL
				SELECT	datecon2.dte_fmt_cen_fun(:oIOParm, :oDateFormatMask)
				INTO	:oDatecomponent
				FROM	DUAL;
 
#ifdef GDI_DEBUG
		Debug(oIOParm);
		Debug(oDatecomponent);
#endif
		  if ( sqlca.sqlcode != SQL_OK )
		  {
			ErrLog(E176M, DATABASE_L);
			return;
		  }
		  else
		  {
			/* Copy oTimecomponent back into oDatetime */
			strcpy(oDateTime,oDatecomponent);
			strcat(oDateTime,oTimecomponent);
		  }
		}
Debug(oDateTime);
 
 
#ifdef GDI_DEBUG
	sprintf(LogMsg, "Reading is [%d,%f,%s,%s,%s]",
					oDateTime, oValue, oReadStat,oQualType, oOrigin );
	Debug(LogMsg);
#endif
 
    strcpy (DBAction,"I");
 
	/*
	|| Check for Rea_Update flag.  If it is Y insert a row and update the
	|| row it is found.  If it is N dont update the row if a reading for the
	|| same Measurement, Monitoring Point and same DATE (disregarding TIME) exists.
	||
	|| SR#078903
	*/
 
	if ( CheckReaUpdate == 1 )
	{
		/*
		|| Find if a reading with the date exists.
		*/
		EXEC SQL
			SELECT COUNT(*)
			INTO :oCount2
			FROM READING
			WHERE REA_MONP_ID = :oMONPId AND
			REA_MEA_ID = :oMEASId AND
			TRUNC(REA_DT_PRIMARY) = TRUNC(TO_DATE(:oDateTime, 'YYYYMMDDHH24MISS'));
 
		if ( sqlca.sqlcode != SQL_OK )
		{
			ErrLog(E179M, DATABASE_L);
		    return;
		}
 
		if ( oCount2 == 0 )
		{
			EXEC SQL
			INSERT INTO Reading
				(	rea_id,
					rea_mea_id,
					rea_monp_id,
					rea_value,
					rea_dt_primary,
					rea_quality_ind,
					rea_dt_secondary,
					rea_state,
					rea_lsam_id,
					rea_inactive_flag,
					rea_fmea_id,
					rea_dt_created,
					rea_created_by,
					rea_dt_modified,
 					rea_modified_by,
					rea_origin
				)
			VALUES
				( 	REA_SEQ.NEXTVAL,
					:oMEASId,
					:oMONPId,
					:oValue,
					TO_DATE(:oDateTime, 'YYYYMMDDHH24MISS'),
					:oQualType,
					NULL,
					:oReadStat,
					NULL,
					NULL,
					decode(:oFORMId, 0, NULL, :oFORMId),
					SYSDATE,
					'GDI',
					NULL,
					NULL,
					:oOrigin
			 	);
 
			if ( sqlca.sqlcode != SQL_OK )
        		{
        		    ErrLog(E109M, DATABASE_L);
        		    return;
        		}
		}
    	}
 
	else
 
	{
		/* Insert the reading */
    	EXEC SQL
			INSERT INTO Reading
				(	rea_id,
					rea_mea_id,
					rea_monp_id,
					rea_value,
					rea_dt_primary,
					rea_quality_ind,
					rea_dt_secondary,
					rea_state,
					rea_lsam_id,
					rea_inactive_flag,
					rea_fmea_id,
					rea_dt_created,
					rea_created_by,
					rea_dt_modified,
					rea_modified_by,
					rea_origin
				)
			VALUES
				( 	REA_SEQ.NEXTVAL,
					:oMEASId,
					:oMONPId,
					:oValue,
					TO_DATE(:oDateTime, 'YYYYMMDDHH24MISS'),
					:oQualType,
					NULL,
					:oReadStat,
					NULL,
					NULL,
					decode(:oFORMId, 0, NULL, :oFORMId),
					SYSDATE,
					'GDI',
					NULL,
					NULL,
					:oOrigin
				);
 
		/* Check the success of the reading insert */
    	if ( sqlca.sqlcode != SQL_OK )
    	{
			/*
			|| The reading insert failed
			|| Check if the insert failed for reasons other than duplicate value
			*/
    	    if ( sqlca.sqlcode != DUP_VAL )
    	    {
    	        ErrLog(E109M, DATABASE_L);
    	        return;
    	    }
 
			/*
			|| The transaction type is update
			*/
 
			strcpy (DBAction,"U");
 
			EXEC SQL
				UPDATE	reading
				SET		rea_value       = :oValue,
						rea_quality_ind = :oQualType,
						rea_dt_modified = SYSDATE,
						rea_modified_by = 'GDI'
				WHERE	rea_mea_id = :oMEASId
				AND		rea_monp_id = :oMONPId
				AND		rea_dt_primary = TO_DATE(:oDateTime,'YYYYMMDDHH24MISS');
 
			if ( sqlca.sqlcode != SQL_OK )
			{
				ErrLog(E141M, DATABASE_L);
				Debug("UPDATE Reading");
				sprintf(ErrorCat, "Mea ID = %i, Monp ID = %i", oMEASId, oMONPId);
				Debug(ErrorCat);
				sprintf(ErrorCat, "Datetime = %s, Value = %f, Qual = %s", oDateTime, oValue, oQualType);
				Debug(ErrorCat);
				return;
            }
		}
	}
 
 
#ifdef GDI_DEBUG
   sprintf(LogMsg, "Read Type  is [%s][%s]", oType, RAWREAD);
   Debug(LogMsg);
#endif
 
    RemoveTrailingBlanks(oType, oType);
    RemoveTrailingBlanks(RAWREAD, RAWREAD);
 
    if ( strcmp(oType, "D") )
    {
		/*
		|| Load the formula measurement id for the measurement point being inserted.
		*/
        EXEC SQL
			SELECT	fmea_id
			INTO	:oFORMId
			FROM	formula_measurement
			WHERE	fmea_mea_id = :oMEASId
			AND		fmea_monp_id = :oMONPId;
 
        if ( sqlca.sqlcode != SQL_OK )
        {
			ErrLog(E177M, DATABASE_L);
			return;
		}
 
		/*
		|| Load the reading id that the formula value is derived from.
		*/
		EXEC SQL
			SELECT	rea_id
			INTO	:oREADId
			FROM	reading
			WHERE	rea_mea_id = :oMEASId
			AND		rea_monp_id = :oMONPId
			AND		rea_dt_primary = TO_DATE(:oDateTime, 'YYYYMMDDHH24MISS');
 
		if ( sqlca.sqlcode != SQL_OK )
		{
			ErrLog(E141M, DATABASE_L);
			sprintf(ErrorCat, "Mea id [%i] Monp id [%i] Datetime [%s]", oMEASId, oMONPId, oDateTime);
			ErrLog(ErrorCat, DATABASE_L);
			return;
		}
 
		/*
		|| Prepare the parameter string for the formula measurement package.
		*/
		sprintf(oIOParm, "%i,%i,'GDI'", oFORMId, oREADId);
		RemoveTrailingBlanks(oIOParm, oIOParm);
		sprintf(oSqlStmt, "BEGIN formula_calc.calculation(%s); END;", oIOParm);
 
#ifdef GDI_DEBUG
		Debug(oSqlStmt);
		Debug(oIOParm);
#endif
 
		/*
		|| Call the formula measurement package.
		*/
		EXEC SQL PREPARE FormulaCall FROM :oSqlStmt;
		EXEC SQL EXECUTE FormulaCall;
 
		if ( sqlca.sqlcode != SQL_OK )
		{
			ErrLog(E176M, DATABASE_L);
			return;
		}
	}
 
	/*
	|| The reading was successfully loaded.
	*/
    LogSuccess(oProcid, CurTrans);
    Debug("Reading created/updated");
}
 
 
/**************************************************************************
 *
 *   Function:      AssignRange
 *   Description:   This function assigns a valid or operation range to a
 *                  Measurement Point. If the Range already exists, it
 *                  is updated.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
void AssignRange(struct TransElem *Trans)
{
/*    strcpy(oRTYPCode, Trans[RTYP_IDX].Item);            */
    strcpy(oMEASCode, Trans[FMNT_IDX].Item);
    strcpy(oFTYPCode, Trans[FTYP_IDX].Item);
    strcpy(oMONPCode, Trans[MONP_IDX].Item);
    oSITECode = atoi(Trans[SITE_IDX].Item);
 
    EXEC SQL SELECT RDGR_MEA_ID,
		    RGDR_MONP_ID
             INTO   :oMEASId,
		    :oMONPId
             FROM   Measurement 	 FMNT,
                    Monitoring_Point     MONP,
                    Facility_Type        FTYP,
                    Site                 SITE
	     WHERE  MONP.FTYP_Id      = FTYP.FTYP_Id
             AND    MONP.SITE_Id      = SITE.SITE_Id
             AND    FMNT.MEAS_Code    = :oMEASCode
             AND    FTYP.FTYP_Code    = :oFTYPCode
             AND    MONP.MONP_Code    = :oMONPCode
             AND    SITE.SITE_AssetId = :oSITECode;
 
    if ( sqlca.sqlcode != SQL_OK )
    {
        ErrLog(E140M, DATABASE_L);
        return;
    }
 
    /*
     * Range type must be Valid or Operational
     * Default is Operational.
     */
    if ( strcmp(Trans[QUAL_IDX].Item, "V") )
        strcpy(oRTYPCode, "O");
    else
        strcpy(oRTYPCode, "V");
 
    oLowRange  = atof(Trans[VALU_IDX].Item);
    oHighRange = atof(Trans[STAT_IDX].Item);
 
    EXEC SQL SELECT RTYP_Id
             INTO   :oRTYPId
             FROM   Range_Type
             WHERE  RTYP_Code = :oRTYPCode;
    if ( sqlca.sqlcode != SQL_OK )
    {
        ErrLog(E167M, DATABASE_L);
        return;
    }
 
    EXEC SQL SELECT COUNT(*)
             INTO   :oCount
             FROM   Reading_Range
             WHERE  RDGR_RTYP_Id = :oRTYPId
	     AND    RDGR_MONP_ID = :oMONPId
	     AND    RDGR_MES_ID = :oMEASId;
 
    if ( sqlca.sqlcode != SQL_OK )
    {
        ErrLog(E168M, DATABASE_L);
        return;
    }
 
    if ( !oCount )
    {
        EXEC SQL INSERT INTO Reading_Range
                           ( RDGR_RTYP_Id,
                             RDGR_MONP_ID,
			     RDGR_MEA_ID,
                             RDGR_Low_Range,
                             RDGR_High_Range )
                    VALUES ( :oRTYPId,
                             :oMONPId,
                             :oMEASId,
                             :oLowRange,
                             :oHighRange );
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E165M, DATABASE_L);
            return;
        }
        Debug("Reading range created");
    }
    else
    {
        EXEC SQL UPDATE Reading_Range
                 SET    RRNG_Low_Range  = :oLowRange,
                        RRNG_High_Range = :oHighRange
                 WHERE  RNGT_Id  = :oRTYPId
	         AND  MONP.FTYP_Id      = FTYP.FTYP_Id
                 AND    MONP.SITE_Id      = SITE.SITE_Id;
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E148M, DATABASE_L);
            return;
        }
        Debug("Range range updated");
    }
 
    LogSuccess(oProcid, CurTrans);
}
 
/**************************************************************************
 *
 *   Function:      GetSITE
 *   Description:   This function identifies a SITE by a given SITE Code
 *                  and loads its unique sequence number into a global
 *                  host variable.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int GetSITE(struct TransElem *Trans)
{
    oSITECode = atoi(Trans[SITE_IDX].Item);
    EXEC SQL SELECT SITE_Id,
                    NVL(SITE_Inactive_Flg, 'N')
             INTO   :oSITEId,
                    :oIFlag
             FROM   Site
             WHERE  SITE_AssetId = :oSITECode;
    if ( sqlca.sqlcode != SQL_OK )
    {
        if ( sqlca.sqlcode == SQL_NOT_FOUND )
            ErrLog(E151M, ERROR_L);
        else
            ErrLog(E149M, DATABASE_L);
        return(FAILURE);
    }
 
    if ( !strcmp(oIFlag, "Y") )
    {
        ErrLog(E150M, ERROR_L);
        return(FAILURE);
    }
 
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      GetFTYPAndUNIT
 *   Description:   This function identifies a FTYP by a given FTYP Code
 *                  and loads its unique sequence number into a global
 *                  host variable. Each FTYP has a default report and base
 *                  UOM. The sequence numbers of these UOMs are also
 *                  loaded.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
int GetFTYPAndUNIT(struct TransElem *Trans)
{
    strcpy(oFTYPCode, Trans[FTYP_IDX].Item);
    strcpy(oMEASCode, Trans[FMNT_IDX].Item);
    EXEC SQL SELECT FTYP.FTYP_Id,
		    FMNT_REPORT_UOM_ID,
                    NVL(FTYP_Inactive_Flg, 'N')
             INTO   :oFTYPId,
                    :oUNITRep,
                    :oIFlag
             FROM   Facility_Type FTYP,
   	  	    Facility_measurement FMNT
             WHERE  FTYP_Code = :oFTYPCode
             AND    FMNT_Code = :oMEASCode
             AND    FTYP.FTYP_ID = FMNT.FTYP_ID;
    if ( sqlca.sqlcode != SQL_OK )
    {
        ErrLog(E152M, DATABASE_L);
        return(FAILURE);
    }
 
    if ( !strcmp(oIFlag, "Y") )
    {
        ErrLog(E153M, ERROR_L);
        return(FAILURE);
    }
 
    EXEC SQL SELECT UCAT.UCAT_Base_UOM_Id
             INTO   :oUNITBase
             FROM   Unit_Of_Measure UNIT,
                    UOM_Category    UCAT
             WHERE  UNIT.UOM_Id = :oUNITRep
             AND    UNIT.UCAT_Id = UCAT.UCAT_Id;
    if ( sqlca.sqlcode != SQL_OK )
    {
        ErrLog(E144M, DATABASE_L);
        return(FAILURE);
    }
 
    return(SUCCESS);
}
 **************************************************************************/
 
 
/**************************************************************************
 *
 *   Function:      GetCreateMONP
 *   Description:   This function identifies a MONP by a given MONP Code
 *                  and loads its unique sequence number into a global
 *                  host variable.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int GetCreateMONP(struct TransElem *Trans)
{
    strcpy(oMONPCode, Trans[MONP_IDX].Item);
    EXEC SQL SELECT MONP_Id,
                    NVL(MONP_Inactive_Flg, 'N')
             INTO   :oMONPId,
                    :oIFlag
             FROM   Monitoring_Point
             WHERE  MONP_Code = :oMONPCode
             AND    SITE_Id   = :oSITEId
             AND    FTYP_Id   = :oFTYPId;
    if ( sqlca.sqlcode != SQL_OK )
    {
        if ( sqlca.sqlcode != SQL_NOT_FOUND )
        {
            ErrLog(E156M, DATABASE_L);
            return(FAILURE);
        }
        ErrLog(E156M, DATABASE_L);
        return(FAILURE);
        EXEC SQL SELECT MONP_SEQ.NEXTVAL
                 INTO   :oMONPId
                 FROM   DUAL;
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E157M, DATABASE_L);
            return(FAILURE);
        }
        EXEC SQL INSERT INTO Monitoring_Point
                        (
			 MONP_ID,
			 MONP_SITE_ID,
			 MONP_SCHM_ID,
			 MONP_FTYP_ID,
			 MONP_CODE,
			 MONP_DESC,
			 MONP_ASSBLE,
			 MONP_ASSET_ID,
			 MONP_WO_NUMBER,
			 MONP_SWRIS_STATION_NMBR,
			 MONP_DT_ESTAB,
			 MONP_DT_CREATED,
			 MONP_CREATED_BY,
			 MONP_DT_MODIFIED,
			 MONP_MODIFIED_BY,
			 MONP_INACTIVE_FLG
                         )
                    VALUES
			 ( :oMONPId,
                           :oSITEId,
			   NULL,
                           :oFTYPId,
                           :oMONPCode,
                           'Undefined',
			   NULL,
			   NULL,
			   NULL,
			   NULL,
			   NULL,
			   NULL,
			   NULL,
			   NULL,
			   NULL,
			   NULL
			 );
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E158M, DATABASE_L);
            return(FAILURE);
        }
        Debug("Monitoring point created");
    }
    else
    {
        if ( !strcmp(oIFlag, "Y") )
        {
            ErrLog(E155M, ERROR_L);
            return(FAILURE);
        }
    }
 
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      GetCreateFMNT
 *   Description:   This function identifies a FMNT by a given FMNT Code
 *                  and loads its unique sequence number into a global
 *                  host variable.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
int GetCreateFMNT(struct TransElem *Trans)
{
    strcpy(oMEASCode, Trans[FMNT_IDX].Item);
    EXEC SQL SELECT FMNT_Id,
                    NVL(FMNT_Inactive_Flg, 'N')
             INTO   :oFMNTId,
                    :oIFlag
             FROM   Facility_Measurement
             WHERE  FTYP_Id   = :oFTYPId
             AND    FMNT_Code = :oMEASCode;
    if ( sqlca.sqlcode != SQL_OK )
    {
        if ( sqlca.sqlcode != SQL_NOT_FOUND )
        {
            ErrLog(E159M, DATABASE_L);
            return(FAILURE);
        }
        EXEC SQL SELECT FMNT_SEQ.NEXTVAL
                 INTO   :oFMNTId
                 FROM   DUAL;
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E160M, DATABASE_L);
            return(FAILURE);
        }
        ErrLog(E160M, DATABASE_L);
        return(FAILURE);
        EXEC SQL INSERT INTO Facility_Measurement
                           ( FMNT_Id,
                             FTYP_Id,
                             FMNT_Code,
                             FMNT_Description )
                    VALUES ( :oFMNTId,
                             :oFTYPId,
                             :oMEASCode,
                             'Undefined' );
        if ( sqlca.sqlcode != SQL_OK )
        {
            ErrLog(E161M, DATABASE_L);
            return(FAILURE);
        }
        Debug("Facility Measurement created");
    }
    else
    {
        if ( !strcmp(oIFlag, "Y") )
        {
            ErrLog(E146M, ERROR_L);
            return(FAILURE);
        }
    }
 
    return(SUCCESS);
}
 
 **************************************************************************/
 
/*-----------------------------------------------------------------------------
||
||   Function:      SplitTransaction
||  Description:   This function splits a built transaction into
||                   individual elements.
||
||   Version Control:
||   Who  When      What
||   ---- --------  ----------------------------------------------------------
||   B.D  01/07/96  Initial program release.
||
-----------------------------------------------------------------------------*/
 
struct TransElem *SplitTransaction( char *Transaction,
                                    int  *ItemCnt )
{
    int    i;
    int    ElemCnt;
    int    ElemLen;
    int    ErrLen;
    char  *Del;
    char  *Field;
    struct TransElem *TransElemX;
    char   TempTrans[MAX_TRANS_L+1];
 
    ElemCnt = 1;
    ErrLen = FALSE;
    Del = Transaction;
    while ( (Del = strchr(Del, ',')+1) > (char *)1 )
        ElemCnt++;
    *ItemCnt = ElemCnt;
    TransElemX = (struct TransElem *)malloc(sizeof(struct TransElem) *
                                            ElemCnt);
    if ( TransElemX == NULL )
    {
        ErrLog(E101M, ERROR_L);
    }
    else
    {
        memcpy(TempTrans, Transaction, MAX_TRANS_L+1);
        Field = Del = TempTrans;
        for ( i=0; i<ElemCnt; i++ )
        {
            memset(TransElemX[i].Item, 0, MAX_FIELD_L + 1);
            if ( (Del = strchr(Field, ',')) != NULL )
			   *Del = NULL;
            RemoveTrailingBlanks(Field, Field);
            ElemLen = strlen(Field);
            if ( (ElemLen < TransValidX[i][MIN_IDX]) ||
                 (ElemLen > TransValidX[i][MAX_IDX]) )
                ErrLen = TRUE;
            else
                strncpy(TransElemX[i].Item, Field, MAX_FIELD_L);
            Field = Del + 1;
#ifdef GDI_DEBUG
sprintf(LogMsg, "Transaction item [%d] is [%s]",
		i+1, TransElemX[i].Item);
Debug(LogMsg);
#endif
        }
    }
 
    if ( ErrLen )
        ErrLog(E110M, ERROR_L);
 
    return(TransElemX);
}
 
 
/**************************************************************************
 *
 *   Function:      TransProcFinalise
 *   Description:   This function frees any allocated memory.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
int TransProcFinalise( void )
{
    if ( !Initialised )
        return(FAILURE);
 
    Initialised = FALSE;
 
    if  ( TPInputX != NULL )
        free(TPInputX);
    if  ( TPOutputX != NULL )
        free(TPOutputX);
    if  ( TPRejectsX != NULL )
        free(TPRejectsX);
    if  ( TPVariablesX != NULL )
        free(TPVariablesX);
    if  ( TPTransX != NULL )
        free(TPTransX);
    if  ( TPFormulaeX != NULL )
        free(TPFormulaeX);
 
    Debug("Trans process finalised successfully");
    return(SUCCESS);
}
 
 
/**************************************************************************
 *
 *   Function:      SetLogGlobals
 *   Description:   This function sets global variables that are used
 *                  throughout the Transaction Processing Library.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
void SetLogGlobals ( int  *ErrSequence,
		     char *CurJobname,
                     char *CurProcid,
                     char *CurRecord,
                     char *CurTransaction )
{
    ErrSeq   = ErrSequence;
    CurProc  = CurProcid;
    CurRec   = CurRecord;
    CurTrans = CurTransaction;
#ifdef GDI_DEBUG
strcpy(oJobname, CurJobname);
#endif
}
 
 
/**************************************************************************
 *
 *   Function:      ErrLog
 *   Description:   This function provides a wrapper for the LogError
 *                  subroutine and substitutes global values into the
 *                  LogError parameter list.
 *
 *   Version Control:
 *   Who  When      What
 *   B.D  01/07/96  Initial program release.
 *
 **************************************************************************/
void ErrLog ( char *ErrMsg, char *ErrType )
{
    if ( LogError( ErrSeq,
                   CurProc,
                   ErrMsg,
                   ErrType,
                   CurRec,
                   CurTrans ) )
    {
        sprintf(LogMsg, "LogError call failed [%d]", sqlca.sqlcode);
        JobLog(oJobname, ERROR_T, LogMsg);
    }
}

Open in new window

0
 

Author Comment

by:darrylf290567
ID: 20332191
Hi sdstuber,

Could I even use PLSQL to read the files and then insert and update the data from the files into the database?

Do you know of any really good sites that has examples on how to do this?

Kind Regards
darrylf290567
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 27

Expert Comment

by:sujith80
ID: 20332457
Are you looking for the configurations required to use VC++ to compile pro*c code? If so, this guide might help.
http://download.oracle.com/docs/cd/B19306_01/win.102/b14321/toc.htm

>> Couldn't I use some Oracle Library files and embed the SQL inside the C code.
Pro*C does exactly the same thing. YOu embed the SQL, pre-compile it using the libraries to convert it to native C code.

>> Could you please give me an example of calling a Oracle Stored Procedure via C code calling an Oracle Stored Procedure or even embedded SQL to do insert and upates
See this guide.
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14407/toc.htm
0
 

Author Comment

by:darrylf290567
ID: 20332929
Could I even use PLSQL to read the files and then insert and update the data from the files into the database?

Do you know of any really good sites that has examples on how to do this?

darylf290567
0
 

Author Comment

by:darrylf290567
ID: 20332990
Hi All,

Does Pro* C compile on a Windows 2003 box with Oracle 10g on that box? Is there any article a blog that shows you how to do this?

Kind Regards
darrylf290567
0
 
LVL 27

Expert Comment

by:sujith80
ID: 20333043
0
 
LVL 27

Accepted Solution

by:
sujith80 earned 500 total points
ID: 20333044
>> Does Pro* C compile on a Windows 2003 box with Oracle 10g on that box?
Yes, provided you have VC++ on the machine.
0
 

Author Comment

by:darrylf290567
ID: 20347264
Hi sujith80,

Your help has been excellent. However, I have got VC++ version 6 on my PC and I have Oracle 10G on my PC as well. I followed the steps as in the abovementioned links that you have provided me in how to integrate Pro* C with VC++. But I am getting the following link errors as indicated below:

I have created the project as a Win32 Console application. Is this correct? I have also tried it as a Win32 Application and that had linking problems as well? Please can you help me.

Linking...
LINK : warning LNK4001: no object files specified; libraries used
LINK : error LNK2001: unresolved external symbol _mainCRTStartup
Debug/VisualProC_v2.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

VisualProC_v2.exe - 2 error(s), 1 warning(s)

0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article started out as an Experts-Exchange question, which then grew into a quick tip to go along with an IOUG presentation for the Collaborate confernce and then later grew again into a full blown article with expanded functionality and legacy…
From implementing a password expiration date, to datatype conversions and file export options, these are some useful settings I've found in Jasper Server.
This video explains what a user managed backup is and shows how to take one, providing a couple of simple example scripts.
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.

789 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question