Qt 4.8
Public Functions | Protected Functions | Properties | List of all members
QODBCResult Class Reference

#include <qsql_odbc.h>

Inheritance diagram for QODBCResult:
QSqlResult

Public Functions

bool exec ()
 Executes the query, returning true if successful; otherwise returns false. More...
 
QVariant handle () const
 Returns the low-level database handle for this result set wrapped in a QVariant or an invalid QVariant if there is no handle. More...
 
bool prepare (const QString &query)
 Prepares the given query for execution; the query will normally use placeholders so that it can be executed repeatedly. More...
 
 QODBCResult (const QODBCDriver *db, QODBCDriverPrivate *p)
 
virtual void setForwardOnly (bool forward)
 Sets forward only mode to forward. More...
 
virtual ~QODBCResult ()
 
- Public Functions inherited from QSqlResult
virtual ~QSqlResult ()
 Destroys the object and frees any allocated resources. More...
 

Protected Functions

QVariant data (int field)
 Returns the data for field index in the current row as a QVariant. More...
 
bool fetch (int i)
 Positions the result to an arbitrary (zero-based) row index. More...
 
bool fetchFirst ()
 Positions the result to the first record (row 0) in the result. More...
 
bool fetchLast ()
 Positions the result to the last record (last row) in the result. More...
 
bool fetchNext ()
 Positions the result to the next available record (row) in the result. More...
 
bool fetchPrevious ()
 Positions the result to the previous record (row) in the result. More...
 
bool isNull (int field)
 Returns true if the field at position index in the current row is null; otherwise returns false. More...
 
bool nextResult ()
 
int numRowsAffected ()
 Returns the number of rows affected by the last query executed, or -1 if it cannot be determined or if the query is a SELECT statement. More...
 
QSqlRecord record () const
 Returns the current record if the query is active; otherwise returns an empty QSqlRecord. More...
 
bool reset (const QString &query)
 Sets the result to use the SQL statement query for subsequent data retrieval. More...
 
int size ()
 Returns the size of the SELECT result, or -1 if it cannot be determined or if the query is not a SELECT statement. More...
 
void virtual_hook (int id, void *data)
 
- Protected Functions inherited from QSqlResult
void addBindValue (const QVariant &val, QSql::ParamType type)
 Binds the value val of parameter type paramType to the next available position in the current record (row). More...
 
int at () const
 Returns the current (zero-based) row position of the result. More...
 
BindingSyntax bindingSyntax () const
 Returns the binding syntax used by prepared queries. More...
 
virtual void bindValue (int pos, const QVariant &val, QSql::ParamType type)
 Binds the value val of parameter type paramType to position index in the current record (row). More...
 
virtual void bindValue (const QString &placeholder, const QVariant &val, QSql::ParamType type)
 Binds the value val of parameter type paramType to the placeholder name in the current record (row). More...
 
QSql::ParamType bindValueType (const QString &placeholder) const
 Returns the parameter type for the value bound with the given placeholder name. More...
 
QSql::ParamType bindValueType (int pos) const
 Returns the parameter type for the value bound at position index. More...
 
QVariant boundValue (const QString &placeholder) const
 Returns the value bound by the given placeholder name in the current record (row). More...
 
QVariant boundValue (int pos) const
 Returns the value bound at position index in the current record (row). More...
 
int boundValueCount () const
 Returns the number of bound values in the result. More...
 
QString boundValueName (int pos) const
 Returns the name of the bound value at position index in the current record (row). More...
 
QVector< QVariant > & boundValues () const
 Returns a vector of the result's bound values for the current record (row). More...
 
void clear ()
 Clears the entire result set and releases any associated resources. More...
 
void detachFromResultSet ()
 
const QSqlDriverdriver () const
 Returns the driver associated with the result. More...
 
bool execBatch (bool arrayBind=false)
 Executes a prepared query in batch mode if the driver supports it, otherwise emulates a batch execution using bindValue() and exec(). More...
 
QString executedQuery () const
 Returns the query that was actually executed. More...
 
bool hasOutValues () const
 Returns true if at least one of the query's bound values is a QSql::Out or a QSql::InOut; otherwise returns false. More...
 
bool isActive () const
 Returns true if the result has records to be retrieved; otherwise returns false. More...
 
bool isForwardOnly () const
 Returns true if you can only scroll forward through the result set; otherwise returns false. More...
 
bool isSelect () const
 Returns true if the current result is from a SELECT statement; otherwise returns false. More...
 
bool isValid () const
 Returns true if the result is positioned on a valid record (that is, the result is not positioned before the first or after the last record); otherwise returns false. More...
 
QSqlError lastError () const
 Returns the last error associated with the result. More...
 
virtual QVariant lastInsertId () const
 Returns the object ID of the most recent inserted row if the database supports it. More...
 
QString lastQuery () const
 Returns the current SQL query text, or an empty string if there isn't one. More...
 
bool nextResult ()
 
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy () const
 
 QSqlResult (const QSqlDriver *db)
 Creates a QSqlResult using database driver db. More...
 
virtual bool savePrepare (const QString &sqlquery)
 Prepares the given query, using the underlying database functionality where possible. More...
 
virtual void setActive (bool a)
 This function is provided for derived classes to set the internal active state to active. More...
 
virtual void setAt (int at)
 This function is provided for derived classes to set the internal (zero-based) row position to index. More...
 
virtual void setLastError (const QSqlError &e)
 This function is provided for derived classes to set the last error to error. More...
 
void setNumericalPrecisionPolicy (QSql::NumericalPrecisionPolicy policy)
 
virtual void setQuery (const QString &query)
 Sets the current query for the result to query. More...
 
virtual void setSelect (bool s)
 This function is provided for derived classes to indicate whether or not the current statement is a SQL SELECT statement. More...
 

Properties

QODBCPrivated
 

Additional Inherited Members

- Protected Types inherited from QSqlResult
enum  BindingSyntax { PositionalBinding, NamedBinding }
 This enum type specifies the different syntaxes for specifying placeholders in prepared queries. More...
 
enum  VirtualHookOperation { BatchOperation, DetachFromResultSet, SetNumericalPrecision, NextResult }
 

Detailed Description

Definition at line 82 of file qsql_odbc.h.

Constructors and Destructors

◆ QODBCResult()

QODBCResult::QODBCResult ( const QODBCDriver db,
QODBCDriverPrivate p 
)

Definition at line 889 of file qsql_odbc.cpp.

890 : QSqlResult(db)
891 {
892  d = new QODBCPrivate(p);
893 }
QODBCPrivate * d
Definition: qsql_odbc.h:110
QSqlResult(const QSqlDriver *db)
Creates a QSqlResult using database driver db.
Definition: qsqlresult.cpp:257

◆ ~QODBCResult()

QODBCResult::~QODBCResult ( )
virtual

Definition at line 895 of file qsql_odbc.cpp.

896 {
897  if (d->hStmt && d->isStmtHandleValid(driver()) && driver()->isOpen()) {
898  SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
899  if (r != SQL_SUCCESS)
900  qSqlWarning(QLatin1String("QODBCDriver: Unable to free statement handle ")
901  + QString::number(r), d);
902  }
903 
904  delete d;
905 }
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
const QSqlDriver * driver() const
Returns the driver associated with the result.
Definition: qsqlresult.cpp:389
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
QODBCPrivate * d
Definition: qsql_odbc.h:110
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
virtual bool isOpen() const
Returns true if the database connection is open; otherwise returns false.
Definition: qsqldriver.cpp:182
static void qSqlWarning(const QString &message, const QODBCPrivate *odbc)
Definition: qsql_odbc.cpp:267
bool isStmtHandleValid(const QSqlDriver *driver)
Definition: qsql_odbc.cpp:190

Functions

◆ data()

QVariant QODBCResult::data ( int  index)
protectedvirtual

Returns the data for field index in the current row as a QVariant.

This function is only called if the result is in an active state and is positioned on a valid record and index is non-negative. Derived classes must reimplement this function and return the value of field index, or QVariant() if it cannot be determined.

Implements QSqlResult.

Definition at line 1128 of file qsql_odbc.cpp.

Referenced by isNull(), prepare(), reset(), and virtual_hook().

1129 {
1130  if (field >= d->rInf.count() || field < 0) {
1131  qWarning() << "QODBCResult::data: column" << field << "out of range";
1132  return QVariant();
1133  }
1134  if (field < d->fieldCacheIdx)
1135  return d->fieldCache.at(field);
1136 
1137  SQLRETURN r(0);
1138  SQLLEN lengthIndicator = 0;
1139 
1140  for (int i = d->fieldCacheIdx; i <= field; ++i) {
1141  // some servers do not support fetching column n after we already
1142  // fetched column n+1, so cache all previous columns here
1143  const QSqlField info = d->rInf.field(i);
1144  switch (info.type()) {
1145  case QVariant::LongLong:
1146  d->fieldCache[i] = qGetBigIntData(d->hStmt, i);
1147  break;
1148  case QVariant::ULongLong:
1149  d->fieldCache[i] = qGetBigIntData(d->hStmt, i, false);
1150  break;
1151  case QVariant::Int:
1152  d->fieldCache[i] = qGetIntData(d->hStmt, i);
1153  break;
1154  case QVariant::UInt:
1155  d->fieldCache[i] = qGetIntData(d->hStmt, i, false);
1156  break;
1157  case QVariant::Date:
1158  DATE_STRUCT dbuf;
1159  r = SQLGetData(d->hStmt,
1160  i + 1,
1161  SQL_C_DATE,
1162  (SQLPOINTER)&dbuf,
1163  0,
1164  &lengthIndicator);
1165  if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (lengthIndicator != SQL_NULL_DATA))
1166  d->fieldCache[i] = QVariant(QDate(dbuf.year, dbuf.month, dbuf.day));
1167  else
1169  break;
1170  case QVariant::Time:
1171  TIME_STRUCT tbuf;
1172  r = SQLGetData(d->hStmt,
1173  i + 1,
1174  SQL_C_TIME,
1175  (SQLPOINTER)&tbuf,
1176  0,
1177  &lengthIndicator);
1178  if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (lengthIndicator != SQL_NULL_DATA))
1179  d->fieldCache[i] = QVariant(QTime(tbuf.hour, tbuf.minute, tbuf.second));
1180  else
1182  break;
1183  case QVariant::DateTime:
1184  TIMESTAMP_STRUCT dtbuf;
1185  r = SQLGetData(d->hStmt,
1186  i + 1,
1187  SQL_C_TIMESTAMP,
1188  (SQLPOINTER)&dtbuf,
1189  0,
1190  &lengthIndicator);
1191  if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (lengthIndicator != SQL_NULL_DATA))
1192  d->fieldCache[i] = QVariant(QDateTime(QDate(dtbuf.year, dtbuf.month, dtbuf.day),
1193  QTime(dtbuf.hour, dtbuf.minute, dtbuf.second, dtbuf.fraction / 1000000)));
1194  else
1196  break;
1197  case QVariant::ByteArray:
1198  d->fieldCache[i] = qGetBinaryData(d->hStmt, i);
1199  break;
1200  case QVariant::String:
1201  d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), d->unicode);
1202  break;
1203  case QVariant::Double:
1204  switch(numericalPrecisionPolicy()) {
1206  d->fieldCache[i] = qGetIntData(d->hStmt, i);
1207  break;
1209  d->fieldCache[i] = qGetBigIntData(d->hStmt, i);
1210  break;
1212  d->fieldCache[i] = qGetDoubleData(d->hStmt, i);
1213  break;
1214  case QSql::HighPrecision:
1215  d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), false);
1216  break;
1217  }
1218  break;
1219  default:
1220  d->fieldCache[i] = QVariant(qGetStringData(d->hStmt, i, info.length(), false));
1221  break;
1222  }
1223  d->fieldCacheIdx = field + 1;
1224  }
1225  return d->fieldCache[field];
1226 }
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
static mach_timebase_info_data_t info
QODBCPrivate * d
Definition: qsql_odbc.h:110
static QVariant qGetDoubleData(SQLHANDLE hStmt, int column)
Definition: qsql_odbc.cpp:531
The QDate class provides date functions.
Definition: qdatetime.h:55
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const
static QVariant qGetIntData(SQLHANDLE hStmt, int column, bool isSigned=true)
Definition: qsql_odbc.cpp:511
The QTime class provides clock time functions.
Definition: qdatetime.h:148
Q_CORE_EXPORT void qWarning(const char *,...)
static QVariant qGetBigIntData(SQLHANDLE hStmt, int column, bool isSigned=true)
Definition: qsql_odbc.cpp:551
QVariant::Type type() const
Returns the field&#39;s type as stored in the database.
Definition: qsqlfield.cpp:394
QSqlField field(int i) const
Returns the field at position index.
Definition: qsqlrecord.cpp:289
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
static QVariant qGetBinaryData(SQLHANDLE hStmt, int column)
Definition: qsql_odbc.cpp:454
int length() const
Returns the field&#39;s length.
Definition: qsqlfield.cpp:457
QVector< QVariant > fieldCache
Definition: qsql_odbc.cpp:179
int count() const
Returns the number of fields in the record.
Definition: qsqlrecord.cpp:573
The QDateTime class provides date and time functions.
Definition: qdatetime.h:216
static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool unicode=false)
Definition: qsql_odbc.cpp:353
QSqlRecord rInf
Definition: qsql_odbc.cpp:178
The QSqlField class manipulates the fields in SQL database tables and views.
Definition: qsqlfield.h:56

◆ exec()

bool QODBCResult::exec ( )
virtual

Executes the query, returning true if successful; otherwise returns false.

See also
prepare()

Reimplemented from QSqlResult.

Definition at line 1318 of file qsql_odbc.cpp.

1319 {
1320  setActive(false);
1322  d->rInf.clear();
1323  d->fieldCache.clear();
1324  d->fieldCacheIdx = 0;
1325 
1326  if (!d->hStmt) {
1327  qSqlWarning(QLatin1String("QODBCResult::exec: No statement handle available"), d);
1328  return false;
1329  }
1330 
1331  if (isSelect())
1332  SQLCloseCursor(d->hStmt);
1333 
1335  QVector<QByteArray> tmpStorage(values.count(), QByteArray()); // holds temporary buffers
1336  QVarLengthArray<SQLLEN, 32> indicators(values.count());
1337  memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN));
1338 
1339  // bind parameters - only positional binding allowed
1340  int i;
1341  SQLRETURN r;
1342  for (i = 0; i < values.count(); ++i) {
1343  if (bindValueType(i) & QSql::Out)
1344  values[i].detach();
1345  const QVariant &val = values.at(i);
1346  SQLLEN *ind = &indicators[i];
1347  if (val.isNull())
1348  *ind = SQL_NULL_DATA;
1349  switch (val.type()) {
1350  case QVariant::Date: {
1351  QByteArray &ba = tmpStorage[i];
1352  ba.resize(sizeof(DATE_STRUCT));
1353  DATE_STRUCT *dt = (DATE_STRUCT *)ba.constData();
1354  QDate qdt = val.toDate();
1355  dt->year = qdt.year();
1356  dt->month = qdt.month();
1357  dt->day = qdt.day();
1358  r = SQLBindParameter(d->hStmt,
1359  i + 1,
1361  SQL_C_DATE,
1362  SQL_DATE,
1363  0,
1364  0,
1365  (void *) dt,
1366  0,
1367  *ind == SQL_NULL_DATA ? ind : NULL);
1368  break; }
1369  case QVariant::Time: {
1370  QByteArray &ba = tmpStorage[i];
1371  ba.resize(sizeof(TIME_STRUCT));
1372  TIME_STRUCT *dt = (TIME_STRUCT *)ba.constData();
1373  QTime qdt = val.toTime();
1374  dt->hour = qdt.hour();
1375  dt->minute = qdt.minute();
1376  dt->second = qdt.second();
1377  r = SQLBindParameter(d->hStmt,
1378  i + 1,
1380  SQL_C_TIME,
1381  SQL_TIME,
1382  0,
1383  0,
1384  (void *) dt,
1385  0,
1386  *ind == SQL_NULL_DATA ? ind : NULL);
1387  break; }
1388  case QVariant::DateTime: {
1389  QByteArray &ba = tmpStorage[i];
1390  ba.resize(sizeof(TIMESTAMP_STRUCT));
1391  TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)ba.constData();
1392  QDateTime qdt = val.toDateTime();
1393  dt->year = qdt.date().year();
1394  dt->month = qdt.date().month();
1395  dt->day = qdt.date().day();
1396  dt->hour = qdt.time().hour();
1397  dt->minute = qdt.time().minute();
1398  dt->second = qdt.time().second();
1399 
1400  int precision = d->driverPrivate->datetime_precision - 20; // (20 includes a separating period)
1401  if (precision <= 0) {
1402  dt->fraction = 0;
1403  } else {
1404  dt->fraction = qdt.time().msec() * 1000000;
1405 
1406  // (How many leading digits do we want to keep? With SQL Server 2005, this should be 3: 123000000)
1407  int keep = (int)qPow(10.0, 9 - qMin(9, precision));
1408  dt->fraction = (dt->fraction / keep) * keep;
1409  }
1410 
1411  r = SQLBindParameter(d->hStmt,
1412  i + 1,
1414  SQL_C_TIMESTAMP,
1415  SQL_TIMESTAMP,
1416  d->driverPrivate->datetime_precision,
1417  precision,
1418  (void *) dt,
1419  0,
1420  *ind == SQL_NULL_DATA ? ind : NULL);
1421  break; }
1422  case QVariant::Int:
1423  r = SQLBindParameter(d->hStmt,
1424  i + 1,
1426  SQL_C_SLONG,
1427  SQL_INTEGER,
1428  0,
1429  0,
1430  (void *) val.constData(),
1431  0,
1432  *ind == SQL_NULL_DATA ? ind : NULL);
1433  break;
1434  case QVariant::UInt:
1435  r = SQLBindParameter(d->hStmt,
1436  i + 1,
1437  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1438  SQL_C_ULONG,
1439  SQL_NUMERIC,
1440  15,
1441  0,
1442  (void *) val.constData(),
1443  0,
1444  *ind == SQL_NULL_DATA ? ind : NULL);
1445  break;
1446  case QVariant::Double:
1447  r = SQLBindParameter(d->hStmt,
1448  i + 1,
1449  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1450  SQL_C_DOUBLE,
1451  SQL_DOUBLE,
1452  0,
1453  0,
1454  (void *) val.constData(),
1455  0,
1456  *ind == SQL_NULL_DATA ? ind : NULL);
1457  break;
1458  case QVariant::LongLong:
1459  r = SQLBindParameter(d->hStmt,
1460  i + 1,
1461  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1462  SQL_C_SBIGINT,
1463  SQL_BIGINT,
1464  0,
1465  0,
1466  (void *) val.constData(),
1467  0,
1468  *ind == SQL_NULL_DATA ? ind : NULL);
1469  break;
1470  case QVariant::ULongLong:
1471  r = SQLBindParameter(d->hStmt,
1472  i + 1,
1473  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1474  SQL_C_UBIGINT,
1475  SQL_BIGINT,
1476  0,
1477  0,
1478  (void *) val.constData(),
1479  0,
1480  *ind == SQL_NULL_DATA ? ind : NULL);
1481  break;
1482  case QVariant::ByteArray:
1483  if (*ind != SQL_NULL_DATA) {
1484  *ind = val.toByteArray().size();
1485  }
1486  r = SQLBindParameter(d->hStmt,
1487  i + 1,
1488  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1489  SQL_C_BINARY,
1490  SQL_LONGVARBINARY,
1491  val.toByteArray().size(),
1492  0,
1493  (void *) val.toByteArray().constData(),
1494  val.toByteArray().size(),
1495  ind);
1496  break;
1497  case QVariant::Bool:
1498  r = SQLBindParameter(d->hStmt,
1499  i + 1,
1500  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1501  SQL_C_BIT,
1502  SQL_BIT,
1503  0,
1504  0,
1505  (void *) val.constData(),
1506  0,
1507  *ind == SQL_NULL_DATA ? ind : NULL);
1508  break;
1509  case QVariant::String:
1510  if (d->unicode) {
1511  QByteArray &ba = tmpStorage[i];
1512  QString str = val.toString();
1513  if (*ind != SQL_NULL_DATA)
1514  *ind = str.length() * sizeof(SQLTCHAR);
1515  int strSize = str.length() * sizeof(SQLTCHAR);
1516 
1517  if (bindValueType(i) & QSql::Out) {
1519  a.reserve(str.capacity());
1520  r = SQLBindParameter(d->hStmt,
1521  i + 1,
1522  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1523  SQL_C_TCHAR,
1524  strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
1525  0, // god knows... don't change this!
1526  0,
1527  (void *)a.constData(),
1528  a.size(),
1529  ind);
1530  break;
1531  }
1532  ba = QByteArray((const char *)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR));
1533  r = SQLBindParameter(d->hStmt,
1534  i + 1,
1535  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1536  SQL_C_TCHAR,
1537  strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
1538  strSize,
1539  0,
1540  (SQLPOINTER)ba.constData(),
1541  ba.size(),
1542  ind);
1543  break;
1544  }
1545  else
1546  {
1547  QByteArray &str = tmpStorage[i];
1548  str = val.toString().toUtf8();
1549  if (*ind != SQL_NULL_DATA)
1550  *ind = str.length();
1551  int strSize = str.length();
1552 
1553  r = SQLBindParameter(d->hStmt,
1554  i + 1,
1555  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1556  SQL_C_CHAR,
1557  strSize > 254 ? SQL_LONGVARCHAR : SQL_VARCHAR,
1558  strSize,
1559  0,
1560  (void *)str.constData(),
1561  strSize,
1562  ind);
1563  break;
1564  }
1565  // fall through
1566  default: {
1567  QByteArray &ba = tmpStorage[i];
1568  if (*ind != SQL_NULL_DATA)
1569  *ind = ba.size();
1570  r = SQLBindParameter(d->hStmt,
1571  i + 1,
1572  qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],
1573  SQL_C_BINARY,
1574  SQL_VARBINARY,
1575  ba.length() + 1,
1576  0,
1577  (void *) ba.constData(),
1578  ba.length() + 1,
1579  ind);
1580  break; }
1581  }
1582  if (r != SQL_SUCCESS) {
1583  qWarning() << "QODBCResult::exec: unable to bind variable:" << qODBCWarn(d);
1585  "Unable to bind variable"), QSqlError::StatementError, d));
1586  return false;
1587  }
1588  }
1589  r = SQLExecute(d->hStmt);
1590  if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r != SQL_NO_DATA) {
1591  qWarning() << "QODBCResult::exec: Unable to execute statement:" << qODBCWarn(d);
1593  "Unable to execute statement"), QSqlError::StatementError, d));
1594  return false;
1595  }
1596 
1597  SQLULEN isScrollable = 0;
1598  r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, 0);
1599  if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
1600  QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE);
1601 
1602  SQLSMALLINT count;
1603  SQLNumResultCols(d->hStmt, &count);
1604  if (count) {
1605  setSelect(true);
1606  for (int i = 0; i < count; ++i) {
1607  d->rInf.append(qMakeFieldInfo(d, i));
1608  }
1609  d->fieldCache.resize(count);
1610  } else {
1611  setSelect(false);
1612  }
1613  setActive(true);
1614 
1615 
1616  //get out parameters
1617  if (!hasOutValues())
1618  return true;
1619 
1620  for (i = 0; i < values.count(); ++i) {
1621  switch (values.at(i).type()) {
1622  case QVariant::Date: {
1623  DATE_STRUCT ds = *((DATE_STRUCT *)tmpStorage.at(i).constData());
1624  values[i] = QVariant(QDate(ds.year, ds.month, ds.day));
1625  break; }
1626  case QVariant::Time: {
1627  TIME_STRUCT dt = *((TIME_STRUCT *)tmpStorage.at(i).constData());
1628  values[i] = QVariant(QTime(dt.hour, dt.minute, dt.second));
1629  break; }
1630  case QVariant::DateTime: {
1631  TIMESTAMP_STRUCT dt = *((TIMESTAMP_STRUCT*)
1632  tmpStorage.at(i).constData());
1633  values[i] = QVariant(QDateTime(QDate(dt.year, dt.month, dt.day),
1634  QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000)));
1635  break; }
1636  case QVariant::Bool:
1637  case QVariant::Int:
1638  case QVariant::UInt:
1639  case QVariant::Double:
1640  case QVariant::ByteArray:
1641  case QVariant::LongLong:
1642  case QVariant::ULongLong:
1643  //nothing to do
1644  break;
1645  case QVariant::String:
1646  if (d->unicode) {
1647  if (bindValueType(i) & QSql::Out) {
1648  const QByteArray &first = tmpStorage.at(i);
1650  array.append((SQLTCHAR *)first.constData(), first.size());
1651  values[i] = fromSQLTCHAR(array, first.size()/sizeof(SQLTCHAR*));
1652  }
1653  break;
1654  }
1655  // fall through
1656  default: {
1657  if (bindValueType(i) & QSql::Out)
1658  values[i] = tmpStorage.at(i);
1659  break; }
1660  }
1661  if (indicators[i] == SQL_NULL_DATA)
1662  values[i] = QVariant(values[i].type());
1663  }
1664  return true;
1665 }
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QString qODBCWarn(const QODBCPrivate *odbc, int *nativeCode=0)
Definition: qsql_odbc.cpp:254
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
int type
Definition: qmetatype.cpp:239
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
QODBCPrivate * d
Definition: qsql_odbc.h:110
bool isNull() const
Returns true if this is a NULL variant, false otherwise.
Definition: qvariant.cpp:3102
The QFlag class is a helper data type for QFlags.
Definition: qglobal.h:2289
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
static QVarLengthArray< SQLTCHAR > toSQLTCHAR(const QString &input)
Definition: qsql_odbc.cpp:93
int month() const
Returns the number corresponding to the month of this date, using the following convention: ...
Definition: qdatetime.cpp:382
QODBCDriverPrivate * driverPrivate
Definition: qsql_odbc.cpp:183
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has type() DateTime , Date , or String ; otherwise ...
Definition: qvariant.cpp:2349
int day() const
Returns the day of the month (1 to 31) of this date.
Definition: qdatetime.cpp:395
The QDate class provides date functions.
Definition: qdatetime.h:55
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
int msec() const
Returns the millisecond part (0 to 999) of the time.
Definition: qdatetime.cpp:1611
long ASN1_INTEGER_get ASN1_INTEGER * a
The QString class provides a Unicode character string.
Definition: qstring.h:83
void append(const T &t)
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
Definition: qvariant.cpp:2383
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
Definition: qsqlresult.cpp:417
The QTime class provides clock time functions.
Definition: qdatetime.h:148
virtual void setSelect(bool s)
This function is provided for derived classes to indicate whether or not the current statement is a S...
Definition: qsqlresult.cpp:367
static const SQLSMALLINT qParamType[4]
Definition: qsql_odbc.cpp:68
void clear()
Removes all the elements from the vector and releases the memory used by the vector.
Definition: qvector.h:347
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
bool hasOutValues() const
Returns true if at least one of the query&#39;s bound values is a QSql::Out or a QSql::InOut; otherwise r...
Definition: qsqlresult.cpp:916
QSql::ParamType bindValueType(const QString &placeholder) const
Returns the parameter type for the value bound with the given placeholder name.
Definition: qsqlresult.cpp:838
Q_CORE_EXPORT void qWarning(const char *,...)
int second() const
Returns the second part (0 to 59) of the time.
Definition: qdatetime.cpp:1600
static void qSqlWarning(const QString &message, const QODBCPrivate *odbc)
Definition: qsql_odbc.cpp:267
int minute() const
Returns the minute part (0 to 59) of the time.
Definition: qdatetime.cpp:1589
quint16 values[128]
virtual void setForwardOnly(bool forward)
Sets forward only mode to forward.
Definition: qsqlresult.cpp:603
qreal qPow(qreal x, qreal y)
Definition: qmath.h:244
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
int length() const
Same as size().
Definition: qbytearray.h:356
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QDate date() const
Returns the date part of the datetime.
Definition: qdatetime.cpp:2357
QVector< QVariant > fieldCache
Definition: qsql_odbc.cpp:179
QDate toDate() const
Returns the variant as a QDate if the variant has type() Date , DateTime , or String ; otherwise retu...
Definition: qvariant.cpp:2311
The QDateTime class provides date and time functions.
Definition: qdatetime.h:216
int capacity() const
Returns the maximum number of characters that can be stored in the string without forcing a reallocat...
Definition: qstring.h:727
Type type() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1901
const void * constData() const
Definition: qvariant.cpp:3065
void resize(int size)
Sets the size of the byte array to size bytes.
void append(const QSqlField &field)
Append a copy of field field to the end of the record.
Definition: qsqlrecord.cpp:312
static QSqlField qMakeFieldInfo(const SQLHANDLE hStmt, const QODBCDriverPrivate *p)
Definition: qsql_odbc.cpp:574
bool isSelect() const
Returns true if the current result is from a SELECT statement; otherwise returns false.
Definition: qsqlresult.cpp:379
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
virtual void setActive(bool a)
This function is provided for derived classes to set the internal active state to active...
Definition: qsqlresult.cpp:402
void clear()
Removes all the record&#39;s fields.
Definition: qsqlrecord.cpp:367
QSqlRecord rInf
Definition: qsql_odbc.cpp:178
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QODBCPrivate *p)
Definition: qsql_odbc.cpp:277
int year() const
Returns the year of this date.
Definition: qdatetime.cpp:353
QTime time() const
Returns the time part of the datetime.
Definition: qdatetime.cpp:2368
Definition: qsql.h:68
QTime toTime() const
Returns the variant as a QTime if the variant has type() Time , DateTime , or String ; otherwise retu...
Definition: qvariant.cpp:2330
QVector< QVariant > & boundValues() const
Returns a vector of the result&#39;s bound values for the current record (row).
Definition: qsqlresult.cpp:859
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
static QString fromSQLTCHAR(const QVarLengthArray< SQLTCHAR > &input, int size=-1)
Definition: qsql_odbc.cpp:70
int hour() const
Returns the hour part (0 to 23) of the time.
Definition: qdatetime.cpp:1578

◆ fetch()

bool QODBCResult::fetch ( int  index)
protectedvirtual

Positions the result to an arbitrary (zero-based) row index.

This function is only called if the result is in an active state. Derived classes must reimplement this function and position the result to the row index, and call setAt() with an appropriate value. Return true to indicate success, or false to signify failure.

See also
isActive(), fetchFirst(), fetchLast(), fetchNext(), fetchPrevious()

Implements QSqlResult.

Definition at line 990 of file qsql_odbc.cpp.

991 {
992  if (!driver()->isOpen())
993  return false;
994 
995  if (isForwardOnly() && i < at())
996  return false;
997  if (i == at())
998  return true;
999  d->clearValues();
1000  int actualIdx = i + 1;
1001  if (actualIdx <= 0) {
1003  return false;
1004  }
1005  SQLRETURN r;
1006  if (isForwardOnly()) {
1007  bool ok = true;
1008  while (ok && i > at())
1009  ok = fetchNext();
1010  return ok;
1011  } else {
1012  r = SQLFetchScroll(d->hStmt,
1013  SQL_FETCH_ABSOLUTE,
1014  actualIdx);
1015  }
1016  if (r != SQL_SUCCESS) {
1017  if (r != SQL_NO_DATA)
1019  "Unable to fetch"), QSqlError::ConnectionError, d));
1020  return false;
1021  }
1022  setAt(i);
1023  return true;
1024 }
const QSqlDriver * driver() const
Returns the driver associated with the result.
Definition: qsqlresult.cpp:389
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
bool fetchNext()
Positions the result to the next available record (row) in the result.
Definition: qsql_odbc.cpp:1026
QODBCPrivate * d
Definition: qsql_odbc.h:110
bool isForwardOnly() const
Returns true if you can only scroll forward through the result set; otherwise returns false...
Definition: qsqlresult.cpp:582
int at() const
Returns the current (zero-based) row position of the result.
Definition: qsqlresult.cpp:306
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
Definition: qsqlresult.cpp:417
void clearValues()
Definition: qsql_odbc.cpp:168
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QODBCPrivate *p)
Definition: qsql_odbc.cpp:277

◆ fetchFirst()

bool QODBCResult::fetchFirst ( )
protectedvirtual

Positions the result to the first record (row 0) in the result.

This function is only called if the result is in an active state. Derived classes must reimplement this function and position the result to the first record, and call setAt() with an appropriate value. Return true to indicate success, or false to signify failure.

See also
fetch(), fetchLast()

Implements QSqlResult.

Definition at line 1048 of file qsql_odbc.cpp.

1049 {
1050  if (isForwardOnly() && at() != QSql::BeforeFirstRow)
1051  return false;
1052  SQLRETURN r;
1053  d->clearValues();
1054  if (isForwardOnly()) {
1055  return fetchNext();
1056  }
1057  r = SQLFetchScroll(d->hStmt,
1058  SQL_FETCH_FIRST,
1059  0);
1060  if (r != SQL_SUCCESS) {
1061  if (r != SQL_NO_DATA)
1063  "Unable to fetch first"), QSqlError::ConnectionError, d));
1064  return false;
1065  }
1066  setAt(0);
1067  return true;
1068 }
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
bool fetchNext()
Positions the result to the next available record (row) in the result.
Definition: qsql_odbc.cpp:1026
QODBCPrivate * d
Definition: qsql_odbc.h:110
bool isForwardOnly() const
Returns true if you can only scroll forward through the result set; otherwise returns false...
Definition: qsqlresult.cpp:582
int at() const
Returns the current (zero-based) row position of the result.
Definition: qsqlresult.cpp:306
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
Definition: qsqlresult.cpp:417
void clearValues()
Definition: qsql_odbc.cpp:168
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QODBCPrivate *p)
Definition: qsql_odbc.cpp:277

◆ fetchLast()

bool QODBCResult::fetchLast ( )
protectedvirtual

Positions the result to the last record (last row) in the result.

This function is only called if the result is in an active state. Derived classes must reimplement this function and position the result to the last record, and call setAt() with an appropriate value. Return true to indicate success, or false to signify failure.

See also
fetch(), fetchFirst()

Implements QSqlResult.

Definition at line 1089 of file qsql_odbc.cpp.

1090 {
1091  SQLRETURN r;
1092  d->clearValues();
1093 
1094  if (isForwardOnly()) {
1095  // cannot seek to last row in forwardOnly mode, so we have to use brute force
1096  int i = at();
1097  if (i == QSql::AfterLastRow)
1098  return false;
1099  if (i == QSql::BeforeFirstRow)
1100  i = 0;
1101  while (fetchNext())
1102  ++i;
1103  setAt(i);
1104  return true;
1105  }
1106 
1107  r = SQLFetchScroll(d->hStmt,
1108  SQL_FETCH_LAST,
1109  0);
1110  if (r != SQL_SUCCESS) {
1111  if (r != SQL_NO_DATA)
1113  "Unable to fetch last"), QSqlError::ConnectionError, d));
1114  return false;
1115  }
1116  SQLULEN currRow = 0;
1117  r = SQLGetStmtAttr(d->hStmt,
1118  SQL_ROW_NUMBER,
1119  &currRow,
1120  SQL_IS_INTEGER,
1121  0);
1122  if (r != SQL_SUCCESS)
1123  return false;
1124  setAt(currRow-1);
1125  return true;
1126 }
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
bool fetchNext()
Positions the result to the next available record (row) in the result.
Definition: qsql_odbc.cpp:1026
QODBCPrivate * d
Definition: qsql_odbc.h:110
bool isForwardOnly() const
Returns true if you can only scroll forward through the result set; otherwise returns false...
Definition: qsqlresult.cpp:582
int at() const
Returns the current (zero-based) row position of the result.
Definition: qsqlresult.cpp:306
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
Definition: qsqlresult.cpp:417
void clearValues()
Definition: qsql_odbc.cpp:168
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QODBCPrivate *p)
Definition: qsql_odbc.cpp:277

◆ fetchNext()

bool QODBCResult::fetchNext ( )
protectedvirtual

Positions the result to the next available record (row) in the result.

This function is only called if the result is in an active state. The default implementation calls fetch() with the next index. Derived classes can reimplement this function and position the result to the next record in some other way, and call setAt() with an appropriate value. Return true to indicate success, or false to signify failure.

See also
fetch(), fetchPrevious()

Reimplemented from QSqlResult.

Definition at line 1026 of file qsql_odbc.cpp.

Referenced by fetch(), fetchFirst(), and fetchLast().

1027 {
1028  SQLRETURN r;
1029  d->clearValues();
1030 
1031  if (d->hasSQLFetchScroll)
1032  r = SQLFetchScroll(d->hStmt,
1033  SQL_FETCH_NEXT,
1034  0);
1035  else
1036  r = SQLFetch(d->hStmt);
1037 
1038  if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
1039  if (r != SQL_NO_DATA)
1041  "Unable to fetch next"), QSqlError::ConnectionError, d));
1042  return false;
1043  }
1044  setAt(at() + 1);
1045  return true;
1046 }
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
QODBCPrivate * d
Definition: qsql_odbc.h:110
int at() const
Returns the current (zero-based) row position of the result.
Definition: qsqlresult.cpp:306
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
Definition: qsqlresult.cpp:417
void clearValues()
Definition: qsql_odbc.cpp:168
bool hasSQLFetchScroll
Definition: qsql_odbc.cpp:182
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QODBCPrivate *p)
Definition: qsql_odbc.cpp:277

◆ fetchPrevious()

bool QODBCResult::fetchPrevious ( )
protectedvirtual

Positions the result to the previous record (row) in the result.

This function is only called if the result is in an active state. The default implementation calls fetch() with the previous index. Derived classes can reimplement this function and position the result to the next record in some other way, and call setAt() with an appropriate value. Return true to indicate success, or false to signify failure.

Reimplemented from QSqlResult.

Definition at line 1070 of file qsql_odbc.cpp.

1071 {
1072  if (isForwardOnly())
1073  return false;
1074  SQLRETURN r;
1075  d->clearValues();
1076  r = SQLFetchScroll(d->hStmt,
1077  SQL_FETCH_PRIOR,
1078  0);
1079  if (r != SQL_SUCCESS) {
1080  if (r != SQL_NO_DATA)
1082  "Unable to fetch previous"), QSqlError::ConnectionError, d));
1083  return false;
1084  }
1085  setAt(at() - 1);
1086  return true;
1087 }
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
QODBCPrivate * d
Definition: qsql_odbc.h:110
bool isForwardOnly() const
Returns true if you can only scroll forward through the result set; otherwise returns false...
Definition: qsqlresult.cpp:582
int at() const
Returns the current (zero-based) row position of the result.
Definition: qsqlresult.cpp:306
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
Definition: qsqlresult.cpp:417
void clearValues()
Definition: qsql_odbc.cpp:168
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QODBCPrivate *p)
Definition: qsql_odbc.cpp:277

◆ handle()

QVariant QODBCResult::handle ( ) const
virtual

Returns the low-level database handle for this result set wrapped in a QVariant or an invalid QVariant if there is no handle.

Warning
Use this with uttermost care and only if you know what you're doing.
The handle returned here can become a stale pointer if the result is modified (for example, if you clear it).
The handle can be NULL if the result was not executed yet.

The handle returned here is database-dependent, you should query the type name of the variant before accessing it.

This example retrieves the handle for a sqlite result:

QSqlQuery query = ...
QVariant v = query.result()->handle();
if (v.isValid() && qstrcmp(v.typeName(), "sqlite3_stmt*")) {
// v.data() returns a pointer to the handle
sqlite3_stmt *handle = *static_cast<sqlite3_stmt **>(v.data());
if (handle != 0) { // check that it is not NULL
...
}
}

This snippet returns the handle for PostgreSQL or MySQL:

if (v.typeName() == "PGresult*") {
PGresult *handle = *static_cast<PGresult **>(v.data());
if (handle != 0) ...
}
if (v.typeName() == "MYSQL_STMT*") {
MYSQL_STMT *handle = *static_cast<MYSQL_STMT **>(v.data());
if (handle != 0) ...
}
See also
QSqlDriver::handle()

Reimplemented from QSqlResult.

Definition at line 1674 of file qsql_odbc.cpp.

1675 {
1676  return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);
1677 }
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
QODBCPrivate * d
Definition: qsql_odbc.h:110

◆ isNull()

bool QODBCResult::isNull ( int  i)
protectedvirtual

Returns true if the field at position index in the current row is null; otherwise returns false.

Implements QSqlResult.

Definition at line 1228 of file qsql_odbc.cpp.

1229 {
1230  if (field < 0 || field > d->fieldCache.size())
1231  return true;
1232  if (field <= d->fieldCacheIdx) {
1233  // since there is no good way to find out whether the value is NULL
1234  // without fetching the field we'll fetch it here.
1235  // (data() also sets the NULL flag)
1236  data(field);
1237  }
1238  return d->fieldCache.at(field).isNull();
1239 }
QODBCPrivate * d
Definition: qsql_odbc.h:110
bool isNull() const
Returns true if this is a NULL variant, false otherwise.
Definition: qvariant.cpp:3102
QVariant data(int field)
Returns the data for field index in the current row as a QVariant.
Definition: qsql_odbc.cpp:1128
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QVector< QVariant > fieldCache
Definition: qsql_odbc.cpp:179
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ nextResult()

bool QODBCResult::nextResult ( )
protected

Definition at line 1679 of file qsql_odbc.cpp.

Referenced by virtual_hook().

1680 {
1681  setActive(false);
1683  d->rInf.clear();
1684  d->fieldCache.clear();
1685  d->fieldCacheIdx = 0;
1686  setSelect(false);
1687 
1688  SQLRETURN r = SQLMoreResults(d->hStmt);
1689  if (r != SQL_SUCCESS) {
1690  if (r == SQL_SUCCESS_WITH_INFO) {
1691  int nativeCode = -1;
1692  QString message = qODBCWarn(d, &nativeCode);
1693  qWarning() << "QODBCResult::nextResult():" << message;
1694  } else {
1695  if (r != SQL_NO_DATA)
1697  "Unable to fetch last"), QSqlError::ConnectionError, d));
1698  return false;
1699  }
1700  }
1701 
1702  SQLSMALLINT count;
1703  SQLNumResultCols(d->hStmt, &count);
1704  if (count) {
1705  setSelect(true);
1706  for (int i = 0; i < count; ++i) {
1707  d->rInf.append(qMakeFieldInfo(d, i));
1708  }
1709  d->fieldCache.resize(count);
1710  } else {
1711  setSelect(false);
1712  }
1713  setActive(true);
1714 
1715  return true;
1716 }
static QString qODBCWarn(const QODBCPrivate *odbc, int *nativeCode=0)
Definition: qsql_odbc.cpp:254
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
QODBCPrivate * d
Definition: qsql_odbc.h:110
The QString class provides a Unicode character string.
Definition: qstring.h:83
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
Definition: qsqlresult.cpp:417
virtual void setSelect(bool s)
This function is provided for derived classes to indicate whether or not the current statement is a S...
Definition: qsqlresult.cpp:367
void clear()
Removes all the elements from the vector and releases the memory used by the vector.
Definition: qvector.h:347
Q_CORE_EXPORT void qWarning(const char *,...)
QVector< QVariant > fieldCache
Definition: qsql_odbc.cpp:179
void append(const QSqlField &field)
Append a copy of field field to the end of the record.
Definition: qsqlrecord.cpp:312
static QSqlField qMakeFieldInfo(const SQLHANDLE hStmt, const QODBCDriverPrivate *p)
Definition: qsql_odbc.cpp:574
virtual void setActive(bool a)
This function is provided for derived classes to set the internal active state to active...
Definition: qsqlresult.cpp:402
void clear()
Removes all the record&#39;s fields.
Definition: qsqlrecord.cpp:367
QSqlRecord rInf
Definition: qsql_odbc.cpp:178
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QODBCPrivate *p)
Definition: qsql_odbc.cpp:277

◆ numRowsAffected()

int QODBCResult::numRowsAffected ( )
protectedvirtual

Returns the number of rows affected by the last query executed, or -1 if it cannot be determined or if the query is a SELECT statement.

See also
size()

Implements QSqlResult.

Definition at line 1246 of file qsql_odbc.cpp.

1247 {
1248  SQLLEN affectedRowCount = 0;
1249  SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
1250  if (r == SQL_SUCCESS)
1251  return affectedRowCount;
1252  else
1253  qSqlWarning(QLatin1String("QODBCResult::numRowsAffected: Unable to count affected rows"), d);
1254  return -1;
1255 }
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
QODBCPrivate * d
Definition: qsql_odbc.h:110
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
static void qSqlWarning(const QString &message, const QODBCPrivate *odbc)
Definition: qsql_odbc.cpp:267

◆ prepare()

bool QODBCResult::prepare ( const QString query)
virtual

Prepares the given query for execution; the query will normally use placeholders so that it can be executed repeatedly.

Returns true if the query is prepared successfully; otherwise returns false.

See also
exec()

Reimplemented from QSqlResult.

Definition at line 1257 of file qsql_odbc.cpp.

1258 {
1259  setActive(false);
1261  SQLRETURN r;
1262 
1263  d->rInf.clear();
1264  if (d->hStmt && d->isStmtHandleValid(driver())) {
1265  r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
1266  if (r != SQL_SUCCESS) {
1267  qSqlWarning(QLatin1String("QODBCResult::prepare: Unable to close statement"), d);
1268  return false;
1269  }
1270  }
1271  r = SQLAllocHandle(SQL_HANDLE_STMT,
1272  d->dpDbc(),
1273  &d->hStmt);
1274  if (r != SQL_SUCCESS) {
1275  qSqlWarning(QLatin1String("QODBCResult::prepare: Unable to allocate statement handle"), d);
1276  return false;
1277  }
1278 
1280 
1281  if (d->userForwardOnly) {
1282  r = SQLSetStmtAttr(d->hStmt,
1283  SQL_ATTR_CURSOR_TYPE,
1284  (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
1285  SQL_IS_UINTEGER);
1286  } else {
1287  r = SQLSetStmtAttr(d->hStmt,
1288  SQL_ATTR_CURSOR_TYPE,
1289  (SQLPOINTER)SQL_CURSOR_STATIC,
1290  SQL_IS_UINTEGER);
1291  }
1292  if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
1294  "QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. "
1295  "Please check your ODBC driver configuration"), QSqlError::StatementError, d));
1296  return false;
1297  }
1298 
1299 #ifdef UNICODE
1300  r = SQLPrepare(d->hStmt,
1301  toSQLTCHAR(query).data(),
1302  (SQLINTEGER) query.length());
1303 #else
1304  QByteArray query8 = query.toUtf8();
1305  r = SQLPrepare(d->hStmt,
1306  (SQLCHAR*) query8.data(),
1307  (SQLINTEGER) query8.length());
1308 #endif
1309 
1310  if (r != SQL_SUCCESS) {
1312  "Unable to prepare statement"), QSqlError::StatementError, d));
1313  return false;
1314  }
1315  return true;
1316 }
const QSqlDriver * driver() const
Returns the driver associated with the result.
Definition: qsqlresult.cpp:389
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
QODBCPrivate * d
Definition: qsql_odbc.h:110
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
static QVarLengthArray< SQLTCHAR > toSQLTCHAR(const QString &input)
Definition: qsql_odbc.cpp:93
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QVariant data(int field)
Returns the data for field index in the current row as a QVariant.
Definition: qsql_odbc.cpp:1128
SQLHANDLE dpDbc() const
Definition: qsql_odbc.cpp:172
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
Definition: qsqlresult.cpp:417
static void qSqlWarning(const QString &message, const QODBCPrivate *odbc)
Definition: qsql_odbc.cpp:267
bool isStmtHandleValid(const QSqlDriver *driver)
Definition: qsql_odbc.cpp:190
virtual void setActive(bool a)
This function is provided for derived classes to set the internal active state to active...
Definition: qsqlresult.cpp:402
void clear()
Removes all the record&#39;s fields.
Definition: qsqlrecord.cpp:367
QSqlRecord rInf
Definition: qsql_odbc.cpp:178
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QODBCPrivate *p)
Definition: qsql_odbc.cpp:277
bool userForwardOnly
Definition: qsql_odbc.cpp:184
void updateStmtHandleState(const QSqlDriver *driver)
Definition: qsql_odbc.cpp:196

◆ record()

QSqlRecord QODBCResult::record ( ) const
protectedvirtual

Returns the current record if the query is active; otherwise returns an empty QSqlRecord.

The default implementation always returns an empty QSqlRecord.

See also
isActive()

Reimplemented from QSqlResult.

Definition at line 1667 of file qsql_odbc.cpp.

1668 {
1669  if (!isActive() || !isSelect())
1670  return QSqlRecord();
1671  return d->rInf;
1672 }
bool isActive() const
Returns true if the result has records to be retrieved; otherwise returns false.
Definition: qsqlresult.cpp:340
QODBCPrivate * d
Definition: qsql_odbc.h:110
The QSqlRecord class encapsulates a database record.
Definition: qsqlrecord.h:58
bool isSelect() const
Returns true if the current result is from a SELECT statement; otherwise returns false.
Definition: qsqlresult.cpp:379
QSqlRecord rInf
Definition: qsql_odbc.cpp:178

◆ reset()

bool QODBCResult::reset ( const QString query)
protectedvirtual

Sets the result to use the SQL statement query for subsequent data retrieval.

Derived classes must reimplement this function and apply the query to the database. This function is only called after the result is set to an inactive state and is positioned before the first record of the new result. Derived classes should return true if the query was successful and ready to be used, or false otherwise.

See also
setQuery()

Implements QSqlResult.

Definition at line 907 of file qsql_odbc.cpp.

908 {
909  setActive(false);
911  d->rInf.clear();
912  d->fieldCache.clear();
913  d->fieldCacheIdx = 0;
914 
915  // Always reallocate the statement handle - the statement attributes
916  // are not reset if SQLFreeStmt() is called which causes some problems.
917  SQLRETURN r;
918  if (d->hStmt && d->isStmtHandleValid(driver())) {
919  r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
920  if (r != SQL_SUCCESS) {
921  qSqlWarning(QLatin1String("QODBCResult::reset: Unable to free statement handle"), d);
922  return false;
923  }
924  }
925  r = SQLAllocHandle(SQL_HANDLE_STMT,
926  d->dpDbc(),
927  &d->hStmt);
928  if (r != SQL_SUCCESS) {
929  qSqlWarning(QLatin1String("QODBCResult::reset: Unable to allocate statement handle"), d);
930  return false;
931  }
932 
934 
935  if (d->userForwardOnly) {
936  r = SQLSetStmtAttr(d->hStmt,
937  SQL_ATTR_CURSOR_TYPE,
938  (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
939  SQL_IS_UINTEGER);
940  } else {
941  r = SQLSetStmtAttr(d->hStmt,
942  SQL_ATTR_CURSOR_TYPE,
943  (SQLPOINTER)SQL_CURSOR_STATIC,
944  SQL_IS_UINTEGER);
945  }
946  if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
948  "QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. "
949  "Please check your ODBC driver configuration"), QSqlError::StatementError, d));
950  return false;
951  }
952 
953 #ifdef UNICODE
954  r = SQLExecDirect(d->hStmt,
955  toSQLTCHAR(query).data(),
956  (SQLINTEGER) query.length());
957 #else
958  QByteArray query8 = query.toUtf8();
959  r = SQLExecDirect(d->hStmt,
960  (SQLCHAR*) query8.data(),
961  (SQLINTEGER) query8.length());
962 #endif
963  if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r!= SQL_NO_DATA) {
965  "Unable to execute statement"), QSqlError::StatementError, d));
966  return false;
967  }
968 
969  SQLULEN isScrollable = 0;
970  r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, 0);
971  if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
972  QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE);
973 
974  SQLSMALLINT count;
975  SQLNumResultCols(d->hStmt, &count);
976  if (count) {
977  setSelect(true);
978  for (int i = 0; i < count; ++i) {
979  d->rInf.append(qMakeFieldInfo(d, i));
980  }
981  d->fieldCache.resize(count);
982  } else {
983  setSelect(false);
984  }
985  setActive(true);
986 
987  return true;
988 }
const QSqlDriver * driver() const
Returns the driver associated with the result.
Definition: qsqlresult.cpp:389
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
QODBCPrivate * d
Definition: qsql_odbc.h:110
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
static QVarLengthArray< SQLTCHAR > toSQLTCHAR(const QString &input)
Definition: qsql_odbc.cpp:93
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QVariant data(int field)
Returns the data for field index in the current row as a QVariant.
Definition: qsql_odbc.cpp:1128
SQLHANDLE dpDbc() const
Definition: qsql_odbc.cpp:172
virtual void setAt(int at)
This function is provided for derived classes to set the internal (zero-based) row position to index...
Definition: qsqlresult.cpp:352
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
virtual void setLastError(const QSqlError &e)
This function is provided for derived classes to set the last error to error.
Definition: qsqlresult.cpp:417
virtual void setSelect(bool s)
This function is provided for derived classes to indicate whether or not the current statement is a S...
Definition: qsqlresult.cpp:367
void clear()
Removes all the elements from the vector and releases the memory used by the vector.
Definition: qvector.h:347
static void qSqlWarning(const QString &message, const QODBCPrivate *odbc)
Definition: qsql_odbc.cpp:267
virtual void setForwardOnly(bool forward)
Sets forward only mode to forward.
Definition: qsqlresult.cpp:603
QVector< QVariant > fieldCache
Definition: qsql_odbc.cpp:179
bool isStmtHandleValid(const QSqlDriver *driver)
Definition: qsql_odbc.cpp:190
void append(const QSqlField &field)
Append a copy of field field to the end of the record.
Definition: qsqlrecord.cpp:312
static QSqlField qMakeFieldInfo(const SQLHANDLE hStmt, const QODBCDriverPrivate *p)
Definition: qsql_odbc.cpp:574
virtual void setActive(bool a)
This function is provided for derived classes to set the internal active state to active...
Definition: qsqlresult.cpp:402
void clear()
Removes all the record&#39;s fields.
Definition: qsqlrecord.cpp:367
QSqlRecord rInf
Definition: qsql_odbc.cpp:178
static QSqlError qMakeError(const QString &err, QSqlError::ErrorType type, const QODBCPrivate *p)
Definition: qsql_odbc.cpp:277
bool userForwardOnly
Definition: qsql_odbc.cpp:184
void updateStmtHandleState(const QSqlDriver *driver)
Definition: qsql_odbc.cpp:196

◆ setForwardOnly()

void QODBCResult::setForwardOnly ( bool  forward)
virtual

Sets forward only mode to forward.

If forward is true, only fetchNext() is allowed for navigating the results. Forward only mode needs much less memory since results do not have to be cached. By default, this feature is disabled.

Setting forward only to false is a suggestion to the database engine, which has the final say on whether a result set is forward only or scrollable. isForwardOnly() will always return the correct status of the result set.

Note
Calling setForwardOnly after execution of the query will result in unexpected results at best, and crashes at worst.
See also
isForwardOnly(), fetchNext(), QSqlQuery::setForwardOnly()

Reimplemented from QSqlResult.

Definition at line 1734 of file qsql_odbc.cpp.

1735 {
1736  d->userForwardOnly = forward;
1737  QSqlResult::setForwardOnly(forward);
1738 }
QODBCPrivate * d
Definition: qsql_odbc.h:110
virtual void setForwardOnly(bool forward)
Sets forward only mode to forward.
Definition: qsqlresult.cpp:603
bool userForwardOnly
Definition: qsql_odbc.cpp:184

◆ size()

int QODBCResult::size ( )
protectedvirtual

Returns the size of the SELECT result, or -1 if it cannot be determined or if the query is not a SELECT statement.

See also
numRowsAffected()

Implements QSqlResult.

Definition at line 1241 of file qsql_odbc.cpp.

1242 {
1243  return -1;
1244 }

◆ virtual_hook()

void QODBCResult::virtual_hook ( int  id,
void *  data 
)
protectedvirtual
Warning
This function is not part of the public interface.

Reimplemented from QSqlResult.

Definition at line 1718 of file qsql_odbc.cpp.

1719 {
1720  switch (id) {
1722  if (d->hStmt)
1723  SQLCloseCursor(d->hStmt);
1724  break;
1726  Q_ASSERT(data);
1727  *static_cast<bool*>(data) = nextResult();
1728  break;
1729  default:
1731  }
1732 }
bool nextResult()
Definition: qsql_odbc.cpp:1679
SQLHANDLE hStmt
Definition: qsql_odbc.cpp:173
QODBCPrivate * d
Definition: qsql_odbc.h:110
QVariant data(int field)
Returns the data for field index in the current row as a QVariant.
Definition: qsql_odbc.cpp:1128
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
virtual void virtual_hook(int id, void *data)
Definition: qsqlresult.cpp:962

Properties

◆ d

QODBCPrivate* QODBCResult::d
private

The documentation for this class was generated from the following files: