1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qsqlquery.h" |
5 | |
6 | //#define QT_DEBUG_SQL |
7 | |
8 | #include "qatomic.h" |
9 | #include "qdebug.h" |
10 | #include "qsqlrecord.h" |
11 | #include "qsqlresult.h" |
12 | #include "qsqldriver.h" |
13 | #include "qsqldatabase.h" |
14 | #include "private/qsqlnulldriver_p.h" |
15 | |
16 | #ifdef QT_DEBUG_SQL |
17 | #include "qelapsedtimer.h" |
18 | #endif |
19 | |
20 | QT_BEGIN_NAMESPACE |
21 | |
22 | class QSqlQueryPrivate |
23 | { |
24 | public: |
25 | QSqlQueryPrivate(QSqlResult* result); |
26 | ~QSqlQueryPrivate(); |
27 | QAtomicInt ref; |
28 | QSqlResult* sqlResult; |
29 | |
30 | static QSqlQueryPrivate* shared_null(); |
31 | }; |
32 | |
33 | Q_GLOBAL_STATIC_WITH_ARGS(QSqlQueryPrivate, nullQueryPrivate, (nullptr)) |
34 | Q_GLOBAL_STATIC(QSqlNullDriver, nullDriver) |
35 | Q_GLOBAL_STATIC_WITH_ARGS(QSqlNullResult, nullResult, (nullDriver())) |
36 | |
37 | QSqlQueryPrivate* QSqlQueryPrivate::shared_null() |
38 | { |
39 | QSqlQueryPrivate *null = nullQueryPrivate(); |
40 | null->ref.ref(); |
41 | return null; |
42 | } |
43 | |
44 | /*! |
45 | \internal |
46 | */ |
47 | QSqlQueryPrivate::QSqlQueryPrivate(QSqlResult* result) |
48 | : ref(1), sqlResult(result) |
49 | { |
50 | if (!sqlResult) |
51 | sqlResult = nullResult(); |
52 | } |
53 | |
54 | QSqlQueryPrivate::~QSqlQueryPrivate() |
55 | { |
56 | QSqlResult *nr = nullResult(); |
57 | if (!nr || sqlResult == nr) |
58 | return; |
59 | delete sqlResult; |
60 | } |
61 | |
62 | /*! |
63 | \class QSqlQuery |
64 | \brief The QSqlQuery class provides a means of executing and |
65 | manipulating SQL statements. |
66 | |
67 | \ingroup database |
68 | \ingroup shared |
69 | |
70 | \inmodule QtSql |
71 | |
72 | QSqlQuery encapsulates the functionality involved in creating, |
73 | navigating and retrieving data from SQL queries which are |
74 | executed on a \l QSqlDatabase. It can be used to execute DML |
75 | (data manipulation language) statements, such as \c SELECT, \c |
76 | INSERT, \c UPDATE and \c DELETE, as well as DDL (data definition |
77 | language) statements, such as \c{CREATE} \c{TABLE}. It can also |
78 | be used to execute database-specific commands which are not |
79 | standard SQL (e.g. \c{SET DATESTYLE=ISO} for PostgreSQL). |
80 | |
81 | Successfully executed SQL statements set the query's state to |
82 | active so that isActive() returns \c true. Otherwise the query's |
83 | state is set to inactive. In either case, when executing a new SQL |
84 | statement, the query is positioned on an invalid record. An active |
85 | query must be navigated to a valid record (so that isValid() |
86 | returns \c true) before values can be retrieved. |
87 | |
88 | For some databases, if an active query that is a \c{SELECT} |
89 | statement exists when you call \l{QSqlDatabase::}{commit()} or |
90 | \l{QSqlDatabase::}{rollback()}, the commit or rollback will |
91 | fail. See isActive() for details. |
92 | |
93 | \target QSqlQuery examples |
94 | |
95 | Navigating records is performed with the following functions: |
96 | |
97 | \list |
98 | \li next() |
99 | \li previous() |
100 | \li first() |
101 | \li last() |
102 | \li seek() |
103 | \endlist |
104 | |
105 | These functions allow the programmer to move forward, backward |
106 | or arbitrarily through the records returned by the query. If you |
107 | only need to move forward through the results (e.g., by using |
108 | next()), you can use setForwardOnly(), which will save a |
109 | significant amount of memory overhead and improve performance on |
110 | some databases. Once an active query is positioned on a valid |
111 | record, data can be retrieved using value(). All data is |
112 | transferred from the SQL backend using QVariants. |
113 | |
114 | For example: |
115 | |
116 | \snippet sqldatabase/sqldatabase.cpp 7 |
117 | |
118 | To access the data returned by a query, use value(int). Each |
119 | field in the data returned by a \c SELECT statement is accessed |
120 | by passing the field's position in the statement, starting from |
121 | 0. This makes using \c{SELECT *} queries inadvisable because the |
122 | order of the fields returned is indeterminate. |
123 | |
124 | For the sake of efficiency, there are no functions to access a |
125 | field by name (unless you use prepared queries with names, as |
126 | explained below). To convert a field name into an index, use |
127 | record().\l{QSqlRecord::indexOf()}{indexOf()}, for example: |
128 | |
129 | \snippet sqldatabase/sqldatabase.cpp 8 |
130 | |
131 | QSqlQuery supports prepared query execution and the binding of |
132 | parameter values to placeholders. Some databases don't support |
133 | these features, so for those, Qt emulates the required |
134 | functionality. For example, the Oracle and ODBC drivers have |
135 | proper prepared query support, and Qt makes use of it; but for |
136 | databases that don't have this support, Qt implements the feature |
137 | itself, e.g. by replacing placeholders with actual values when a |
138 | query is executed. Use numRowsAffected() to find out how many rows |
139 | were affected by a non-\c SELECT query, and size() to find how |
140 | many were retrieved by a \c SELECT. |
141 | |
142 | Oracle databases identify placeholders by using a colon-name |
143 | syntax, e.g \c{:name}. ODBC simply uses \c ? characters. Qt |
144 | supports both syntaxes, with the restriction that you can't mix |
145 | them in the same query. |
146 | |
147 | You can retrieve the values of all the fields in a single variable |
148 | using boundValues(). |
149 | |
150 | \note Not all SQL operations support binding values. Refer to your database |
151 | system's documentation to check their availability. |
152 | |
153 | \section1 Approaches to Binding Values |
154 | |
155 | Below we present the same example using each of the four |
156 | different binding approaches, as well as one example of binding |
157 | values to a stored procedure. |
158 | |
159 | \b{Named binding using named placeholders:} |
160 | |
161 | \snippet sqldatabase/sqldatabase.cpp 9 |
162 | |
163 | \b{Positional binding using named placeholders:} |
164 | |
165 | \snippet sqldatabase/sqldatabase.cpp 10 |
166 | |
167 | \b{Binding values using positional placeholders (version 1):} |
168 | |
169 | \snippet sqldatabase/sqldatabase.cpp 11 |
170 | |
171 | \b{Binding values using positional placeholders (version 2):} |
172 | |
173 | \snippet sqldatabase/sqldatabase.cpp 12 |
174 | |
175 | \b{Binding values to a stored procedure:} |
176 | |
177 | This code calls a stored procedure called \c AsciiToInt(), passing |
178 | it a character through its in parameter, and taking its result in |
179 | the out parameter. |
180 | |
181 | \snippet sqldatabase/sqldatabase.cpp 13 |
182 | |
183 | Note that unbound parameters will retain their values. |
184 | |
185 | Stored procedures that uses the return statement to return values, |
186 | or return multiple result sets, are not fully supported. For specific |
187 | details see \l{SQL Database Drivers}. |
188 | |
189 | \warning You must load the SQL driver and open the connection before a |
190 | QSqlQuery is created. Also, the connection must remain open while the |
191 | query exists; otherwise, the behavior of QSqlQuery is undefined. |
192 | |
193 | \sa QSqlDatabase, QSqlQueryModel, QSqlTableModel, QVariant |
194 | */ |
195 | |
196 | /*! |
197 | Constructs a QSqlQuery object which uses the QSqlResult \a result |
198 | to communicate with a database. |
199 | */ |
200 | |
201 | QSqlQuery::QSqlQuery(QSqlResult *result) |
202 | { |
203 | d = new QSqlQueryPrivate(result); |
204 | } |
205 | |
206 | /*! |
207 | Destroys the object and frees any allocated resources. |
208 | */ |
209 | |
210 | QSqlQuery::~QSqlQuery() |
211 | { |
212 | if (d && !d->ref.deref()) |
213 | delete d; |
214 | } |
215 | |
216 | #if QT_DEPRECATED_SINCE(6, 2) |
217 | /*! |
218 | Constructs a copy of \a other. |
219 | |
220 | \deprecated QSqlQuery cannot be meaningfully copied. Prepared |
221 | statements, bound values and so on will not work correctly, depending |
222 | on your database driver (for instance, changing the copy will affect |
223 | the original). Treat QSqlQuery as a move-only type instead. |
224 | */ |
225 | |
226 | QSqlQuery::QSqlQuery(const QSqlQuery& other) |
227 | { |
228 | d = other.d; |
229 | d->ref.ref(); |
230 | } |
231 | |
232 | /*! |
233 | Assigns \a other to this object. |
234 | |
235 | \deprecated QSqlQuery cannot be meaningfully copied. Prepared |
236 | statements, bound values and so on will not work correctly, depending |
237 | on your database driver (for instance, changing the copy will affect |
238 | the original). Treat QSqlQuery as a move-only type instead. |
239 | */ |
240 | |
241 | QSqlQuery& QSqlQuery::operator=(const QSqlQuery& other) |
242 | { |
243 | qAtomicAssign(d, x: other.d); |
244 | return *this; |
245 | } |
246 | #endif |
247 | |
248 | /*! |
249 | \fn QSqlQuery::QSqlQuery(QSqlQuery &&other) noexcept |
250 | \since 6.2 |
251 | Move-constructs a QSqlQuery from \a other. |
252 | */ |
253 | |
254 | /*! |
255 | \fn QSqlQuery &QSqlQuery::operator=(QSqlQuery &&other) noexcept |
256 | \since 6.2 |
257 | Move-assigns \a other to this object. |
258 | */ |
259 | |
260 | /*! |
261 | \fn void QSqlQuery::swap(QSqlQuery &other) noexcept |
262 | \since 6.2 |
263 | Swaps \a other to this object. This operation is very |
264 | fast and never fails. |
265 | */ |
266 | |
267 | /*! |
268 | \internal |
269 | */ |
270 | static void qInit(QSqlQuery *q, const QString& query, const QSqlDatabase &db) |
271 | { |
272 | QSqlDatabase database = db; |
273 | if (!database.isValid()) { |
274 | database = |
275 | QSqlDatabase::database(connectionName: QLatin1StringView(QSqlDatabase::defaultConnection), open: false); |
276 | } |
277 | if (database.isValid()) |
278 | *q = QSqlQuery(database.driver()->createResult()); |
279 | |
280 | if (!query.isEmpty()) |
281 | q->exec(query); |
282 | } |
283 | |
284 | /*! |
285 | Constructs a QSqlQuery object using the SQL \a query and the |
286 | database \a db. If \a db is not specified, or is invalid, the application's |
287 | default database is used. If \a query is not an empty string, it |
288 | will be executed. |
289 | |
290 | \sa QSqlDatabase |
291 | */ |
292 | QSqlQuery::QSqlQuery(const QString& query, const QSqlDatabase &db) |
293 | { |
294 | d = QSqlQueryPrivate::shared_null(); |
295 | qInit(q: this, query, db); |
296 | } |
297 | |
298 | /*! |
299 | Constructs a QSqlQuery object using the database \a db. |
300 | If \a db is invalid, the application's default database will be used. |
301 | |
302 | \sa QSqlDatabase |
303 | */ |
304 | |
305 | QSqlQuery::QSqlQuery(const QSqlDatabase &db) |
306 | { |
307 | d = QSqlQueryPrivate::shared_null(); |
308 | qInit(q: this, query: QString(), db); |
309 | } |
310 | |
311 | /*! |
312 | Returns \c true if the query is not \l{isActive()}{active}, |
313 | the query is not positioned on a valid record, |
314 | there is no such \a field, or the \a field is null; otherwise \c false. |
315 | Note that for some drivers, isNull() will not return accurate |
316 | information until after an attempt is made to retrieve data. |
317 | |
318 | \sa isActive(), isValid(), value() |
319 | */ |
320 | |
321 | bool QSqlQuery::isNull(int field) const |
322 | { |
323 | return !d->sqlResult->isActive() |
324 | || !d->sqlResult->isValid() |
325 | || d->sqlResult->isNull(i: field); |
326 | } |
327 | |
328 | /*! |
329 | \overload |
330 | |
331 | Returns \c true if there is no field with this \a name; otherwise |
332 | returns isNull(int index) for the corresponding field index. |
333 | |
334 | This overload is less efficient than \l{QSqlQuery::}{isNull()} |
335 | */ |
336 | |
337 | bool QSqlQuery::isNull(const QString &name) const |
338 | { |
339 | qsizetype index = d->sqlResult->record().indexOf(name); |
340 | if (index > -1) |
341 | return isNull(field: index); |
342 | qWarning(msg: "QSqlQuery::isNull: unknown field name '%s'" , qPrintable(name)); |
343 | return true; |
344 | } |
345 | |
346 | /*! |
347 | |
348 | Executes the SQL in \a query. Returns \c true and sets the query state |
349 | to \l{isActive()}{active} if the query was successful; otherwise |
350 | returns \c false. The \a query string must use syntax appropriate for |
351 | the SQL database being queried (for example, standard SQL). |
352 | |
353 | After the query is executed, the query is positioned on an \e |
354 | invalid record and must be navigated to a valid record before data |
355 | values can be retrieved (for example, using next()). |
356 | |
357 | Note that the last error for this query is reset when exec() is |
358 | called. |
359 | |
360 | For SQLite, the query string can contain only one statement at a time. |
361 | If more than one statement is given, the function returns \c false. |
362 | |
363 | Example: |
364 | |
365 | \snippet sqldatabase/sqldatabase.cpp 34 |
366 | |
367 | \sa isActive(), isValid(), next(), previous(), first(), last(), |
368 | seek() |
369 | */ |
370 | |
371 | bool QSqlQuery::exec(const QString& query) |
372 | { |
373 | #ifdef QT_DEBUG_SQL |
374 | QElapsedTimer t; |
375 | t.start(); |
376 | #endif |
377 | if (!driver()) { |
378 | qWarning(msg: "QSqlQuery::exec: called before driver has been set up" ); |
379 | return false; |
380 | } |
381 | if (d->ref.loadRelaxed() != 1) { |
382 | bool fo = isForwardOnly(); |
383 | *this = QSqlQuery(driver()->createResult()); |
384 | d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy()); |
385 | setForwardOnly(fo); |
386 | } else { |
387 | d->sqlResult->clear(); |
388 | d->sqlResult->setActive(false); |
389 | d->sqlResult->setLastError(QSqlError()); |
390 | d->sqlResult->setAt(QSql::BeforeFirstRow); |
391 | d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy()); |
392 | } |
393 | d->sqlResult->setQuery(query.trimmed()); |
394 | if (!driver()->isOpen() || driver()->isOpenError()) { |
395 | qWarning(msg: "QSqlQuery::exec: database not open" ); |
396 | return false; |
397 | } |
398 | if (query.isEmpty()) { |
399 | qWarning(msg: "QSqlQuery::exec: empty query" ); |
400 | return false; |
401 | } |
402 | |
403 | bool retval = d->sqlResult->reset(sqlquery: query); |
404 | #ifdef QT_DEBUG_SQL |
405 | qDebug().nospace() << "Executed query (" << t.elapsed() << "ms, " << d->sqlResult->size() |
406 | << " results, " << d->sqlResult->numRowsAffected() |
407 | << " affected): " << d->sqlResult->lastQuery(); |
408 | #endif |
409 | return retval; |
410 | } |
411 | |
412 | /*! |
413 | Returns the value of field \a index in the current record. |
414 | |
415 | The fields are numbered from left to right using the text of the |
416 | \c SELECT statement, e.g. in |
417 | |
418 | \snippet code/src_sql_kernel_qsqlquery_snippet.cpp 0 |
419 | |
420 | field 0 is \c forename and field 1 is \c |
421 | surname. Using \c{SELECT *} is not recommended because the order |
422 | of the fields in the query is undefined. |
423 | |
424 | An invalid QVariant is returned if field \a index does not |
425 | exist, if the query is inactive, or if the query is positioned on |
426 | an invalid record. |
427 | |
428 | \sa previous(), next(), first(), last(), seek(), isActive(), isValid() |
429 | */ |
430 | |
431 | QVariant QSqlQuery::value(int index) const |
432 | { |
433 | if (isActive() && isValid() && (index > -1)) |
434 | return d->sqlResult->data(i: index); |
435 | qWarning(msg: "QSqlQuery::value: not positioned on a valid record" ); |
436 | return QVariant(); |
437 | } |
438 | |
439 | /*! |
440 | \overload |
441 | |
442 | Returns the value of the field called \a name in the current record. |
443 | If field \a name does not exist an invalid variant is returned. |
444 | |
445 | This overload is less efficient than \l{QSqlQuery::}{value()} |
446 | */ |
447 | |
448 | QVariant QSqlQuery::value(const QString& name) const |
449 | { |
450 | qsizetype index = d->sqlResult->record().indexOf(name); |
451 | if (index > -1) |
452 | return value(index); |
453 | qWarning(msg: "QSqlQuery::value: unknown field name '%s'" , qPrintable(name)); |
454 | return QVariant(); |
455 | } |
456 | |
457 | /*! |
458 | Returns the current internal position of the query. The first |
459 | record is at position zero. If the position is invalid, the |
460 | function returns QSql::BeforeFirstRow or |
461 | QSql::AfterLastRow, which are special negative values. |
462 | |
463 | \sa previous(), next(), first(), last(), seek(), isActive(), isValid() |
464 | */ |
465 | |
466 | int QSqlQuery::at() const |
467 | { |
468 | return d->sqlResult->at(); |
469 | } |
470 | |
471 | /*! |
472 | Returns the text of the current query being used, or an empty |
473 | string if there is no current query text. |
474 | |
475 | \sa executedQuery() |
476 | */ |
477 | |
478 | QString QSqlQuery::lastQuery() const |
479 | { |
480 | return d->sqlResult->lastQuery(); |
481 | } |
482 | |
483 | /*! |
484 | Returns the database driver associated with the query. |
485 | */ |
486 | |
487 | const QSqlDriver *QSqlQuery::driver() const |
488 | { |
489 | return d->sqlResult->driver(); |
490 | } |
491 | |
492 | /*! |
493 | Returns the result associated with the query. |
494 | */ |
495 | |
496 | const QSqlResult* QSqlQuery::result() const |
497 | { |
498 | return d->sqlResult; |
499 | } |
500 | |
501 | /*! |
502 | Retrieves the record at position \a index, if available, and |
503 | positions the query on the retrieved record. The first record is at |
504 | position 0. Note that the query must be in an \l{isActive()} |
505 | {active} state and isSelect() must return true before calling this |
506 | function. |
507 | |
508 | If \a relative is false (the default), the following rules apply: |
509 | |
510 | \list |
511 | |
512 | \li If \a index is negative, the result is positioned before the |
513 | first record and false is returned. |
514 | |
515 | \li Otherwise, an attempt is made to move to the record at position |
516 | \a index. If the record at position \a index could not be retrieved, |
517 | the result is positioned after the last record and false is |
518 | returned. If the record is successfully retrieved, true is returned. |
519 | |
520 | \endlist |
521 | |
522 | If \a relative is true, the following rules apply: |
523 | |
524 | \list |
525 | |
526 | \li If the result is currently positioned before the first record and: |
527 | \list |
528 | \li \a index is negative or zero, there is no change, and false is |
529 | returned. |
530 | \li \a index is positive, an attempt is made to position the result |
531 | at absolute position \a index - 1, following the sames rule for non |
532 | relative seek, above. |
533 | \endlist |
534 | |
535 | \li If the result is currently positioned after the last record and: |
536 | \list |
537 | \li \a index is positive or zero, there is no change, and false is |
538 | returned. |
539 | \li \a index is negative, an attempt is made to position the result |
540 | at \a index + 1 relative position from last record, following the |
541 | rule below. |
542 | \endlist |
543 | |
544 | \li If the result is currently located somewhere in the middle, and |
545 | the relative offset \a index moves the result below zero, the result |
546 | is positioned before the first record and false is returned. |
547 | |
548 | \li Otherwise, an attempt is made to move to the record \a index |
549 | records ahead of the current record (or \a index records behind the |
550 | current record if \a index is negative). If the record at offset \a |
551 | index could not be retrieved, the result is positioned after the |
552 | last record if \a index >= 0, (or before the first record if \a |
553 | index is negative), and false is returned. If the record is |
554 | successfully retrieved, true is returned. |
555 | |
556 | \endlist |
557 | |
558 | \sa next(), previous(), first(), last(), at(), isActive(), isValid() |
559 | */ |
560 | bool QSqlQuery::seek(int index, bool relative) |
561 | { |
562 | if (!isSelect() || !isActive()) |
563 | return false; |
564 | int actualIdx; |
565 | if (!relative) { // arbitrary seek |
566 | if (index < 0) { |
567 | d->sqlResult->setAt(QSql::BeforeFirstRow); |
568 | return false; |
569 | } |
570 | actualIdx = index; |
571 | } else { |
572 | switch (at()) { // relative seek |
573 | case QSql::BeforeFirstRow: |
574 | if (index > 0) |
575 | actualIdx = index - 1; |
576 | else { |
577 | return false; |
578 | } |
579 | break; |
580 | case QSql::AfterLastRow: |
581 | if (index < 0) { |
582 | d->sqlResult->fetchLast(); |
583 | actualIdx = at() + index + 1; |
584 | } else { |
585 | return false; |
586 | } |
587 | break; |
588 | default: |
589 | if ((at() + index) < 0) { |
590 | d->sqlResult->setAt(QSql::BeforeFirstRow); |
591 | return false; |
592 | } |
593 | actualIdx = at() + index; |
594 | break; |
595 | } |
596 | } |
597 | // let drivers optimize |
598 | if (isForwardOnly() && actualIdx < at()) { |
599 | qWarning(msg: "QSqlQuery::seek: cannot seek backwards in a forward only query" ); |
600 | return false; |
601 | } |
602 | if (actualIdx == (at() + 1) && at() != QSql::BeforeFirstRow) { |
603 | if (!d->sqlResult->fetchNext()) { |
604 | d->sqlResult->setAt(QSql::AfterLastRow); |
605 | return false; |
606 | } |
607 | return true; |
608 | } |
609 | if (actualIdx == (at() - 1)) { |
610 | if (!d->sqlResult->fetchPrevious()) { |
611 | d->sqlResult->setAt(QSql::BeforeFirstRow); |
612 | return false; |
613 | } |
614 | return true; |
615 | } |
616 | if (!d->sqlResult->fetch(i: actualIdx)) { |
617 | d->sqlResult->setAt(QSql::AfterLastRow); |
618 | return false; |
619 | } |
620 | return true; |
621 | } |
622 | |
623 | /*! |
624 | |
625 | Retrieves the next record in the result, if available, and positions |
626 | the query on the retrieved record. Note that the result must be in |
627 | the \l{isActive()}{active} state and isSelect() must return true |
628 | before calling this function or it will do nothing and return false. |
629 | |
630 | The following rules apply: |
631 | |
632 | \list |
633 | |
634 | \li If the result is currently located before the first record, |
635 | e.g. immediately after a query is executed, an attempt is made to |
636 | retrieve the first record. |
637 | |
638 | \li If the result is currently located after the last record, there |
639 | is no change and false is returned. |
640 | |
641 | \li If the result is located somewhere in the middle, an attempt is |
642 | made to retrieve the next record. |
643 | |
644 | \endlist |
645 | |
646 | If the record could not be retrieved, the result is positioned after |
647 | the last record and false is returned. If the record is successfully |
648 | retrieved, true is returned. |
649 | |
650 | \sa previous(), first(), last(), seek(), at(), isActive(), isValid() |
651 | */ |
652 | bool QSqlQuery::next() |
653 | { |
654 | if (!isSelect() || !isActive()) |
655 | return false; |
656 | |
657 | switch (at()) { |
658 | case QSql::BeforeFirstRow: |
659 | return d->sqlResult->fetchFirst(); |
660 | case QSql::AfterLastRow: |
661 | return false; |
662 | default: |
663 | if (!d->sqlResult->fetchNext()) { |
664 | d->sqlResult->setAt(QSql::AfterLastRow); |
665 | return false; |
666 | } |
667 | return true; |
668 | } |
669 | } |
670 | |
671 | /*! |
672 | |
673 | Retrieves the previous record in the result, if available, and |
674 | positions the query on the retrieved record. Note that the result |
675 | must be in the \l{isActive()}{active} state and isSelect() must |
676 | return true before calling this function or it will do nothing and |
677 | return false. |
678 | |
679 | The following rules apply: |
680 | |
681 | \list |
682 | |
683 | \li If the result is currently located before the first record, there |
684 | is no change and false is returned. |
685 | |
686 | \li If the result is currently located after the last record, an |
687 | attempt is made to retrieve the last record. |
688 | |
689 | \li If the result is somewhere in the middle, an attempt is made to |
690 | retrieve the previous record. |
691 | |
692 | \endlist |
693 | |
694 | If the record could not be retrieved, the result is positioned |
695 | before the first record and false is returned. If the record is |
696 | successfully retrieved, true is returned. |
697 | |
698 | \sa next(), first(), last(), seek(), at(), isActive(), isValid() |
699 | */ |
700 | bool QSqlQuery::previous() |
701 | { |
702 | if (!isSelect() || !isActive()) |
703 | return false; |
704 | if (isForwardOnly()) { |
705 | qWarning(msg: "QSqlQuery::seek: cannot seek backwards in a forward only query" ); |
706 | return false; |
707 | } |
708 | |
709 | switch (at()) { |
710 | case QSql::BeforeFirstRow: |
711 | return false; |
712 | case QSql::AfterLastRow: |
713 | return d->sqlResult->fetchLast(); |
714 | default: |
715 | if (!d->sqlResult->fetchPrevious()) { |
716 | d->sqlResult->setAt(QSql::BeforeFirstRow); |
717 | return false; |
718 | } |
719 | return true; |
720 | } |
721 | } |
722 | |
723 | /*! |
724 | Retrieves the first record in the result, if available, and |
725 | positions the query on the retrieved record. Note that the result |
726 | must be in the \l{isActive()}{active} state and isSelect() must |
727 | return true before calling this function or it will do nothing and |
728 | return false. Returns \c true if successful. If unsuccessful the query |
729 | position is set to an invalid position and false is returned. |
730 | |
731 | \sa next(), previous(), last(), seek(), at(), isActive(), isValid() |
732 | */ |
733 | bool QSqlQuery::first() |
734 | { |
735 | if (!isSelect() || !isActive()) |
736 | return false; |
737 | if (isForwardOnly() && at() > QSql::BeforeFirstRow) { |
738 | qWarning(msg: "QSqlQuery::seek: cannot seek backwards in a forward only query" ); |
739 | return false; |
740 | } |
741 | return d->sqlResult->fetchFirst(); |
742 | } |
743 | |
744 | /*! |
745 | |
746 | Retrieves the last record in the result, if available, and positions |
747 | the query on the retrieved record. Note that the result must be in |
748 | the \l{isActive()}{active} state and isSelect() must return true |
749 | before calling this function or it will do nothing and return false. |
750 | Returns \c true if successful. If unsuccessful the query position is |
751 | set to an invalid position and false is returned. |
752 | |
753 | \sa next(), previous(), first(), seek(), at(), isActive(), isValid() |
754 | */ |
755 | |
756 | bool QSqlQuery::last() |
757 | { |
758 | if (!isSelect() || !isActive()) |
759 | return false; |
760 | return d->sqlResult->fetchLast(); |
761 | } |
762 | |
763 | /*! |
764 | Returns the size of the result (number of rows returned), or -1 if |
765 | the size cannot be determined or if the database does not support |
766 | reporting information about query sizes. Note that for non-\c SELECT |
767 | statements (isSelect() returns \c false), size() will return -1. If the |
768 | query is not active (isActive() returns \c false), -1 is returned. |
769 | |
770 | To determine the number of rows affected by a non-\c SELECT |
771 | statement, use numRowsAffected(). |
772 | |
773 | \sa isActive(), numRowsAffected(), QSqlDriver::hasFeature() |
774 | */ |
775 | int QSqlQuery::size() const |
776 | { |
777 | if (isActive() && d->sqlResult->driver()->hasFeature(f: QSqlDriver::QuerySize)) |
778 | return d->sqlResult->size(); |
779 | return -1; |
780 | } |
781 | |
782 | /*! |
783 | Returns the number of rows affected by the result's SQL statement, |
784 | or -1 if it cannot be determined. Note that for \c SELECT |
785 | statements, the value is undefined; use size() instead. If the query |
786 | is not \l{isActive()}{active}, -1 is returned. |
787 | |
788 | \sa size(), QSqlDriver::hasFeature() |
789 | */ |
790 | |
791 | int QSqlQuery::numRowsAffected() const |
792 | { |
793 | if (isActive()) |
794 | return d->sqlResult->numRowsAffected(); |
795 | return -1; |
796 | } |
797 | |
798 | /*! |
799 | Returns error information about the last error (if any) that |
800 | occurred with this query. |
801 | |
802 | \sa QSqlError, QSqlDatabase::lastError() |
803 | */ |
804 | |
805 | QSqlError QSqlQuery::lastError() const |
806 | { |
807 | return d->sqlResult->lastError(); |
808 | } |
809 | |
810 | /*! |
811 | Returns \c true if the query is currently positioned on a valid |
812 | record; otherwise returns \c false. |
813 | */ |
814 | |
815 | bool QSqlQuery::isValid() const |
816 | { |
817 | return d->sqlResult->isValid(); |
818 | } |
819 | |
820 | /*! |
821 | |
822 | Returns \c true if the query is \e{active}. An active QSqlQuery is one |
823 | that has been \l{QSqlQuery::exec()} {exec()'d} successfully but not |
824 | yet finished with. When you are finished with an active query, you |
825 | can make the query inactive by calling finish() or clear(), or |
826 | you can delete the QSqlQuery instance. |
827 | |
828 | \note Of particular interest is an active query that is a \c{SELECT} |
829 | statement. For some databases that support transactions, an active |
830 | query that is a \c{SELECT} statement can cause a \l{QSqlDatabase::} |
831 | {commit()} or a \l{QSqlDatabase::} {rollback()} to fail, so before |
832 | committing or rolling back, you should make your active \c{SELECT} |
833 | statement query inactive using one of the ways listed above. |
834 | |
835 | \sa isSelect() |
836 | */ |
837 | bool QSqlQuery::isActive() const |
838 | { |
839 | return d->sqlResult->isActive(); |
840 | } |
841 | |
842 | /*! |
843 | Returns \c true if the current query is a \c SELECT statement; |
844 | otherwise returns \c false. |
845 | */ |
846 | |
847 | bool QSqlQuery::isSelect() const |
848 | { |
849 | return d->sqlResult->isSelect(); |
850 | } |
851 | |
852 | /*! |
853 | Returns \c true if you can only scroll forward through a result set; |
854 | otherwise returns \c false. |
855 | |
856 | \sa setForwardOnly(), next() |
857 | */ |
858 | bool QSqlQuery::isForwardOnly() const |
859 | { |
860 | return d->sqlResult->isForwardOnly(); |
861 | } |
862 | |
863 | /*! |
864 | Sets forward only mode to \a forward. If \a forward is true, only |
865 | next() and seek() with positive values, are allowed for navigating |
866 | the results. |
867 | |
868 | Forward only mode can be (depending on the driver) more memory |
869 | efficient since results do not need to be cached. It will also |
870 | improve performance on some databases. For this to be true, you must |
871 | call \c setForwardOnly() before the query is prepared or executed. |
872 | Note that the constructor that takes a query and a database may |
873 | execute the query. |
874 | |
875 | Forward only mode is off by default. |
876 | |
877 | Setting forward only to false is a suggestion to the database engine, |
878 | which has the final say on whether a result set is forward only or |
879 | scrollable. isForwardOnly() will always return the correct status of |
880 | the result set. |
881 | |
882 | \note Calling setForwardOnly after execution of the query will result |
883 | in unexpected results at best, and crashes at worst. |
884 | |
885 | \note To make sure the forward-only query completed successfully, |
886 | the application should check lastError() for an error not only after |
887 | executing the query, but also after navigating the query results. |
888 | |
889 | \warning PostgreSQL: While navigating the query results in forward-only |
890 | mode, do not execute any other SQL command on the same database |
891 | connection. This will cause the query results to be lost. |
892 | |
893 | \sa isForwardOnly(), next(), seek(), QSqlResult::setForwardOnly() |
894 | */ |
895 | void QSqlQuery::setForwardOnly(bool forward) |
896 | { |
897 | d->sqlResult->setForwardOnly(forward); |
898 | } |
899 | |
900 | /*! |
901 | Returns a QSqlRecord containing the field information for the |
902 | current query. If the query points to a valid row (isValid() returns |
903 | true), the record is populated with the row's values. An empty |
904 | record is returned when there is no active query (isActive() returns |
905 | false). |
906 | |
907 | To retrieve values from a query, value() should be used since |
908 | its index-based lookup is faster. |
909 | |
910 | In the following example, a \c{SELECT * FROM} query is executed. |
911 | Since the order of the columns is not defined, QSqlRecord::indexOf() |
912 | is used to obtain the index of a column. |
913 | |
914 | \snippet code/src_sql_kernel_qsqlquery.cpp 1 |
915 | |
916 | \sa value() |
917 | */ |
918 | QSqlRecord QSqlQuery::record() const |
919 | { |
920 | QSqlRecord rec = d->sqlResult->record(); |
921 | |
922 | if (isValid()) { |
923 | for (qsizetype i = 0; i < rec.count(); ++i) |
924 | rec.setValue(i, val: value(index: i)); |
925 | } |
926 | return rec; |
927 | } |
928 | |
929 | /*! |
930 | Clears the result set and releases any resources held by the |
931 | query. Sets the query state to inactive. You should rarely if ever |
932 | need to call this function. |
933 | */ |
934 | void QSqlQuery::clear() |
935 | { |
936 | *this = QSqlQuery(driver()->createResult()); |
937 | } |
938 | |
939 | /*! |
940 | Prepares the SQL query \a query for execution. Returns \c true if the |
941 | query is prepared successfully; otherwise returns \c false. |
942 | |
943 | The query may contain placeholders for binding values. Both Oracle |
944 | style colon-name (e.g., \c{:surname}), and ODBC style (\c{?}) |
945 | placeholders are supported; but they cannot be mixed in the same |
946 | query. See the \l{QSqlQuery examples}{Detailed Description} for |
947 | examples. |
948 | |
949 | Portability notes: Some databases choose to delay preparing a query |
950 | until it is executed the first time. In this case, preparing a |
951 | syntactically wrong query succeeds, but every consecutive exec() |
952 | will fail. |
953 | When the database does not support named placeholders directly, |
954 | the placeholder can only contain characters in the range [a-zA-Z0-9_]. |
955 | |
956 | For SQLite, the query string can contain only one statement at a time. |
957 | If more than one statement is given, the function returns \c false. |
958 | |
959 | Example: |
960 | |
961 | \snippet sqldatabase/sqldatabase.cpp 9 |
962 | |
963 | \sa exec(), bindValue(), addBindValue() |
964 | */ |
965 | bool QSqlQuery::prepare(const QString& query) |
966 | { |
967 | if (d->ref.loadRelaxed() != 1) { |
968 | bool fo = isForwardOnly(); |
969 | *this = QSqlQuery(driver()->createResult()); |
970 | setForwardOnly(fo); |
971 | d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy()); |
972 | } else { |
973 | d->sqlResult->setActive(false); |
974 | d->sqlResult->setLastError(QSqlError()); |
975 | d->sqlResult->setAt(QSql::BeforeFirstRow); |
976 | d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy()); |
977 | } |
978 | if (!driver()) { |
979 | qWarning(msg: "QSqlQuery::prepare: no driver" ); |
980 | return false; |
981 | } |
982 | if (!driver()->isOpen() || driver()->isOpenError()) { |
983 | qWarning(msg: "QSqlQuery::prepare: database not open" ); |
984 | return false; |
985 | } |
986 | if (query.isEmpty()) { |
987 | qWarning(msg: "QSqlQuery::prepare: empty query" ); |
988 | return false; |
989 | } |
990 | #ifdef QT_DEBUG_SQL |
991 | qDebug("\n QSqlQuery::prepare: %s" , query.toLocal8Bit().constData()); |
992 | #endif |
993 | return d->sqlResult->savePrepare(sqlquery: query); |
994 | } |
995 | |
996 | /*! |
997 | Executes a previously prepared SQL query. Returns \c true if the query |
998 | executed successfully; otherwise returns \c false. |
999 | |
1000 | Note that the last error for this query is reset when exec() is |
1001 | called. |
1002 | |
1003 | \sa prepare(), bindValue(), addBindValue(), boundValue(), boundValues() |
1004 | */ |
1005 | bool QSqlQuery::exec() |
1006 | { |
1007 | #ifdef QT_DEBUG_SQL |
1008 | QElapsedTimer t; |
1009 | t.start(); |
1010 | #endif |
1011 | d->sqlResult->resetBindCount(); |
1012 | |
1013 | if (d->sqlResult->lastError().isValid()) |
1014 | d->sqlResult->setLastError(QSqlError()); |
1015 | |
1016 | bool retval = d->sqlResult->exec(); |
1017 | #ifdef QT_DEBUG_SQL |
1018 | qDebug().nospace() << "Executed prepared query (" << t.elapsed() << "ms, " |
1019 | << d->sqlResult->size() << " results, " << d->sqlResult->numRowsAffected() |
1020 | << " affected): " << d->sqlResult->lastQuery(); |
1021 | #endif |
1022 | return retval; |
1023 | } |
1024 | |
1025 | /*! \enum QSqlQuery::BatchExecutionMode |
1026 | |
1027 | \value ValuesAsRows - Updates multiple rows. Treats every entry in a QVariantList as a value for updating the next row. |
1028 | \value ValuesAsColumns - Updates a single row. Treats every entry in a QVariantList as a single value of an array type. |
1029 | */ |
1030 | |
1031 | /*! |
1032 | \since 4.2 |
1033 | |
1034 | Executes a previously prepared SQL query in a batch. All the bound |
1035 | parameters have to be lists of variants. If the database doesn't |
1036 | support batch executions, the driver will simulate it using |
1037 | conventional exec() calls. |
1038 | |
1039 | Returns \c true if the query is executed successfully; otherwise |
1040 | returns \c false. |
1041 | |
1042 | Example: |
1043 | |
1044 | \snippet code/src_sql_kernel_qsqlquery.cpp 2 |
1045 | |
1046 | The example above inserts four new rows into \c myTable: |
1047 | |
1048 | \snippet code/src_sql_kernel_qsqlquery_snippet.cpp 3 |
1049 | |
1050 | To bind NULL values, a null QVariant of the relevant type has to be |
1051 | added to the bound QVariantList; for example, \c |
1052 | {QVariant(QMetaType::fromType<QString>())} should be used if you are |
1053 | using strings. |
1054 | |
1055 | \note Every bound QVariantList must contain the same amount of |
1056 | variants. |
1057 | |
1058 | \note The type of the QVariants in a list must not change. For |
1059 | example, you cannot mix integer and string variants within a |
1060 | QVariantList. |
1061 | |
1062 | The \a mode parameter indicates how the bound QVariantList will be |
1063 | interpreted. If \a mode is \c ValuesAsRows, every variant within |
1064 | the QVariantList will be interpreted as a value for a new row. \c |
1065 | ValuesAsColumns is a special case for the Oracle driver. In this |
1066 | mode, every entry within a QVariantList will be interpreted as |
1067 | array-value for an IN or OUT value within a stored procedure. Note |
1068 | that this will only work if the IN or OUT value is a table-type |
1069 | consisting of only one column of a basic type, for example \c{TYPE |
1070 | myType IS TABLE OF VARCHAR(64) INDEX BY BINARY_INTEGER;} |
1071 | |
1072 | \sa prepare(), bindValue(), addBindValue() |
1073 | */ |
1074 | bool QSqlQuery::execBatch(BatchExecutionMode mode) |
1075 | { |
1076 | d->sqlResult->resetBindCount(); |
1077 | return d->sqlResult->execBatch(arrayBind: mode == ValuesAsColumns); |
1078 | } |
1079 | |
1080 | /*! |
1081 | Set the placeholder \a placeholder to be bound to value \a val in |
1082 | the prepared statement. Note that the placeholder mark (e.g \c{:}) |
1083 | must be included when specifying the placeholder name. If \a |
1084 | paramType is QSql::Out or QSql::InOut, the placeholder will be |
1085 | overwritten with data from the database after the exec() call. |
1086 | In this case, sufficient space must be pre-allocated to store |
1087 | the result into. |
1088 | |
1089 | To bind a NULL value, use a null QVariant; for example, use |
1090 | \c {QVariant(QMetaType::fromType<QString>())} if you are binding a string. |
1091 | |
1092 | \sa addBindValue(), prepare(), exec(), boundValue(), boundValues() |
1093 | */ |
1094 | void QSqlQuery::bindValue(const QString& placeholder, const QVariant& val, |
1095 | QSql::ParamType paramType |
1096 | ) |
1097 | { |
1098 | d->sqlResult->bindValue(placeholder, val, type: paramType); |
1099 | } |
1100 | |
1101 | /*! |
1102 | Set the placeholder in position \a pos to be bound to value \a val |
1103 | in the prepared statement. Field numbering starts at 0. If \a |
1104 | paramType is QSql::Out or QSql::InOut, the placeholder will be |
1105 | overwritten with data from the database after the exec() call. |
1106 | */ |
1107 | void QSqlQuery::bindValue(int pos, const QVariant& val, QSql::ParamType paramType) |
1108 | { |
1109 | d->sqlResult->bindValue(pos, val, type: paramType); |
1110 | } |
1111 | |
1112 | /*! |
1113 | Adds the value \a val to the list of values when using positional |
1114 | value binding. The order of the addBindValue() calls determines |
1115 | which placeholder a value will be bound to in the prepared query. |
1116 | If \a paramType is QSql::Out or QSql::InOut, the placeholder will be |
1117 | overwritten with data from the database after the exec() call. |
1118 | |
1119 | To bind a NULL value, use a null QVariant; for example, use \c |
1120 | {QVariant(QMetaType::fromType<QString>())} if you are binding a string. |
1121 | |
1122 | \sa bindValue(), prepare(), exec(), boundValue(), boundValues() |
1123 | */ |
1124 | void QSqlQuery::addBindValue(const QVariant& val, QSql::ParamType paramType) |
1125 | { |
1126 | d->sqlResult->addBindValue(val, type: paramType); |
1127 | } |
1128 | |
1129 | /*! |
1130 | Returns the value for the \a placeholder. |
1131 | |
1132 | \sa boundValues(), bindValue(), addBindValue() |
1133 | */ |
1134 | QVariant QSqlQuery::boundValue(const QString& placeholder) const |
1135 | { |
1136 | return d->sqlResult->boundValue(placeholder); |
1137 | } |
1138 | |
1139 | /*! |
1140 | Returns the value for the placeholder at position \a pos. |
1141 | \sa boundValues() |
1142 | */ |
1143 | QVariant QSqlQuery::boundValue(int pos) const |
1144 | { |
1145 | return d->sqlResult->boundValue(pos); |
1146 | } |
1147 | |
1148 | /*! |
1149 | \since 6.0 |
1150 | |
1151 | Returns a list of bound values. |
1152 | |
1153 | The order of the list is in binding order, irrespective of whether |
1154 | named or positional binding is used. |
1155 | |
1156 | The bound values can be examined in the following way: |
1157 | |
1158 | \snippet sqldatabase/sqldatabase.cpp 14 |
1159 | |
1160 | \sa boundValue(), bindValue(), addBindValue(), boundValueNames() |
1161 | */ |
1162 | |
1163 | QVariantList QSqlQuery::boundValues() const |
1164 | { |
1165 | const QVariantList values(d->sqlResult->boundValues()); |
1166 | return values; |
1167 | } |
1168 | |
1169 | /*! |
1170 | \since 6.6 |
1171 | |
1172 | Returns the names of all bound values. |
1173 | |
1174 | The order of the list is in binding order, irrespective of whether |
1175 | named or positional binding is used. |
1176 | |
1177 | \sa boundValues(), boundValueName() |
1178 | */ |
1179 | QStringList QSqlQuery::boundValueNames() const |
1180 | { |
1181 | return d->sqlResult->boundValueNames(); |
1182 | } |
1183 | |
1184 | /*! |
1185 | \since 6.6 |
1186 | |
1187 | Returns the bound value name at position \a pos. |
1188 | |
1189 | The order of the list is in binding order, irrespective of whether |
1190 | named or positional binding is used. |
1191 | |
1192 | \sa boundValueNames() |
1193 | */ |
1194 | QString QSqlQuery::boundValueName(int pos) const |
1195 | { |
1196 | return d->sqlResult->boundValueName(pos); |
1197 | } |
1198 | |
1199 | /*! |
1200 | Returns the last query that was successfully executed. |
1201 | |
1202 | In most cases this function returns the same string as lastQuery(). |
1203 | If a prepared query with placeholders is executed on a DBMS that |
1204 | does not support it, the preparation of this query is emulated. The |
1205 | placeholders in the original query are replaced with their bound |
1206 | values to form a new query. This function returns the modified |
1207 | query. It is mostly useful for debugging purposes. |
1208 | |
1209 | \sa lastQuery() |
1210 | */ |
1211 | QString QSqlQuery::executedQuery() const |
1212 | { |
1213 | return d->sqlResult->executedQuery(); |
1214 | } |
1215 | |
1216 | /*! |
1217 | Returns the object ID of the most recent inserted row if the |
1218 | database supports it. An invalid QVariant will be returned if the |
1219 | query did not insert any value or if the database does not report |
1220 | the id back. If more than one row was touched by the insert, the |
1221 | behavior is undefined. |
1222 | |
1223 | For MySQL databases the row's auto-increment field will be returned. |
1224 | |
1225 | \note For this function to work in PSQL, the table must |
1226 | contain OIDs, which may not have been created by default. Check the |
1227 | \c default_with_oids configuration variable to be sure. |
1228 | |
1229 | \sa QSqlDriver::hasFeature() |
1230 | */ |
1231 | QVariant QSqlQuery::lastInsertId() const |
1232 | { |
1233 | return d->sqlResult->lastInsertId(); |
1234 | } |
1235 | |
1236 | /*! |
1237 | |
1238 | Instruct the database driver to return numerical values with a |
1239 | precision specified by \a precisionPolicy. |
1240 | |
1241 | The Oracle driver, for example, can retrieve numerical values as |
1242 | strings to prevent the loss of precision. If high precision doesn't |
1243 | matter, use this method to increase execution speed by bypassing |
1244 | string conversions. |
1245 | |
1246 | Note: Drivers that don't support fetching numerical values with low |
1247 | precision will ignore the precision policy. You can use |
1248 | QSqlDriver::hasFeature() to find out whether a driver supports this |
1249 | feature. |
1250 | |
1251 | Note: Setting the precision policy doesn't affect the currently |
1252 | active query. Call \l{exec()}{exec(QString)} or prepare() in order |
1253 | to activate the policy. |
1254 | |
1255 | \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy() |
1256 | */ |
1257 | void QSqlQuery::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy) |
1258 | { |
1259 | d->sqlResult->setNumericalPrecisionPolicy(precisionPolicy); |
1260 | } |
1261 | |
1262 | /*! |
1263 | Returns the current precision policy. |
1264 | |
1265 | \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy() |
1266 | */ |
1267 | QSql::NumericalPrecisionPolicy QSqlQuery::numericalPrecisionPolicy() const |
1268 | { |
1269 | return d->sqlResult->numericalPrecisionPolicy(); |
1270 | } |
1271 | |
1272 | /*! |
1273 | \since 4.3.2 |
1274 | |
1275 | Instruct the database driver that no more data will be fetched from |
1276 | this query until it is re-executed. There is normally no need to |
1277 | call this function, but it may be helpful in order to free resources |
1278 | such as locks or cursors if you intend to re-use the query at a |
1279 | later time. |
1280 | |
1281 | Sets the query to inactive. Bound values retain their values. |
1282 | |
1283 | \sa prepare(), exec(), isActive() |
1284 | */ |
1285 | void QSqlQuery::finish() |
1286 | { |
1287 | if (isActive()) { |
1288 | d->sqlResult->setLastError(QSqlError()); |
1289 | d->sqlResult->setAt(QSql::BeforeFirstRow); |
1290 | d->sqlResult->detachFromResultSet(); |
1291 | d->sqlResult->setActive(false); |
1292 | } |
1293 | } |
1294 | |
1295 | /*! |
1296 | \since 4.4 |
1297 | |
1298 | Discards the current result set and navigates to the next if available. |
1299 | |
1300 | Some databases are capable of returning multiple result sets for |
1301 | stored procedures or SQL batches (a query strings that contains |
1302 | multiple statements). If multiple result sets are available after |
1303 | executing a query this function can be used to navigate to the next |
1304 | result set(s). |
1305 | |
1306 | If a new result set is available this function will return true. |
1307 | The query will be repositioned on an \e invalid record in the new |
1308 | result set and must be navigated to a valid record before data |
1309 | values can be retrieved. If a new result set isn't available the |
1310 | function returns \c false and the query is set to inactive. In any |
1311 | case the old result set will be discarded. |
1312 | |
1313 | When one of the statements is a non-select statement a count of |
1314 | affected rows may be available instead of a result set. |
1315 | |
1316 | Note that some databases, i.e. Microsoft SQL Server, requires |
1317 | non-scrollable cursors when working with multiple result sets. Some |
1318 | databases may execute all statements at once while others may delay |
1319 | the execution until the result set is actually accessed, and some |
1320 | databases may have restrictions on which statements are allowed to |
1321 | be used in a SQL batch. |
1322 | |
1323 | \sa QSqlDriver::hasFeature(), setForwardOnly(), next(), isSelect(), |
1324 | numRowsAffected(), isActive(), lastError() |
1325 | */ |
1326 | bool QSqlQuery::nextResult() |
1327 | { |
1328 | if (isActive()) |
1329 | return d->sqlResult->nextResult(); |
1330 | return false; |
1331 | } |
1332 | |
1333 | QT_END_NAMESPACE |
1334 | |