]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/dbtable.cpp
Need LINKAGEMODE for Visualage C++ compiles on the static global procs at the top
[wxWidgets.git] / src / common / dbtable.cpp
index 1113157d9028ab6076be760c361598f033d41673..edf1a0ce1ca4f4d9075de72b05e942ddeb7b89b6 100644 (file)
        #include "wx/dbtable.h"
 #endif
 
-#ifdef __MWERKS__
-#ifdef __WXMSW__
-#define stricmp _stricmp
-#define strnicmp _strnicmp
-#else
-int strcasecmp(const char *str_1, const char *str_2) ;
-int strncasecmp(const char *str_1, const char *str_2, size_t maxchar) ;
-#define stricmp strcasecmp
-#define strnicmp strncasecmp
-#endif
-#endif
-
 #ifdef __UNIX__
 // The HPUX preprocessor lines below were commented out on 8/20/97
 // because macros.h currently redefines DEBUG and is unneeded.
@@ -114,7 +102,7 @@ ULONG lastTableID = 0;
 
 /********** wxTable::wxTable() **********/
 wxTable::wxTable(wxDB *pwxDB, const char *tblName, const int nCols,
-                                       const char *qryTblName, bool qryOnly, char *tblPath)
+                                       const char *qryTblName, bool qryOnly, const char *tblPath)
 {
        pDb                                     = pwxDB;                                        // Pointer to the wxDB object
        henv                                    = 0;
@@ -137,14 +125,14 @@ wxTable::wxTable(wxDB *pwxDB, const char *tblName, const int nCols,
 
        assert (tblName);
 
-       strcpy(tableName, tblName);                             // Table Name
+       wxStrcpy(tableName, tblName);                           // Table Name
        if (tblPath)
-               strcpy(tablePath, tblPath);                             // Table Path - used for dBase files
+               wxStrcpy(tablePath, tblPath);                           // Table Path - used for dBase files
 
        if (qryTblName)                                                         // Name of the table/view to query
-               strcpy(queryTableName, qryTblName);
+               wxStrcpy(queryTableName, qryTblName);
        else
-               strcpy(queryTableName, tblName);
+               wxStrcpy(queryTableName, tblName);
 
 //     assert(pDb);  // Assert is placed after table name is assigned for error reporting reasons
        if (!pDb)
@@ -321,6 +309,250 @@ wxTable::~wxTable()
 
 }  // wxTable::~wxTable()
 
+/***************************** PRIVATE FUNCTIONS *****************************/
+
+/********** wxTable::bindInsertParams() **********/
+bool wxTable::bindInsertParams(void)
+{
+       assert(!queryOnly);
+       if (queryOnly)
+               return(FALSE);
+
+       SWORD   fSqlType        = 0;
+       UDWORD  precision       = 0;
+       SWORD   scale           = 0;
+
+       // Bind each column (that can be inserted) of the table to a parameter marker
+       int i;
+       for (i = 0; i < noCols; i++)
+       {
+               if (! colDefs[i].InsertAllowed)
+                       continue;
+               switch(colDefs[i].DbDataType)
+               {
+               case DB_DATA_TYPE_VARCHAR:
+                       fSqlType = pDb->typeInfVarchar.FsqlType;
+                       precision = colDefs[i].SzDataObj;
+                       scale = 0;
+                       colDefs[i].CbValue = SQL_NTS;
+                       break;
+               case DB_DATA_TYPE_INTEGER:
+                       fSqlType = pDb->typeInfInteger.FsqlType;
+                       precision = pDb->typeInfInteger.Precision;
+                       scale = 0;
+                       colDefs[i].CbValue = 0;
+                       break;
+               case DB_DATA_TYPE_FLOAT:
+                       fSqlType = pDb->typeInfFloat.FsqlType;
+                       precision = pDb->typeInfFloat.Precision;
+                       scale = pDb->typeInfFloat.MaximumScale;
+                       // SQL Sybase Anywhere v5.5 returned a negative number for the
+                       // MaxScale.  This caused ODBC to kick out an error on ibscale.
+                       // I check for this here and set the scale = precision.
+                       //if (scale < 0)
+                       //      scale = (short) precision;
+                       colDefs[i].CbValue = 0;
+                       break;
+               case DB_DATA_TYPE_DATE:
+                       fSqlType = pDb->typeInfDate.FsqlType;
+                       precision = pDb->typeInfDate.Precision;
+                       scale = 0;
+                       colDefs[i].CbValue = 0;
+                       break;
+               }
+               // Null values
+               if (colDefs[i].Null)
+               {
+                       colDefs[i].CbValue = SQL_NULL_DATA;
+                       colDefs[i].Null = FALSE;
+               }
+               if (SQLBindParameter(hstmtInsert, i+1, SQL_PARAM_INPUT, colDefs[i].SqlCtype,
+                                                                       fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, 
+                                                                       precision+1,&colDefs[i].CbValue) != SQL_SUCCESS)
+                       return(pDb->DispAllErrors(henv, hdbc, hstmtInsert));
+       }
+
+       // Completed successfully
+       return(TRUE);
+
+}  // wxTable::bindInsertParams()
+
+/********** wxTable::bindUpdateParams() **********/
+bool wxTable::bindUpdateParams(void)
+{
+       assert(!queryOnly);
+       if (queryOnly)
+               return(FALSE);
+
+       SWORD   fSqlType        = 0;
+       UDWORD  precision       = 0;
+       SWORD   scale           = 0;
+       
+       // Bind each UPDATEABLE column of the table to a parameter marker
+       int i,colNo;
+       for (i = 0, colNo = 1; i < noCols; i++)
+       {
+               if (! colDefs[i].Updateable)
+                       continue;
+               switch(colDefs[i].DbDataType)
+               {
+               case DB_DATA_TYPE_VARCHAR:
+                       fSqlType = pDb->typeInfVarchar.FsqlType;
+                       precision = colDefs[i].SzDataObj;
+                       scale = 0;
+                       colDefs[i].CbValue = SQL_NTS;
+                       break;
+               case DB_DATA_TYPE_INTEGER:
+                       fSqlType = pDb->typeInfInteger.FsqlType;
+                       precision = pDb->typeInfInteger.Precision;
+                       scale = 0;
+                       colDefs[i].CbValue = 0;
+                       break;
+               case DB_DATA_TYPE_FLOAT:
+                       fSqlType = pDb->typeInfFloat.FsqlType;
+                       precision = pDb->typeInfFloat.Precision;
+                       scale = pDb->typeInfFloat.MaximumScale;
+                       // SQL Sybase Anywhere v5.5 returned a negative number for the
+                       // MaxScale.  This caused ODBC to kick out an error on ibscale.
+                       // I check for this here and set the scale = precision.
+                       //if (scale < 0)
+                       // scale = (short) precision;
+                       colDefs[i].CbValue = 0;
+                       break;
+               case DB_DATA_TYPE_DATE:
+                       fSqlType = pDb->typeInfDate.FsqlType;
+                       precision = pDb->typeInfDate.Precision;
+                       scale = 0;
+                       colDefs[i].CbValue = 0;
+                       break;
+               }
+               if (SQLBindParameter(hstmtUpdate, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype,
+                                                                       fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, 
+                                                                       precision+1, &colDefs[i].CbValue) != SQL_SUCCESS)
+                       return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
+       }
+
+       // Completed successfully
+       return(TRUE);
+
+}  // wxTable::bindUpdateParams()
+
+/********** wxTable::bindCols() **********/
+bool wxTable::bindCols(HSTMT cursor)
+{
+       static SDWORD  cb;
+       
+       // Bind each column of the table to a memory address for fetching data
+       int i;
+       for (i = 0; i < noCols; i++)
+       {
+               if (SQLBindCol(cursor, i+1, colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj,
+                                                       colDefs[i].SzDataObj, &cb) != SQL_SUCCESS)
+                       return(pDb->DispAllErrors(henv, hdbc, cursor));
+       }
+
+       // Completed successfully
+       return(TRUE);
+
+}  // wxTable::bindCols()
+
+/********** wxTable::getRec() **********/
+bool wxTable::getRec(UWORD fetchType)
+{
+       RETCODE retcode;
+
+       if (!pDb->FwdOnlyCursors())
+       {
+               // Fetch the NEXT, PREV, FIRST or LAST record, depending on fetchType
+               UDWORD  cRowsFetched;
+               UWORD   rowStatus;
+
+               retcode = SQLExtendedFetch(hstmt, fetchType, 0, &cRowsFetched, &rowStatus);
+               if (retcode  != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+                       if (retcode == SQL_NO_DATA_FOUND)
+                               return(FALSE);
+                       else
+                               return(pDb->DispAllErrors(henv, hdbc, hstmt));
+       }
+       else
+       {
+               // Fetch the next record from the record set
+               retcode = SQLFetch(hstmt);
+               if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+               {
+                       if (retcode == SQL_NO_DATA_FOUND)
+                               return(FALSE);
+                       else
+                               return(pDb->DispAllErrors(henv, hdbc, hstmt));
+               }
+       }
+
+       // Completed successfully
+       return(TRUE);
+
+}  // wxTable::getRec()
+
+/********** wxTable::execDelete() **********/
+bool wxTable::execDelete(const char *pSqlStmt)
+{
+       // Execute the DELETE statement
+       if (SQLExecDirect(hstmtDelete, (UCHAR FAR *) pSqlStmt, SQL_NTS) != SQL_SUCCESS)
+               return(pDb->DispAllErrors(henv, hdbc, hstmtDelete));
+
+       // Record deleted successfully
+       return(TRUE);
+
+}  // wxTable::execDelete()
+
+/********** wxTable::execUpdate() **********/
+bool wxTable::execUpdate(const char *pSqlStmt)
+{
+       // Execute the UPDATE statement
+       if (SQLExecDirect(hstmtUpdate, (UCHAR FAR *) pSqlStmt, SQL_NTS) != SQL_SUCCESS)
+               return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
+
+       // Record deleted successfully
+       return(TRUE);
+
+}  // wxTable::execUpdate()
+
+/********** wxTable::query() **********/
+bool wxTable::query(int queryType, bool forUpdate, bool distinct, char *pSqlStmt)
+{
+       char sqlStmt[DB_MAX_STATEMENT_LEN];
+
+       // Set the selectForUpdate member variable
+       if (forUpdate)
+               // The user may wish to select for update, but the DBMS may not be capable
+               selectForUpdate = CanSelectForUpdate();
+       else
+               selectForUpdate = FALSE;
+
+       // Set the SQL SELECT string
+       if (queryType != DB_SELECT_STATEMENT)                           // A select statement was not passed in,
+       {                                                                                                                               // so generate a select statement.
+               GetSelectStmt(sqlStmt, queryType, distinct);
+               pDb->WriteSqlLog(sqlStmt);
+       }
+
+       // Make sure the cursor is closed first
+       if (! CloseCursor(hstmt))
+               return(FALSE);
+
+       // Execute the SQL SELECT statement
+       int retcode;
+
+       retcode = SQLExecDirect(hstmt, (UCHAR FAR *) (queryType == DB_SELECT_STATEMENT ? pSqlStmt : sqlStmt), SQL_NTS);
+       if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+               return(pDb->DispAllErrors(henv, hdbc, hstmt));
+
+       // Completed successfully
+       return(TRUE);
+
+}  // wxTable::query()
+
+
+
 /********** wxTable::Open() **********/
 bool wxTable::Open(void)
 {
@@ -366,22 +598,22 @@ bool wxTable::Open(void)
                        if (! colDefs[i].InsertAllowed)
                                continue;
                        if (needComma)
-                               strcat(sqlStmt, ",");
-                       strcat(sqlStmt, colDefs[i].ColName);
+                               wxStrcat(sqlStmt, ",");
+                       wxStrcat(sqlStmt, colDefs[i].ColName);
                        needComma = TRUE;
                }
                needComma = FALSE;
-               strcat(sqlStmt, ") VALUES (");
+               wxStrcat(sqlStmt, ") VALUES (");
                for (i = 0; i < noCols; i++)
                {
                        if (! colDefs[i].InsertAllowed)
                                continue;
                        if (needComma)
-                               strcat(sqlStmt, ",");
-                       strcat(sqlStmt, "?");
+                               wxStrcat(sqlStmt, ",");
+                       wxStrcat(sqlStmt, "?");
                        needComma = TRUE;
                }
-               strcat(sqlStmt, ")");
+               wxStrcat(sqlStmt, ")");
 
 //             pDb->WriteSqlLog(sqlStmt);
 
@@ -428,40 +660,53 @@ bool wxTable::QueryOnKeyFields(bool forUpdate, bool distinct)
 
 }  // wxTable::QueryOnKeyFields()
 
-/********** wxTable::query() **********/
-bool wxTable::query(int queryType, bool forUpdate, bool distinct, char *pSqlStmt)
+/********** wxTable::GetPrev() **********/
+bool wxTable::GetPrev(void)
 {
-       char sqlStmt[DB_MAX_STATEMENT_LEN];
-
-       // Set the selectForUpdate member variable
-       if (forUpdate)
-               // The user may wish to select for update, but the DBMS may not be capable
-               selectForUpdate = CanSelectForUpdate();
+       if (pDb->FwdOnlyCursors())
+       {
+               wxFAIL_MSG(wxT("GetPrev()::Backward scrolling cursors are not enabled for this instance of wxTable"));
+               return FALSE;
+       }
        else
-               selectForUpdate = FALSE;
+               return(getRec(SQL_FETCH_PRIOR));
+}  // wxTable::GetPrev()
 
-       // Set the SQL SELECT string
-       if (queryType != DB_SELECT_STATEMENT)                           // A select statement was not passed in,
-       {                                                                                                                               // so generate a select statement.
-               GetSelectStmt(sqlStmt, queryType, distinct);
-               pDb->WriteSqlLog(sqlStmt);
+/********** wxTable::operator-- **********/
+bool wxTable::operator--(int)
+{
+       if (pDb->FwdOnlyCursors())
+       {
+               wxFAIL_MSG(wxT("operator--:Backward scrolling cursors are not enabled for this instance of wxTable"));
+               return FALSE;
        }
+       else
+               return(getRec(SQL_FETCH_PRIOR));
+}  // wxTable::operator--
 
-       // Make sure the cursor is closed first
-       if (! CloseCursor(hstmt))
-               return(FALSE);
-
-       // Execute the SQL SELECT statement
-       int retcode;
-
-       retcode = SQLExecDirect(hstmt, (UCHAR FAR *) (queryType == DB_SELECT_STATEMENT ? pSqlStmt : sqlStmt), SQL_NTS);
-       if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
-               return(pDb->DispAllErrors(henv, hdbc, hstmt));
-
-       // Completed successfully
-       return(TRUE);
+/********** wxTable::GetFirst() **********/
+bool wxTable::GetFirst(void)
+{
+       if (pDb->FwdOnlyCursors())
+       {
+               wxFAIL_MSG(wxT("GetFirst():Backward scrolling cursors are not enabled for this instance of wxTable"));
+               return FALSE;
+       }
+       else
+               return(getRec(SQL_FETCH_FIRST));
+}  // wxTable::GetFirst()
 
-}  // wxTable::query()
+/********** wxTable::GetLast() **********/
+bool wxTable::GetLast(void)
+{
+       if (pDb->FwdOnlyCursors())
+       {
+               wxFAIL_MSG(wxT("GetLast()::Backward scrolling cursors are not enabled for this instance of wxTable"));
+               return FALSE;
+       }
+       else 
+               return(getRec(SQL_FETCH_LAST));
+}  // wxTable::GetLast()
 
 /********** wxTable::GetSelectStmt() **********/
 void wxTable::GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct)
@@ -471,16 +716,16 @@ void wxTable::GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct)
        whereClause[0] = 0;
 
        // Build a select statement to query the database
-       strcpy(pSqlStmt, "SELECT ");
+       wxStrcpy(pSqlStmt, "SELECT ");
 
        // SELECT DISTINCT values only?
        if (distinct)
-               strcat(pSqlStmt, "DISTINCT ");
+               wxStrcat(pSqlStmt, "DISTINCT ");
 
        // Was a FROM clause specified to join tables to the base table?
        // Available for ::Query() only!!!
        bool appendFromClause = FALSE;
-       if (typeOfSelect == DB_SELECT_WHERE && from && strlen(from))
+       if (typeOfSelect == DB_SELECT_WHERE && from && wxStrlen(from))
                appendFromClause = TRUE;
 
        // Add the column list
@@ -490,12 +735,12 @@ void wxTable::GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct)
                // If joining tables, the base table column names must be qualified to avoid ambiguity
                if (appendFromClause)
                {
-                       strcat(pSqlStmt, queryTableName);
-                       strcat(pSqlStmt, ".");
+                       wxStrcat(pSqlStmt, queryTableName);
+                       wxStrcat(pSqlStmt, ".");
                }
-               strcat(pSqlStmt, colDefs[i].ColName);
+               wxStrcat(pSqlStmt, colDefs[i].ColName);
                if (i + 1 < noCols)
-                       strcat(pSqlStmt, ",");
+                       wxStrcat(pSqlStmt, ",");
        }
 
        // If the datasource supports ROWID, get this column as well.  Exception: Don't retrieve
@@ -505,17 +750,17 @@ void wxTable::GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct)
                // If joining tables, the base table column names must be qualified to avoid ambiguity
                if (appendFromClause)
                {
-                       strcat(pSqlStmt, ",");
-                       strcat(pSqlStmt, queryTableName);
-                       strcat(pSqlStmt, ".ROWID");
+                       wxStrcat(pSqlStmt, ",");
+                       wxStrcat(pSqlStmt, queryTableName);
+                       wxStrcat(pSqlStmt, ".ROWID");
                }
                else
-                       strcat(pSqlStmt, ",ROWID");
+                       wxStrcat(pSqlStmt, ",ROWID");
        }
 
        // Append the FROM tablename portion
-       strcat(pSqlStmt, " FROM ");
-       strcat(pSqlStmt, queryTableName);
+       wxStrcat(pSqlStmt, " FROM ");
+       wxStrcat(pSqlStmt, queryTableName);
 
        // Sybase uses the HOLDLOCK keyword to lock a record during query.
        // The HOLDLOCK keyword follows the table name in the from clause.
@@ -523,91 +768,55 @@ void wxTable::GetSelectStmt(char *pSqlStmt, int typeOfSelect, bool distinct)
        // NOHOLDLOCK (the default).  Note: The "FOR UPDATE" clause
        // is parsed but ignored in SYBASE Transact-SQL.
        if (selectForUpdate && (pDb->Dbms() == dbmsSYBASE_ASA || pDb->Dbms() == dbmsSYBASE_ASE))
-               strcat(pSqlStmt, " HOLDLOCK");
+               wxStrcat(pSqlStmt, " HOLDLOCK");
 
        if (appendFromClause)
-               strcat(pSqlStmt, from);
+               wxStrcat(pSqlStmt, from);
 
        // Append the WHERE clause.  Either append the where clause for the class
        // or build a where clause.  The typeOfSelect determines this.
        switch(typeOfSelect)
        {
        case DB_SELECT_WHERE:
-               if (where && strlen(where))     // May not want a where clause!!!
+               if (where && wxStrlen(where))   // May not want a where clause!!!
                {
-                       strcat(pSqlStmt, " WHERE ");
-                       strcat(pSqlStmt, where);
+                       wxStrcat(pSqlStmt, " WHERE ");
+                       wxStrcat(pSqlStmt, where);
                }
                break;
        case DB_SELECT_KEYFIELDS:
                GetWhereClause(whereClause, DB_WHERE_KEYFIELDS);
-               if (strlen(whereClause))
+               if (wxStrlen(whereClause))
                {
-                       strcat(pSqlStmt, " WHERE ");
-                       strcat(pSqlStmt, whereClause);
+                       wxStrcat(pSqlStmt, " WHERE ");
+                       wxStrcat(pSqlStmt, whereClause);
                }
                break;
        case DB_SELECT_MATCHING:
                GetWhereClause(whereClause, DB_WHERE_MATCHING);
-               if (strlen(whereClause))
+               if (wxStrlen(whereClause))
                {
-                       strcat(pSqlStmt, " WHERE ");
-                       strcat(pSqlStmt, whereClause);
+                       wxStrcat(pSqlStmt, " WHERE ");
+                       wxStrcat(pSqlStmt, whereClause);
                }
                break;
        }
 
        // Append the ORDER BY clause
-       if (orderBy && strlen(orderBy))
+       if (orderBy && wxStrlen(orderBy))
        {
-               strcat(pSqlStmt, " ORDER BY ");
-               strcat(pSqlStmt, orderBy);
+               wxStrcat(pSqlStmt, " ORDER BY ");
+               wxStrcat(pSqlStmt, orderBy);
        }
 
        // SELECT FOR UPDATE if told to do so and the datasource is capable.  Sybase
        // parses the FOR UPDATE clause but ignores it.  See the comment above on the
        // HOLDLOCK for Sybase.
        if (selectForUpdate && CanSelectForUpdate())
-               strcat(pSqlStmt, " FOR UPDATE");
+               wxStrcat(pSqlStmt, " FOR UPDATE");
 
 }  // wxTable::GetSelectStmt()
 
-/********** wxTable::getRec() **********/
-bool wxTable::getRec(UWORD fetchType)
-{
-       RETCODE retcode;
-
-#if !wxODBC_FWD_ONLY_CURSORS
-
-       // Fetch the NEXT, PREV, FIRST or LAST record, depending on fetchType
-       UDWORD  cRowsFetched;
-       UWORD   rowStatus;
-
-//     if ((retcode = SQLExtendedFetch(hstmt, fetchType, 0, &cRowsFetched, &rowStatus)) != SQL_SUCCESS)
-   retcode = SQLExtendedFetch(hstmt, fetchType, 0, &cRowsFetched, &rowStatus);
-   if (retcode  != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
-               if (retcode == SQL_NO_DATA_FOUND)
-                       return(FALSE);
-               else
-                       return(pDb->DispAllErrors(henv, hdbc, hstmt));
-#else
-
-       // Fetch the next record from the record set
-       retcode = SQLFetch(hstmt);
-       if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
-       {
-               if (retcode == SQL_NO_DATA_FOUND)
-                       return(FALSE);
-               else
-                       return(pDb->DispAllErrors(henv, hdbc, hstmt));
-       }
-#endif
-
-       // Completed successfully
-       return(TRUE);
-
-}  // wxTable::getRec()
-
 /********** wxTable::GetRowNum() **********/
 UWORD wxTable::GetRowNum(void)
 {
@@ -624,151 +833,6 @@ UWORD wxTable::GetRowNum(void)
 
 }  // wxTable::GetRowNum()
 
-/********** wxTable::bindInsertParams() **********/
-bool wxTable::bindInsertParams(void)
-{
-       assert(!queryOnly);
-       if (queryOnly)
-               return(FALSE);
-
-       SWORD   fSqlType        = 0;
-       UDWORD  precision       = 0;
-       SWORD   scale           = 0;
-
-       // Bind each column (that can be inserted) of the table to a parameter marker
-       int i;
-       for (i = 0; i < noCols; i++)
-       {
-               if (! colDefs[i].InsertAllowed)
-                       continue;
-               switch(colDefs[i].DbDataType)
-               {
-               case DB_DATA_TYPE_VARCHAR:
-                       fSqlType = pDb->typeInfVarchar.FsqlType;
-                       precision = colDefs[i].SzDataObj;
-                       scale = 0;
-                       colDefs[i].CbValue = SQL_NTS;
-                       break;
-               case DB_DATA_TYPE_INTEGER:
-                       fSqlType = pDb->typeInfInteger.FsqlType;
-                       precision = pDb->typeInfInteger.Precision;
-                       scale = 0;
-                       colDefs[i].CbValue = 0;
-                       break;
-               case DB_DATA_TYPE_FLOAT:
-                       fSqlType = pDb->typeInfFloat.FsqlType;
-                       precision = pDb->typeInfFloat.Precision;
-                       scale = pDb->typeInfFloat.MaximumScale;
-                       // SQL Sybase Anywhere v5.5 returned a negative number for the
-                       // MaxScale.  This caused ODBC to kick out an error on ibscale.
-                       // I check for this here and set the scale = precision.
-                       //if (scale < 0)
-                       //      scale = (short) precision;
-                       colDefs[i].CbValue = 0;
-                       break;
-               case DB_DATA_TYPE_DATE:
-                       fSqlType = pDb->typeInfDate.FsqlType;
-                       precision = pDb->typeInfDate.Precision;
-                       scale = 0;
-                       colDefs[i].CbValue = 0;
-                       break;
-               }
-               // Null values
-               if (colDefs[i].Null)
-               {
-                       colDefs[i].CbValue = SQL_NULL_DATA;
-                       colDefs[i].Null = FALSE;
-               }
-               if (SQLBindParameter(hstmtInsert, i+1, SQL_PARAM_INPUT, colDefs[i].SqlCtype,
-                                                                       fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, 
-                                                                       precision+1,&colDefs[i].CbValue) != SQL_SUCCESS)
-                       return(pDb->DispAllErrors(henv, hdbc, hstmtInsert));
-       }
-
-       // Completed successfully
-       return(TRUE);
-
-}  // wxTable::bindInsertParams()
-
-/********** wxTable::bindUpdateParams() **********/
-bool wxTable::bindUpdateParams(void)
-{
-       assert(!queryOnly);
-       if (queryOnly)
-               return(FALSE);
-
-       SWORD   fSqlType        = 0;
-       UDWORD  precision       = 0;
-       SWORD   scale           = 0;
-       
-       // Bind each UPDATEABLE column of the table to a parameter marker
-       int i,colNo;
-       for (i = 0, colNo = 1; i < noCols; i++)
-       {
-               if (! colDefs[i].Updateable)
-                       continue;
-               switch(colDefs[i].DbDataType)
-               {
-               case DB_DATA_TYPE_VARCHAR:
-                       fSqlType = pDb->typeInfVarchar.FsqlType;
-                       precision = colDefs[i].SzDataObj;
-                       scale = 0;
-                       colDefs[i].CbValue = SQL_NTS;
-                       break;
-               case DB_DATA_TYPE_INTEGER:
-                       fSqlType = pDb->typeInfInteger.FsqlType;
-                       precision = pDb->typeInfInteger.Precision;
-                       scale = 0;
-                       colDefs[i].CbValue = 0;
-                       break;
-               case DB_DATA_TYPE_FLOAT:
-                       fSqlType = pDb->typeInfFloat.FsqlType;
-                       precision = pDb->typeInfFloat.Precision;
-                       scale = pDb->typeInfFloat.MaximumScale;
-                       // SQL Sybase Anywhere v5.5 returned a negative number for the
-                       // MaxScale.  This caused ODBC to kick out an error on ibscale.
-                       // I check for this here and set the scale = precision.
-                       //if (scale < 0)
-                       // scale = (short) precision;
-                       colDefs[i].CbValue = 0;
-                       break;
-               case DB_DATA_TYPE_DATE:
-                       fSqlType = pDb->typeInfDate.FsqlType;
-                       precision = pDb->typeInfDate.Precision;
-                       scale = 0;
-                       colDefs[i].CbValue = 0;
-                       break;
-               }
-               if (SQLBindParameter(hstmtUpdate, colNo++, SQL_PARAM_INPUT, colDefs[i].SqlCtype,
-                                                                       fSqlType, precision, scale, (UCHAR*) colDefs[i].PtrDataObj, 
-                                                                       precision+1, &colDefs[i].CbValue) != SQL_SUCCESS)
-                       return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
-       }
-
-       // Completed successfully
-       return(TRUE);
-
-}  // wxTable::bindUpdateParams()
-
-/********** wxTable::bindCols() **********/
-bool wxTable::bindCols(HSTMT cursor)
-{
-       static SDWORD  cb;
-       
-       // Bind each column of the table to a memory address for fetching data
-       int i;
-       for (i = 0; i < noCols; i++)
-       {
-               if (SQLBindCol(cursor, i+1, colDefs[i].SqlCtype, (UCHAR*) colDefs[i].PtrDataObj,
-                                                       colDefs[i].SzDataObj, &cb) != SQL_SUCCESS)
-                       return(pDb->DispAllErrors(henv, hdbc, cursor));
-       }
-
-       // Completed successfully
-       return(TRUE);
-
-}  // wxTable::bindCols()
-
 /********** wxTable::CloseCursor() **********/
 bool wxTable::CloseCursor(HSTMT cursor)
 {
@@ -834,38 +898,38 @@ bool wxTable::CreateTable(bool attemptDrop)
                        continue;
                // Comma Delimiter
                if (needComma)
-                  strcat(sqlStmt, ",");
+                  wxStrcat(sqlStmt, ",");
                // Column Name
-               strcat(sqlStmt, colDefs[i].ColName);
-               strcat(sqlStmt, " ");
+               wxStrcat(sqlStmt, colDefs[i].ColName);
+               wxStrcat(sqlStmt, " ");
                // Column Type
                switch(colDefs[i].DbDataType)
                {
                        case DB_DATA_TYPE_VARCHAR:
-                               strcat(sqlStmt, pDb->typeInfVarchar.TypeName); break;
+                               wxStrcat(sqlStmt, pDb->typeInfVarchar.TypeName); break;
                        case DB_DATA_TYPE_INTEGER:
-                               strcat(sqlStmt, pDb->typeInfInteger.TypeName); break;
+                               wxStrcat(sqlStmt, pDb->typeInfInteger.TypeName); break;
                        case DB_DATA_TYPE_FLOAT:
-                               strcat(sqlStmt, pDb->typeInfFloat.TypeName); break;
+                               wxStrcat(sqlStmt, pDb->typeInfFloat.TypeName); break;
                        case DB_DATA_TYPE_DATE:
-                               strcat(sqlStmt, pDb->typeInfDate.TypeName); break;
+                               wxStrcat(sqlStmt, pDb->typeInfDate.TypeName); break;
                }
                // For varchars, append the size of the string
                if (colDefs[i].DbDataType == DB_DATA_TYPE_VARCHAR)
                {
                        char s[10];
-                       // strcat(sqlStmt, "(");
-                       // strcat(sqlStmt, itoa(colDefs[i].SzDataObj, s, 10));
-                       // strcat(sqlStmt, ")");
+                       // wxStrcat(sqlStmt, "(");
+                       // wxStrcat(sqlStmt, itoa(colDefs[i].SzDataObj, s, 10));
+                       // wxStrcat(sqlStmt, ")");
                        sprintf(s, "(%d)", colDefs[i].SzDataObj);
-                       strcat(sqlStmt, s);
+                       wxStrcat(sqlStmt, s);
                }
+
                if (pDb->Dbms() == dbmsSYBASE_ASE || pDb->Dbms() == dbmsMY_SQL)
                {
                        if (colDefs[i].KeyField)
                        {
-                                         strcat(sqlStmt, " NOT NULL");
+                               wxStrcat(sqlStmt, " NOT NULL");
                        }
                }
                
@@ -884,14 +948,14 @@ bool wxTable::CreateTable(bool attemptDrop)
        {
                if (pDb->Dbms() != dbmsMY_SQL)
                {
-                       strcat(sqlStmt, ",CONSTRAINT ");
-                       strcat(sqlStmt, tableName);
-                       strcat(sqlStmt, "_PIDX PRIMARY KEY (");
+                       wxStrcat(sqlStmt, ",CONSTRAINT ");
+                       wxStrcat(sqlStmt, tableName);
+                       wxStrcat(sqlStmt, "_PIDX PRIMARY KEY (");
                }
                else
                {
                        /* MySQL goes out on this one. We also declare the relevant key NON NULL above */
-                       strcat(sqlStmt, ", PRIMARY KEY (");
+                       wxStrcat(sqlStmt, ", PRIMARY KEY (");
                }
 
                // List column name(s) of column(s) comprising the primary key
@@ -900,14 +964,14 @@ bool wxTable::CreateTable(bool attemptDrop)
                        if (colDefs[i].KeyField)
                        {
                                if (j++) // Multi part key, comma separate names
-                                       strcat(sqlStmt, ",");
-                               strcat(sqlStmt, colDefs[i].ColName);
+                                       wxStrcat(sqlStmt, ",");
+                               wxStrcat(sqlStmt, colDefs[i].ColName);
                        }
                }
-          strcat(sqlStmt, ")");
+          wxStrcat(sqlStmt, ")");
        }
        // Append the closing parentheses for the create table statement
-   strcat(sqlStmt, ")");
+   wxStrcat(sqlStmt, ")");
 
        pDb->WriteSqlLog(sqlStmt);
 
@@ -983,7 +1047,7 @@ bool wxTable::DropTable()
 }  // wxTable::DropTable()
 
 /********** wxTable::CreateIndex() **********/
-bool wxTable::CreateIndex(char * idxName, bool unique, int noIdxCols, CidxDef *pIdxDefs, bool attemptDrop)
+bool wxTable::CreateIndex(const char * idxName, bool unique, int noIdxCols, CidxDef *pIdxDefs, bool attemptDrop)
 {
        char sqlStmt[DB_MAX_STATEMENT_LEN];
 
@@ -992,36 +1056,36 @@ bool wxTable::CreateIndex(char * idxName, bool unique, int noIdxCols, CidxDef *p
                return (FALSE);
 
        // Build a CREATE INDEX statement
-       strcpy(sqlStmt, "CREATE ");
+       wxStrcpy(sqlStmt, "CREATE ");
        if (unique)
-               strcat(sqlStmt, "UNIQUE ");
+               wxStrcat(sqlStmt, "UNIQUE ");
 
-       strcat(sqlStmt, "INDEX ");
-       strcat(sqlStmt, idxName);
-       strcat(sqlStmt, " ON ");
-       strcat(sqlStmt, tableName);
-       strcat(sqlStmt, " (");
+       wxStrcat(sqlStmt, "INDEX ");
+       wxStrcat(sqlStmt, idxName);
+       wxStrcat(sqlStmt, " ON ");
+       wxStrcat(sqlStmt, tableName);
+       wxStrcat(sqlStmt, " (");
 
        // Append list of columns making up index
        int i;
        for (i = 0; i < noIdxCols; i++)
        {
-               strcat(sqlStmt, pIdxDefs[i].ColName);
+               wxStrcat(sqlStmt, pIdxDefs[i].ColName);
       /* Postgres doesn't cope with ASC */
                if (pDb->Dbms() != dbmsPOSTGRES)
                {
                        if (pIdxDefs[i].Ascending)
-                               strcat(sqlStmt, " ASC");
+                               wxStrcat(sqlStmt, " ASC");
                        else
-                               strcat(sqlStmt, " DESC");
+                               wxStrcat(sqlStmt, " DESC");
                }
 
                if ((i + 1) < noIdxCols)
-                       strcat(sqlStmt, ",");
+                       wxStrcat(sqlStmt, ",");
        }
        
        // Append closing parentheses
-       strcat(sqlStmt, ")");
+       wxStrcat(sqlStmt, ")");
 
        pDb->WriteSqlLog(sqlStmt);
 
@@ -1050,7 +1114,7 @@ bool wxTable::CreateIndex(char * idxName, bool unique, int noIdxCols, CidxDef *p
 }  // wxTable::CreateIndex()
 
 /********** wxTable::DropIndex() **********/
-bool wxTable::DropIndex(char * idxName)
+bool wxTable::DropIndex(const char * idxName)
 {
        // NOTE: This function returns TRUE if the Index does not exist, but
        //       only for identified databases.  Code will need to be added
@@ -1133,19 +1197,6 @@ int wxTable::Insert(void)
 
 }  // wxTable::Insert()
 
-/********** wxTable::Update(pSqlStmt) **********/
-bool wxTable::Update(char *pSqlStmt)
-{
-       assert(!queryOnly);
-       if (queryOnly)
-               return(FALSE);
-
-       pDb->WriteSqlLog(pSqlStmt);
-
-       return(execUpdate(pSqlStmt));
-
-}  // wxTable::Update(pSqlStmt)
-
 /********** wxTable::Update() **********/
 bool wxTable::Update(void)
 {
@@ -1169,8 +1220,21 @@ bool wxTable::Update(void)
 
 }  // wxTable::Update()
 
+/********** wxTable::Update(pSqlStmt) **********/
+bool wxTable::Update(const char *pSqlStmt)
+{
+       assert(!queryOnly);
+       if (queryOnly)
+               return(FALSE);
+
+       pDb->WriteSqlLog(pSqlStmt);
+
+       return(execUpdate(pSqlStmt));
+
+}  // wxTable::Update(pSqlStmt)
+
 /********** wxTable::UpdateWhere() **********/
-bool wxTable::UpdateWhere(char *pWhereClause)
+bool wxTable::UpdateWhere(const char *pWhereClause)
 {
        assert(!queryOnly);
        if (queryOnly)
@@ -1212,7 +1276,7 @@ bool wxTable::Delete(void)
 }  // wxTable::Delete()
 
 /********** wxTable::DeleteWhere() **********/
-bool wxTable::DeleteWhere(char *pWhereClause)
+bool wxTable::DeleteWhere(const char *pWhereClause)
 {
        assert(!queryOnly);
        if (queryOnly)
@@ -1249,32 +1313,8 @@ bool wxTable::DeleteMatching(void)
 
 }  // wxTable::DeleteMatching()
 
-/********** wxTable::execDelete() **********/
-bool wxTable::execDelete(char *pSqlStmt)
-{
-       // Execute the DELETE statement
-       if (SQLExecDirect(hstmtDelete, (UCHAR FAR *) pSqlStmt, SQL_NTS) != SQL_SUCCESS)
-               return(pDb->DispAllErrors(henv, hdbc, hstmtDelete));
-
-       // Record deleted successfully
-       return(TRUE);
-
-}  // wxTable::execDelete()
-
-/********** wxTable::execUpdate() **********/
-bool wxTable::execUpdate(char *pSqlStmt)
-{
-       // Execute the UPDATE statement
-       if (SQLExecDirect(hstmtUpdate, (UCHAR FAR *) pSqlStmt, SQL_NTS) != SQL_SUCCESS)
-               return(pDb->DispAllErrors(henv, hdbc, hstmtUpdate));
-
-       // Record deleted successfully
-       return(TRUE);
-
-}  // wxTable::execUpdate()
-
 /********** wxTable::GetUpdateStmt() **********/
-void wxTable::GetUpdateStmt(char *pSqlStmt, int typeOfUpd, char *pWhereClause)
+void wxTable::GetUpdateStmt(char *pSqlStmt, int typeOfUpd, const char *pWhereClause)
 {
        assert(!queryOnly);
        if (queryOnly)
@@ -1294,16 +1334,16 @@ void wxTable::GetUpdateStmt(char *pSqlStmt, int typeOfUpd, char *pWhereClause)
                if (colDefs[i].Updateable)
                {
                        if (! firstColumn)
-                               strcat(pSqlStmt, ",");
+                               wxStrcat(pSqlStmt, ",");
                        else
                                firstColumn = FALSE;
-                       strcat(pSqlStmt, colDefs[i].ColName);
-                       strcat(pSqlStmt, " = ?");
+                       wxStrcat(pSqlStmt, colDefs[i].ColName);
+                       wxStrcat(pSqlStmt, " = ?");
                }
        }
 
        // Append the WHERE clause to the SQL UPDATE statement
-       strcat(pSqlStmt, " WHERE ");
+       wxStrcat(pSqlStmt, " WHERE ");
        switch(typeOfUpd)
        {
        case DB_UPD_KEYFIELDS:
@@ -1320,26 +1360,25 @@ void wxTable::GetUpdateStmt(char *pSqlStmt, int typeOfUpd, char *pWhereClause)
                        // based on the key fields.
                        if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, ROWID_LEN, &cb) == SQL_SUCCESS)
                        {
-                               strcat(pSqlStmt, "ROWID = '");
-                               strcat(pSqlStmt, rowid);
-                               strcat(pSqlStmt, "'");
+                               wxStrcat(pSqlStmt, "ROWID = '");
+                               wxStrcat(pSqlStmt, rowid);
+                               wxStrcat(pSqlStmt, "'");
                                break;
                        }
                }
                // Unable to delete by ROWID, so build a WHERE
                // clause based on the keyfields.
                GetWhereClause(whereClause, DB_WHERE_KEYFIELDS);
-               strcat(pSqlStmt, whereClause);
+               wxStrcat(pSqlStmt, whereClause);
                break;
        case DB_UPD_WHERE:
-               strcat(pSqlStmt, pWhereClause);
+               wxStrcat(pSqlStmt, pWhereClause);
                break;
        }
-
 }  // GetUpdateStmt()
 
 /********** wxTable::GetDeleteStmt() **********/
-void wxTable::GetDeleteStmt(char *pSqlStmt, int typeOfDel, char *pWhereClause)
+void wxTable::GetDeleteStmt(char *pSqlStmt, int typeOfDel, const char *pWhereClause)
 {
        assert(!queryOnly);
        if (queryOnly)
@@ -1351,7 +1390,7 @@ void wxTable::GetDeleteStmt(char *pSqlStmt, int typeOfDel, char *pWhereClause)
 
        // Handle the case of DeleteWhere() and the where clause is blank.  It should
        // delete all records from the database in this case.
-       if (typeOfDel == DB_DEL_WHERE && (pWhereClause == 0 || strlen(pWhereClause) == 0))
+       if (typeOfDel == DB_DEL_WHERE && (pWhereClause == 0 || wxStrlen(pWhereClause) == 0))
        {
                sprintf(pSqlStmt, "DELETE FROM %s", tableName);
                return;
@@ -1376,23 +1415,23 @@ void wxTable::GetDeleteStmt(char *pSqlStmt, int typeOfDel, char *pWhereClause)
                        // based on the key fields.
                        if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, ROWID_LEN, &cb) == SQL_SUCCESS)
                        {
-                               strcat(pSqlStmt, "ROWID = '");
-                               strcat(pSqlStmt, rowid);
-                               strcat(pSqlStmt, "'");
+                               wxStrcat(pSqlStmt, "ROWID = '");
+                               wxStrcat(pSqlStmt, rowid);
+                               wxStrcat(pSqlStmt, "'");
                                break;
                        }
                }
                // Unable to delete by ROWID, so build a WHERE
                // clause based on the keyfields.
                GetWhereClause(whereClause, DB_WHERE_KEYFIELDS);
-               strcat(pSqlStmt, whereClause);
+               wxStrcat(pSqlStmt, whereClause);
                break;
        case DB_DEL_WHERE:
-               strcat(pSqlStmt, pWhereClause);
+               wxStrcat(pSqlStmt, pWhereClause);
                break;
        case DB_DEL_MATCHING:
                GetWhereClause(whereClause, DB_WHERE_MATCHING);
-               strcat(pSqlStmt, whereClause);
+               wxStrcat(pSqlStmt, whereClause);
                break;
        }
 
@@ -1404,7 +1443,7 @@ void wxTable::GetDeleteStmt(char *pSqlStmt, int typeOfDel, char *pWhereClause)
  *       They are not included as part of the where clause.
  */
 
-void wxTable::GetWhereClause(char *pWhereClause, int typeOfWhere, char *qualTableName)
+void wxTable::GetWhereClause(char *pWhereClause, int typeOfWhere, const char *qualTableName)
 {
        bool moreThanOneColumn = FALSE;
        char colValue[255];
@@ -1422,17 +1461,17 @@ void wxTable::GetWhereClause(char *pWhereClause, int typeOfWhere, char *qualTabl
                                continue;
                        // If there is more than 1 column, join them with the keyword "AND"
                        if (moreThanOneColumn)
-                               strcat(pWhereClause, " AND ");
+                               wxStrcat(pWhereClause, " AND ");
                        else
                                moreThanOneColumn = TRUE;
                        // Concatenate where phrase for the column
-                       if (qualTableName && strlen(qualTableName))
+                       if (qualTableName && wxStrlen(qualTableName))
                        {
-                               strcat(pWhereClause, qualTableName);
-                               strcat(pWhereClause, ".");
+                               wxStrcat(pWhereClause, qualTableName);
+                               wxStrcat(pWhereClause, ".");
                        }
-                       strcat(pWhereClause, colDefs[i].ColName);
-                       strcat(pWhereClause, " = ");
+                       wxStrcat(pWhereClause, colDefs[i].ColName);
+                       wxStrcat(pWhereClause, " = ");
                        switch(colDefs[i].SqlCtype)
                        {
                        case SQL_C_CHAR:
@@ -1457,7 +1496,7 @@ void wxTable::GetWhereClause(char *pWhereClause, int typeOfWhere, char *qualTabl
                                sprintf(colValue, "%.6f", *((SDOUBLE *) colDefs[i].PtrDataObj));
                                break;
                        }
-                       strcat(pWhereClause, colValue);
+                       wxStrcat(pWhereClause, colValue);
                }
        }
 
@@ -1597,20 +1636,20 @@ bool wxTable::SetQueryTimeout(UDWORD nSeconds)
 }  // wxTable::SetQueryTimeout()
 
 /********** wxTable::SetColDefs() **********/
-void wxTable::SetColDefs (int index, char *fieldName, int dataType, void *pData,
+void wxTable::SetColDefs (int index, const char *fieldName, int dataType, void *pData,
                                                                 int cType, int size, bool keyField, bool upd,
                                                                 bool insAllow, bool derivedCol)
 {
        if (!colDefs)  // May happen if the database connection fails
                return;
 
-       if (strlen(fieldName) > (unsigned int) DB_MAX_COLUMN_NAME_LEN)
+       if (wxStrlen(fieldName) > (unsigned int) DB_MAX_COLUMN_NAME_LEN)
        {
-               strncpy (colDefs[index].ColName, fieldName, DB_MAX_COLUMN_NAME_LEN);
+               wxStrncpy (colDefs[index].ColName, fieldName, DB_MAX_COLUMN_NAME_LEN);
                colDefs[index].ColName[DB_MAX_COLUMN_NAME_LEN] = 0;
        }
        else
-               strcpy(colDefs[index].ColName, fieldName);
+               wxStrcpy(colDefs[index].ColName, fieldName);
 
        colDefs[index].DbDataType               = dataType;
        colDefs[index].PtrDataObj               = pData;
@@ -1644,25 +1683,27 @@ void wxTable::SetCursor(HSTMT *hstmtActivate)
 
 }  // wxTable::SetCursor()
 
-/********** wxTable::Count() **********/
-ULONG wxTable::Count(void)
+/********** wxTable::Count(const char *) **********/
+ULONG wxTable::Count(const char *args)
 {
        ULONG l;
        char sqlStmt[DB_MAX_STATEMENT_LEN];
        SDWORD cb;
 
        // Build a "SELECT COUNT(*) FROM queryTableName [WHERE whereClause]" SQL Statement
-       strcpy(sqlStmt, "SELECT COUNT(*) FROM ");
-       strcat(sqlStmt, queryTableName);
+       wxStrcpy(sqlStmt, "SELECT COUNT(");
+       wxStrcat(sqlStmt, args);
+       wxStrcat(sqlStmt, ") FROM ");
+       wxStrcat(sqlStmt, queryTableName);
 
-       if (from && strlen(from))
-               strcat(sqlStmt, from);
+       if (from && wxStrlen(from))
+               wxStrcat(sqlStmt, from);
 
        // Add the where clause if one is provided
-       if (where && strlen(where))
+       if (where && wxStrlen(where))
        {
-               strcat(sqlStmt, " WHERE ");
-               strcat(sqlStmt, where);
+               wxStrcat(sqlStmt, " WHERE ");
+               wxStrcat(sqlStmt, where);
        }
 
        pDb->WriteSqlLog(sqlStmt);
@@ -1722,7 +1763,7 @@ bool wxTable::Refresh(void)
        // Build a where clause to refetch the record with.  Try and use the
        // ROWID if it's available, ow use the key fields.
        char whereClause[DB_MAX_WHERE_CLAUSE_LEN+1];
-       strcpy(whereClause, "");
+       wxStrcpy(whereClause, "");
        if (CanUpdByROWID())
        {
                SDWORD cb;
@@ -1733,15 +1774,15 @@ bool wxTable::Refresh(void)
                // based on the key fields.
                if (SQLGetData(hstmt, noCols+1, SQL_C_CHAR, (UCHAR*) rowid, ROWID_LEN, &cb) == SQL_SUCCESS)
                {
-                       strcat(whereClause, queryTableName);
-                       strcat(whereClause, ".ROWID = '");
-                       strcat(whereClause, rowid);
-                       strcat(whereClause, "'");
+                       wxStrcat(whereClause, queryTableName);
+                       wxStrcat(whereClause, ".ROWID = '");
+                       wxStrcat(whereClause, rowid);
+                       wxStrcat(whereClause, "'");
                }
        }
 
        // If unable to use the ROWID, build a where clause from the keyfields
-       if (strlen(whereClause) == 0)
+       if (wxStrlen(whereClause) == 0)
                GetWhereClause(whereClause, DB_WHERE_KEYFIELDS, queryTableName);
 
        // Requery the record
@@ -1779,7 +1820,7 @@ bool wxTable::SetNull(int colNo)
 }  // wxTable::SetNull(UINT colNo)
 
 /********** wxTable::SetNull(char *colName) **********/
-bool wxTable::SetNull(char *colName)
+bool wxTable::SetNull(const char *colName)
 {
        int i;
        for (i = 0; i < noCols; i++)