- SWORD fSqlType;
- UDWORD precision;
- SWORD scale;
-
- // Bind each UPDATEABLE column of the table to a parameter marker
- for (int 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, 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)
+ char whereClause[DB_MAX_WHERE_CLAUSE_LEN];
+
+ whereClause[0] = 0;
+
+ // Build a select statement to query the database
+ wxStrcpy(pSqlStmt, "SELECT ");
+
+ // SELECT DISTINCT values only?
+ if (distinct)
+ wxStrcat(pSqlStmt, "DISTINCT ");
+
+ // Was a FROM clause specified to join tables to the base table?
+ // Available for ::Query() only!!!
+ bool appendFromClause = FALSE;
+#if wxODBC_BACKWARD_COMPATABILITY
+ if (typeOfSelect == DB_SELECT_WHERE && from && wxStrlen(from))
+ appendFromClause = TRUE;
+#else
+ if (typeOfSelect == DB_SELECT_WHERE && from.Length())
+ appendFromClause = TRUE;
+#endif
+
+ // Add the column list
+ int i;
+ for (i = 0; i < noCols; i++)
+ {
+ // If joining tables, the base table column names must be qualified to avoid ambiguity
+ if (appendFromClause)
+ {
+ wxStrcat(pSqlStmt, queryTableName);
+ wxStrcat(pSqlStmt, ".");
+ }
+ wxStrcat(pSqlStmt, colDefs[i].ColName);
+ if (i + 1 < noCols)
+ wxStrcat(pSqlStmt, ",");
+ }
+
+ // If the datasource supports ROWID, get this column as well. Exception: Don't retrieve
+ // the ROWID if querying distinct records. The rowid will always be unique.
+ if (!distinct && CanUpdByROWID())
+ {
+ // If joining tables, the base table column names must be qualified to avoid ambiguity
+ if (appendFromClause)
+ {
+ wxStrcat(pSqlStmt, ",");
+ wxStrcat(pSqlStmt, queryTableName);
+ wxStrcat(pSqlStmt, ".ROWID");
+ }
+ else
+ wxStrcat(pSqlStmt, ",ROWID");
+ }
+
+ // Append the FROM tablename portion
+ 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.
+ // Each table in the from clause must specify HOLDLOCK or
+ // 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))
+ wxStrcat(pSqlStmt, " HOLDLOCK");
+
+ if (appendFromClause)
+ 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 wxODBC_BACKWARD_COMPATABILITY
+ if (where && wxStrlen(where)) // May not want a where clause!!!
+#else
+ if (where.Length()) // May not want a where clause!!!
+#endif
+ {
+ wxStrcat(pSqlStmt, " WHERE ");
+ wxStrcat(pSqlStmt, where);
+ }
+ break;
+ case DB_SELECT_KEYFIELDS:
+ BuildWhereClause(whereClause, DB_WHERE_KEYFIELDS);
+ if (wxStrlen(whereClause))
+ {
+ wxStrcat(pSqlStmt, " WHERE ");
+ wxStrcat(pSqlStmt, whereClause);
+ }
+ break;
+ case DB_SELECT_MATCHING:
+ BuildWhereClause(whereClause, DB_WHERE_MATCHING);
+ if (wxStrlen(whereClause))
+ {
+ wxStrcat(pSqlStmt, " WHERE ");
+ wxStrcat(pSqlStmt, whereClause);
+ }
+ break;
+ }
+
+ // Append the ORDER BY clause
+#if wxODBC_BACKWARD_COMPATABILITY
+ if (orderBy && wxStrlen(orderBy))
+#else
+ if (orderBy.Length())
+#endif
+ {
+ 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())
+ wxStrcat(pSqlStmt, " FOR UPDATE");
+
+} // wxDbTable::BuildSelectStmt()
+
+
+/********** wxDbTable::GetRowNum() **********/
+UWORD wxDbTable::GetRowNum(void)