Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qsqlresult.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 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
// Qt-Security score:critical reason:data-parser
4
5
#
include
"qsqlresult.h"
6
7
#
include
"qlist.h"
8
#
include
"qsqldriver.h"
9
#
include
"qsqlerror.h"
10
#
include
"qsqlfield.h"
11
#
include
"qsqlrecord.h"
12
#
include
"qsqlresult_p.h"
13
#
include
"quuid.h"
14
#
include
"qvariant.h"
15
#
include
"qdatetime.h"
16
#
include
"private/qsqldriver_p.h"
17
18
QT_BEGIN_NAMESPACE
19
20
using
namespace
Qt::StringLiterals;
21
22
QString QSqlResultPrivate::holderAt(
int
index)
const
23
{
24
return
holders.size() > index ? holders.at(index).holderName : fieldSerial(index);
25
}
26
27
QString QSqlResultPrivate::fieldSerial(qsizetype i)
const
28
{
29
return
QString(
":%1"_L1
).arg(i);
30
}
31
32
static
bool
qIsAlnum
(QChar ch)
33
{
34
uint u = uint(ch.unicode());
35
// matches [a-zA-Z0-9_]
36
return
u -
'a'
< 26 || u -
'A'
< 26 || u -
'0'
< 10 || u ==
'_'
;
37
}
38
39
QString QSqlResultPrivate::positionalToNamedBinding(
const
QString &query)
const
40
{
41
if
(!positionalBindingEnabled)
42
return
query;
43
44
const
qsizetype n = query.size();
45
46
QString result;
47
result.reserve(n * 5 / 4);
48
QChar closingQuote;
49
qsizetype count = 0;
50
bool
ignoreBraces = (sqldriver->dbmsType() == QSqlDriver::PostgreSQL);
51
52
for
(qsizetype i = 0; i < n; ++i) {
53
QChar ch = query.at(i);
54
if
(!closingQuote.isNull()) {
55
if
(ch == closingQuote) {
56
if
(closingQuote == u']'
57
&& i + 1 < n && query.at(i + 1) == closingQuote) {
58
// consume the extra character. don't close.
59
++i;
60
result += ch;
61
}
else
{
62
closingQuote = QChar();
63
}
64
}
65
result += ch;
66
}
else
{
67
if
(ch == u'?') {
68
result += fieldSerial(count++);
69
}
else
{
70
if
(ch == u'\'' || ch == u'"' || ch == u'`')
71
closingQuote = ch;
72
else
if
(!ignoreBraces && ch == u'[')
73
closingQuote = u']';
74
result += ch;
75
}
76
}
77
}
78
result.squeeze();
79
return
result;
80
}
81
82
QString QSqlResultPrivate::namedToPositionalBinding(
const
QString &query)
83
{
84
// In the Interbase case if it is an EXECUTE BLOCK then it is up to the
85
// caller to make sure that it is not using named bindings for the wrong
86
// parts of the query since Interbase uses them literally
87
const
QSqlDriver::DbmsType dbmsType = sqldriver->dbmsType();
88
if
((dbmsType == QSqlDriver::Interbase || dbmsType == QSqlDriver::FirebirdSQL) &&
89
query.trimmed().startsWith(
"EXECUTE BLOCK"_L1
, Qt::CaseInsensitive))
90
return
query;
91
92
const
qsizetype n = query.size();
93
94
QString result;
95
result.reserve(n);
96
QChar closingQuote;
97
int
count = 0;
98
qsizetype i = 0;
99
bool
ignoreBraces = (sqldriver->dbmsType() == QSqlDriver::PostgreSQL);
100
101
while
(i < n) {
102
QChar ch = query.at(i);
103
if
(!closingQuote.isNull()) {
104
if
(ch == closingQuote) {
105
if
(closingQuote == u']'
106
&& i + 1 < n && query.at(i + 1) == closingQuote) {
107
// consume the extra character. don't close.
108
++i;
109
result += ch;
110
}
else
{
111
closingQuote = QChar();
112
}
113
}
114
result += ch;
115
++i;
116
}
else
{
117
if
(ch == u':'
118
&& (i == 0 || query.at(i - 1) != u':')
119
&& (i + 1 < n && qIsAlnum(query.at(i + 1)))) {
120
int
pos = i + 2;
121
while
(pos < n && qIsAlnum(query.at(pos)))
122
++pos;
123
// if question mark notation is not supported we have to use
124
// the native binding. fieldSerial() should be renamed
125
// to toNativeBinding() and used unconditionally here
126
if
(qmarkNotationSupported)
127
result += u'?';
128
else
129
result += fieldSerial(count);
130
QString holder(query.mid(i, pos - i));
131
indexes[holder].append(count++);
132
holders.append(QHolder(holder, i));
133
i = pos;
134
}
else
{
135
if
(ch == u'\'' || ch == u'"' || ch == u'`')
136
closingQuote = ch;
137
else
if
(!ignoreBraces && ch == u'[')
138
closingQuote = u']';
139
result += ch;
140
++i;
141
}
142
}
143
}
144
result.squeeze();
145
values.resize(holders.size());
146
return
result;
147
}
148
149
/*!
150
\class QSqlResult
151
\brief The QSqlResult class provides an abstract interface for
152
accessing data from specific SQL databases.
153
154
\ingroup database
155
\inmodule QtSql
156
157
Normally, you would use QSqlQuery instead of QSqlResult, since
158
QSqlQuery provides a generic wrapper for database-specific
159
implementations of QSqlResult.
160
161
If you are implementing your own SQL driver (by subclassing
162
QSqlDriver), you will need to provide your own QSqlResult
163
subclass that implements all the pure virtual functions and other
164
virtual functions that you need.
165
166
\sa QSqlDriver
167
*/
168
169
/*!
170
\enum QSqlResult::BindingSyntax
171
172
This enum type specifies the different syntaxes for specifying
173
placeholders in prepared queries.
174
175
\value PositionalBinding Use the ODBC-style positional syntax, with "?" as placeholders.
176
\value NamedBinding Use the Oracle-style syntax with named placeholders (e.g., ":id")
177
178
\sa bindingSyntax()
179
*/
180
181
/*!
182
\enum QSqlResult::VirtualHookOperation
183
\internal
184
*/
185
186
/*!
187
Creates a QSqlResult using database driver \a db. The object is
188
initialized to an inactive state.
189
190
\sa isActive(), driver()
191
*/
192
193
QSqlResult::QSqlResult(
const
QSqlDriver *db)
194
{
195
d_ptr =
new
QSqlResultPrivate(
this
, db);
196
Q_D(QSqlResult);
197
if
(d->sqldriver)
198
setNumericalPrecisionPolicy(d->sqldriver->numericalPrecisionPolicy());
199
}
200
201
/*! \internal
202
*/
203
QSqlResult::QSqlResult(QSqlResultPrivate &dd)
204
: d_ptr(&dd)
205
{
206
Q_D(QSqlResult);
207
if
(d->sqldriver)
208
setNumericalPrecisionPolicy(d->sqldriver->numericalPrecisionPolicy());
209
}
210
211
/*!
212
Destroys the object and frees any allocated resources.
213
*/
214
215
QSqlResult::~QSqlResult()
216
{
217
Q_D(QSqlResult);
218
delete
d;
219
}
220
221
/*!
222
Sets the current query for the result to \a query. You must call
223
reset() to execute the query on the database.
224
225
\sa reset(), lastQuery()
226
*/
227
228
void
QSqlResult::setQuery(
const
QString& query)
229
{
230
Q_D(QSqlResult);
231
d->sql = query;
232
}
233
234
/*!
235
Returns the current SQL query text, or an empty string if there
236
isn't one.
237
238
\sa setQuery()
239
*/
240
241
QString QSqlResult::lastQuery()
const
242
{
243
Q_D(
const
QSqlResult);
244
return
d->sql;
245
}
246
247
/*!
248
Returns the current (zero-based) row position of the result. May
249
return the special values QSql::BeforeFirstRow or
250
QSql::AfterLastRow.
251
252
\sa setAt(), isValid()
253
*/
254
int
QSqlResult::at()
const
255
{
256
Q_D(
const
QSqlResult);
257
return
d->idx;
258
}
259
260
261
/*!
262
Returns \c true if the result is positioned on a valid record (that
263
is, the result is not positioned before the first or after the
264
last record); otherwise returns \c false.
265
266
\sa at()
267
*/
268
269
bool
QSqlResult::isValid()
const
270
{
271
Q_D(
const
QSqlResult);
272
return
d->idx != QSql::BeforeFirstRow && d->idx != QSql::AfterLastRow;
273
}
274
275
/*!
276
\fn bool QSqlResult::isNull(int index)
277
278
Returns \c true if the field at position \a index in the current row
279
is null; otherwise returns \c false.
280
*/
281
282
/*!
283
Returns \c true if the result has records to be retrieved; otherwise
284
returns \c false.
285
*/
286
287
bool
QSqlResult::isActive()
const
288
{
289
Q_D(
const
QSqlResult);
290
return
d->active;
291
}
292
293
/*!
294
This function is provided for derived classes to set the
295
internal (zero-based) row position to \a index.
296
297
\sa at()
298
*/
299
300
void
QSqlResult::setAt(
int
index)
301
{
302
Q_D(QSqlResult);
303
d->idx = index;
304
}
305
306
307
/*!
308
This function is provided for derived classes to indicate whether
309
or not the current statement is a SQL \c SELECT statement. The \a
310
select parameter should be true if the statement is a \c SELECT
311
statement; otherwise it should be false.
312
313
\sa isSelect()
314
*/
315
316
void
QSqlResult::setSelect(
bool
select)
317
{
318
Q_D(QSqlResult);
319
d->isSel = select;
320
}
321
322
/*!
323
Returns \c true if the current result is from a \c SELECT statement;
324
otherwise returns \c false.
325
326
\sa setSelect()
327
*/
328
329
bool
QSqlResult::isSelect()
const
330
{
331
Q_D(
const
QSqlResult);
332
return
d->isSel;
333
}
334
335
/*!
336
Returns the driver associated with the result. This is the object
337
that was passed to the constructor.
338
*/
339
340
const
QSqlDriver *QSqlResult::driver()
const
341
{
342
Q_D(
const
QSqlResult);
343
return
d->sqldriver;
344
}
345
346
347
/*!
348
This function is provided for derived classes to set the internal
349
active state to \a active.
350
351
\sa isActive()
352
*/
353
354
void
QSqlResult::setActive(
bool
active)
355
{
356
Q_D(QSqlResult);
357
if
(active)
358
d->executedQuery = d->sql;
359
360
d->active = active;
361
}
362
363
/*!
364
This function is provided for derived classes to set the last
365
error to \a error.
366
367
\sa lastError()
368
*/
369
370
void
QSqlResult::setLastError(
const
QSqlError &error)
371
{
372
Q_D(QSqlResult);
373
d->error = error;
374
}
375
376
377
/*!
378
Returns the last error associated with the result.
379
*/
380
381
QSqlError QSqlResult::lastError()
const
382
{
383
Q_D(
const
QSqlResult);
384
return
d->error;
385
}
386
387
/*!
388
\fn int QSqlResult::size()
389
390
Returns the size of the \c SELECT result, or -1 if it cannot be
391
determined or if the query is not a \c SELECT statement.
392
393
\sa numRowsAffected()
394
*/
395
396
/*!
397
\fn int QSqlResult::numRowsAffected()
398
399
Returns the number of rows affected by the last query executed, or
400
-1 if it cannot be determined or if the query is a \c SELECT
401
statement.
402
403
\sa size()
404
*/
405
406
/*!
407
\fn QVariant QSqlResult::data(int index)
408
409
Returns the data for field \a index in the current row as
410
a QVariant. This function is only called if the result is in
411
an active state and is positioned on a valid record and \a index is
412
non-negative. Derived classes must reimplement this function and
413
return the value of field \a index, or QVariant() if it cannot be
414
determined.
415
*/
416
417
/*!
418
\fn bool QSqlResult::reset(const QString &query)
419
420
Sets the result to use the SQL statement \a query for subsequent
421
data retrieval.
422
423
Derived classes must reimplement this function and apply the \a
424
query to the database. This function is only called after the
425
result is set to an inactive state and is positioned before the
426
first record of the new result. Derived classes should return
427
true if the query was successful and ready to be used, or false
428
otherwise.
429
430
\sa setQuery()
431
*/
432
433
/*!
434
\fn bool QSqlResult::fetch(int index)
435
436
Positions the result to an arbitrary (zero-based) row \a index.
437
438
This function is only called if the result is in an active state.
439
Derived classes must reimplement this function and position the
440
result to the row \a index, and call setAt() with an appropriate
441
value. Return true to indicate success, or false to signify
442
failure.
443
444
\sa isActive(), fetchFirst(), fetchLast(), fetchNext(), fetchPrevious()
445
*/
446
447
/*!
448
\fn bool QSqlResult::fetchFirst()
449
450
Positions the result to the first record (row 0) in the result.
451
452
This function is only called if the result is in an active state.
453
Derived classes must reimplement this function and position the
454
result to the first record, and call setAt() with an appropriate
455
value. Return true to indicate success, or false to signify
456
failure.
457
458
\sa fetch(), fetchLast()
459
*/
460
461
/*!
462
\fn bool QSqlResult::fetchLast()
463
464
Positions the result to the last record (last row) in the result.
465
466
This function is only called if the result is in an active state.
467
Derived classes must reimplement this function and position the
468
result to the last record, and call setAt() with an appropriate
469
value. Return true to indicate success, or false to signify
470
failure.
471
472
\sa fetch(), fetchFirst()
473
*/
474
475
/*!
476
Positions the result to the next available record (row) in the
477
result.
478
479
This function is only called if the result is in an active
480
state. The default implementation calls fetch() with the next
481
index. Derived classes can reimplement this function and position
482
the result to the next record in some other way, and call setAt()
483
with an appropriate value. Return true to indicate success, or
484
false to signify failure.
485
486
\sa fetch(), fetchPrevious()
487
*/
488
489
bool
QSqlResult::fetchNext()
490
{
491
return
fetch(at() + 1);
492
}
493
494
/*!
495
Positions the result to the previous record (row) in the result.
496
497
This function is only called if the result is in an active state.
498
The default implementation calls fetch() with the previous index.
499
Derived classes can reimplement this function and position the
500
result to the next record in some other way, and call setAt()
501
with an appropriate value. Return true to indicate success, or
502
false to signify failure.
503
*/
504
505
bool
QSqlResult::fetchPrevious()
506
{
507
return
fetch(at() - 1);
508
}
509
510
/*!
511
Returns \c true if you can only scroll forward through the result
512
set; otherwise returns \c false.
513
514
\sa setForwardOnly()
515
*/
516
bool
QSqlResult::isForwardOnly()
const
517
{
518
Q_D(
const
QSqlResult);
519
return
d->forwardOnly;
520
}
521
522
/*!
523
Sets forward only mode to \a forward. If \a forward is true, only
524
fetchNext() is allowed for navigating the results. Forward only
525
mode needs much less memory since results do not have to be
526
cached. By default, this feature is disabled.
527
528
Setting forward only to false is a suggestion to the database engine,
529
which has the final say on whether a result set is forward only or
530
scrollable. isForwardOnly() will always return the correct status of
531
the result set.
532
533
\note Calling setForwardOnly after execution of the query will result
534
in unexpected results at best, and crashes at worst.
535
536
\note To make sure the forward-only query completed successfully,
537
the application should check lastError() for an error not only after
538
executing the query, but also after navigating the query results.
539
540
\warning PostgreSQL: While navigating the query results in forward-only
541
mode, do not execute any other SQL command on the same database
542
connection. This will cause the query results to be lost.
543
544
\sa isForwardOnly(), fetchNext(), QSqlQuery::setForwardOnly()
545
*/
546
void
QSqlResult::setForwardOnly(
bool
forward)
547
{
548
Q_D(QSqlResult);
549
d->forwardOnly = forward;
550
}
551
552
/*!
553
Prepares the given \a query, using the underlying database
554
functionality where possible. Returns \c true if the query is
555
prepared successfully; otherwise returns \c false.
556
557
Note: This method should have been called "safePrepare()".
558
559
\sa prepare()
560
*/
561
bool
QSqlResult::savePrepare(
const
QString& query)
562
{
563
Q_D(QSqlResult);
564
if
(!driver())
565
return
false
;
566
d->clear();
567
d->sql = query;
568
if
(!driver()->hasFeature(QSqlDriver::PreparedQueries))
569
return
prepare(query);
570
571
// parse the query to memorize parameter location
572
d->executedQuery = d->namedToPositionalBinding(query);
573
574
if
(driver()->hasFeature(QSqlDriver::NamedPlaceholders))
575
d->executedQuery = d->positionalToNamedBinding(query);
576
577
return
prepare(d->executedQuery);
578
}
579
580
/*!
581
Prepares the given \a query for execution; the query will normally
582
use placeholders so that it can be executed repeatedly. Returns
583
true if the query is prepared successfully; otherwise returns \c false.
584
585
\sa exec()
586
*/
587
bool
QSqlResult::prepare(
const
QString& query)
588
{
589
Q_D(QSqlResult);
590
d->sql = query;
591
if
(d->holders.isEmpty()) {
592
// parse the query to memorize parameter location
593
d->namedToPositionalBinding(query);
594
}
595
return
true
;
// fake prepares should always succeed
596
}
597
598
bool
QSqlResultPrivate::isVariantNull(
const
QVariant &variant)
599
{
600
if
(variant.isNull())
601
return
true
;
602
603
switch
(variant.typeId()) {
604
case
qMetaTypeId<QString>():
605
return
static_cast
<
const
QString*>(variant.constData())->isNull();
606
case
qMetaTypeId<QByteArray>():
607
return
static_cast
<
const
QByteArray*>(variant.constData())->isNull();
608
case
qMetaTypeId<QDateTime>():
609
// We treat invalid date-time as null, since its ISODate would be empty.
610
return
!
static_cast
<
const
QDateTime*>(variant.constData())->isValid();
611
case
qMetaTypeId<QDate>():
612
return
static_cast
<
const
QDate*>(variant.constData())->isNull();
613
case
qMetaTypeId<QTime>():
614
// As for QDateTime, QTime can be invalid without being null.
615
return
!
static_cast
<
const
QTime*>(variant.constData())->isValid();
616
case
qMetaTypeId<QUuid>():
617
return
static_cast
<
const
QUuid*>(variant.constData())->isNull();
618
default
:
619
break
;
620
}
621
622
return
false
;
623
}
624
625
/*!
626
Executes the query, returning true if successful; otherwise returns
627
false.
628
629
\sa prepare()
630
*/
631
bool
QSqlResult::exec()
632
{
633
Q_D(QSqlResult);
634
bool
ret;
635
// fake preparation - just replace the placeholders..
636
QString query = lastQuery();
637
if
(d->binds == NamedBinding) {
638
for
(qsizetype i = d->holders.size() - 1; i >= 0; --i) {
639
const
QString &holder = d->holders.at(i).holderName;
640
const
QVariant val = d->values.value(d->indexes.value(holder).value(0,-1));
641
QSqlField f(
""_L1
, val.metaType());
642
if
(QSqlResultPrivate::isVariantNull(val))
643
f.setValue(QVariant());
644
else
645
f.setValue(val);
646
query = query.replace(d->holders.at(i).holderPos,
647
holder.size(), driver()->formatValue(f));
648
}
649
}
else
{
650
qsizetype i = 0;
651
for
(
const
QVariant &var : std::as_const(d->values)) {
652
i = query.indexOf(u'?', i);
653
if
(i == -1)
654
continue
;
655
QSqlField f(
""_L1
, var.metaType());
656
if
(QSqlResultPrivate::isVariantNull(var))
657
f.clear();
658
else
659
f.setValue(var);
660
const
QString val = driver()->formatValue(f);
661
query = query.replace(i, 1, val);
662
i += val.size();
663
}
664
}
665
666
// have to retain the original query with placeholders
667
QString orig = lastQuery();
668
ret = reset(query);
669
d->executedQuery = query;
670
setQuery(orig);
671
d->resetBindCount();
672
return
ret;
673
}
674
675
/*!
676
Binds the value \a val of parameter type \a paramType to position \a index
677
in the current record (row).
678
679
\sa addBindValue()
680
*/
681
void
QSqlResult::bindValue(
int
index,
const
QVariant& val, QSql::ParamType paramType)
682
{
683
Q_D(QSqlResult);
684
d->binds = PositionalBinding;
685
QList<
int
> &indexes = d->indexes[d->fieldSerial(index)];
686
if
(!indexes.contains(index))
687
indexes.append(index);
688
if
(d->values.size() <= index)
689
d->values.resize(index + 1);
690
d->values[index] = val;
691
if
(paramType != QSql::In || !d->types.isEmpty())
692
d->types[index] = paramType;
693
}
694
695
/*!
696
\overload
697
698
Binds the value \a val of parameter type \a paramType to the \a
699
placeholder name in the current record (row).
700
701
\note Binding an undefined placeholder will result in undefined behavior.
702
703
\sa QSqlQuery::bindValue()
704
*/
705
void
QSqlResult::bindValue(
const
QString& placeholder,
const
QVariant& val,
706
QSql::ParamType paramType)
707
{
708
Q_D(QSqlResult);
709
d->binds = NamedBinding;
710
// if the index has already been set when doing emulated named
711
// bindings - don't reset it
712
const
QList<
int
> indexes = d->indexes.value(placeholder);
713
for
(
int
idx : indexes) {
714
if
(d->values.size() <= idx)
715
d->values.resize(idx + 1);
716
d->values[idx] = val;
717
if
(paramType != QSql::In || !d->types.isEmpty())
718
d->types[idx] = paramType;
719
}
720
}
721
722
/*!
723
Binds the value \a val of parameter type \a paramType to the next
724
available position in the current record (row).
725
726
\sa bindValue()
727
*/
728
void
QSqlResult::addBindValue(
const
QVariant& val, QSql::ParamType paramType)
729
{
730
Q_D(QSqlResult);
731
d->binds = PositionalBinding;
732
bindValue(d->bindCount, val, paramType);
733
++d->bindCount;
734
}
735
736
/*!
737
Returns the value bound at position \a index in the current record
738
(row).
739
740
\sa bindValue(), boundValues()
741
*/
742
QVariant QSqlResult::boundValue(
int
index)
const
743
{
744
Q_D(
const
QSqlResult);
745
return
d->values.value(index);
746
}
747
748
/*!
749
\overload
750
751
Returns the value bound by the given \a placeholder name in the
752
current record (row).
753
754
\sa bindValueType()
755
*/
756
QVariant QSqlResult::boundValue(
const
QString& placeholder)
const
757
{
758
Q_D(
const
QSqlResult);
759
const
QList<
int
> indexes = d->indexes.value(placeholder);
760
return
d->values.value(indexes.value(0,-1));
761
}
762
763
/*!
764
Returns the parameter type for the value bound at position \a index.
765
766
\sa boundValue()
767
*/
768
QSql::ParamType QSqlResult::bindValueType(
int
index)
const
769
{
770
Q_D(
const
QSqlResult);
771
return
d->types.value(index, QSql::In);
772
}
773
774
/*!
775
\overload
776
777
Returns the parameter type for the value bound with the given \a
778
placeholder name.
779
*/
780
QSql::ParamType QSqlResult::bindValueType(
const
QString& placeholder)
const
781
{
782
Q_D(
const
QSqlResult);
783
return
d->types.value(d->indexes.value(placeholder).value(0,-1), QSql::In);
784
}
785
786
/*!
787
Returns the number of bound values in the result.
788
789
\sa boundValues()
790
*/
791
int
QSqlResult::boundValueCount()
const
792
{
793
Q_D(
const
QSqlResult);
794
return
d->values.size();
795
}
796
797
/*!
798
Returns a list of the result's bound values for the current
799
record (row).
800
801
\sa boundValueCount()
802
*/
803
QVariantList QSqlResult::boundValues(QT6_IMPL_NEW_OVERLOAD)
const
804
{
805
Q_D(
const
QSqlResult);
806
return
d->values;
807
}
808
809
/*!
810
\overload
811
812
Returns a mutable reference to the list of the result's bound values
813
for the current record (row).
814
815
\sa boundValueCount()
816
*/
817
QVariantList &QSqlResult::boundValues(QT6_IMPL_NEW_OVERLOAD)
818
{
819
Q_D(QSqlResult);
820
return
d->values;
821
}
822
823
824
/*!
825
Returns the binding syntax used by prepared queries.
826
*/
827
QSqlResult::BindingSyntax QSqlResult::bindingSyntax()
const
828
{
829
Q_D(
const
QSqlResult);
830
return
d->binds;
831
}
832
833
/*!
834
Clears the entire result set and releases any associated
835
resources.
836
*/
837
void
QSqlResult::clear()
838
{
839
Q_D(QSqlResult);
840
d->clear();
841
}
842
843
/*!
844
Returns the query that was actually executed. This may differ from
845
the query that was passed, for example if bound values were used
846
with a prepared query and the underlying database doesn't support
847
prepared queries.
848
849
\sa exec(), setQuery()
850
*/
851
QString QSqlResult::executedQuery()
const
852
{
853
Q_D(
const
QSqlResult);
854
return
d->executedQuery;
855
}
856
857
/*!
858
Resets the number of bind parameters.
859
*/
860
void
QSqlResult::resetBindCount()
861
{
862
Q_D(QSqlResult);
863
d->resetBindCount();
864
}
865
866
/*!
867
Returns the names of all bound values.
868
869
\sa boundValue(), boundValueName()
870
*/
871
QStringList QSqlResult::boundValueNames()
const
872
{
873
Q_D(
const
QSqlResult);
874
QList<QString> ret;
875
for
(
const
QHolder &holder : std::as_const(d->holders))
876
ret.push_back(holder.holderName);
877
return
ret;
878
}
879
880
/*!
881
Returns the name of the bound value at position \a index in the
882
current record (row).
883
884
\sa boundValue(), boundValueNames()
885
*/
886
QString QSqlResult::boundValueName(
int
index)
const
887
{
888
Q_D(
const
QSqlResult);
889
return
d->holderAt(index);
890
}
891
892
/*!
893
Returns \c true if at least one of the query's bound values is a \c
894
QSql::Out or a QSql::InOut; otherwise returns \c false.
895
896
\sa bindValueType()
897
*/
898
bool
QSqlResult::hasOutValues()
const
899
{
900
Q_D(
const
QSqlResult);
901
if
(d->types.isEmpty())
902
return
false
;
903
QHash<
int
, QSql::ParamType>::ConstIterator it;
904
for
(it = d->types.constBegin(); it != d->types.constEnd(); ++it) {
905
if
(it.value() != QSql::In)
906
return
true
;
907
}
908
return
false
;
909
}
910
911
/*!
912
Returns the current record if the query is active; otherwise
913
returns an empty QSqlRecord.
914
915
The default implementation always returns an empty QSqlRecord.
916
917
\sa isActive()
918
*/
919
QSqlRecord QSqlResult::record()
const
920
{
921
return
QSqlRecord();
922
}
923
924
/*!
925
Returns the object ID of the most recent inserted row if the
926
database supports it.
927
An invalid QVariant will be returned if the query did not
928
insert any value or if the database does not report the id back.
929
If more than one row was touched by the insert, the behavior is
930
undefined.
931
932
Note that for Oracle databases the row's ROWID will be returned,
933
while for MySQL databases the row's auto-increment field will
934
be returned.
935
936
\sa QSqlDriver::hasFeature()
937
*/
938
QVariant QSqlResult::lastInsertId()
const
939
{
940
return
QVariant();
941
}
942
943
/*! \internal
944
*/
945
void
QSqlResult::virtual_hook(
int
,
void
*)
946
{
947
}
948
949
/*! \internal
950
Executes a prepared query in batch mode if the driver supports it,
951
otherwise emulates a batch execution using bindValue() and exec().
952
QSqlDriver::hasFeature() can be used to find out whether a driver
953
supports batch execution.
954
955
Batch execution can be faster for large amounts of data since it
956
reduces network roundtrips.
957
958
For batch executions, bound values have to be provided as lists
959
of variants (QVariantList).
960
961
Each list must contain values of the same type. All lists must
962
contain equal amount of values (rows).
963
964
NULL values are passed in as typed QVariants, for example
965
\c {QVariant(QMetaType::fromType<int>())} for an integer NULL value.
966
967
Example:
968
969
\snippet code/src_sql_kernel_qsqlresult.cpp 0
970
971
Here, we insert two rows into a SQL table, with each row containing three values.
972
973
\sa exec(), QSqlDriver::hasFeature()
974
*/
975
bool
QSqlResult::execBatch(
bool
arrayBind)
976
{
977
Q_UNUSED(arrayBind);
978
Q_D(QSqlResult);
979
980
const
QList<QVariant> values = d->values;
981
if
(values.size() == 0)
982
return
false
;
983
const
qsizetype batchCount = values.at(0).toList().size();
984
const
qsizetype valueCount = values.size();
985
for
(qsizetype i = 0; i < batchCount; ++i) {
986
for
(qsizetype j = 0; j < valueCount; ++j)
987
bindValue(j, values.at(j).toList().at(i), QSql::In);
988
if
(!exec())
989
return
false
;
990
}
991
return
true
;
992
}
993
994
/*! \internal
995
*/
996
void
QSqlResult::detachFromResultSet()
997
{
998
}
999
1000
/*! \internal
1001
*/
1002
void
QSqlResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy)
1003
{
1004
Q_D(QSqlResult);
1005
d->precisionPolicy = policy;
1006
}
1007
1008
/*! \internal
1009
*/
1010
QSql::NumericalPrecisionPolicy QSqlResult::numericalPrecisionPolicy()
const
1011
{
1012
Q_D(
const
QSqlResult);
1013
return
d->precisionPolicy;
1014
}
1015
1016
/*! \internal
1017
*/
1018
void
QSqlResult::setPositionalBindingEnabled(
bool
enable)
1019
{
1020
Q_D(QSqlResult);
1021
d->positionalBindingEnabled = enable;
1022
}
1023
1024
/*! \internal
1025
*/
1026
bool
QSqlResult::isPositionalBindingEnabled()
const
1027
{
1028
Q_D(
const
QSqlResult);
1029
return
d->positionalBindingEnabled;
1030
}
1031
1032
1033
/*! \internal
1034
*/
1035
bool
QSqlResult::nextResult()
1036
{
1037
return
false
;
1038
}
1039
1040
/*!
1041
Returns the low-level database handle for this result set
1042
wrapped in a QVariant or an invalid QVariant if there is no handle.
1043
1044
\warning Use this with uttermost care and only if you know what you're doing.
1045
1046
\warning The handle returned here can become a stale pointer if the result
1047
is modified (for example, if you clear it).
1048
1049
\warning The handle can be NULL if the result was not executed yet.
1050
1051
\warning PostgreSQL: in forward-only mode, the handle of QSqlResult can change
1052
after calling fetch(), fetchFirst(), fetchLast(), fetchNext(), fetchPrevious(),
1053
nextResult().
1054
1055
The handle returned here is database-dependent, you should query the type
1056
name of the variant before accessing it.
1057
1058
This example retrieves the handle for a sqlite result:
1059
1060
\snippet code/src_sql_kernel_qsqlresult.cpp 1
1061
1062
This snippet returns the handle for PostgreSQL or MySQL:
1063
1064
\snippet code/src_sql_kernel_qsqlresult_snippet.cpp 2
1065
1066
\sa QSqlDriver::handle()
1067
*/
1068
QVariant QSqlResult::handle()
const
1069
{
1070
return
QVariant();
1071
}
1072
1073
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qIsAlnum
static bool qIsAlnum(QChar ch)
Definition
qsqlresult.cpp:32
qtbase
src
sql
kernel
qsqlresult.cpp
Generated on
for Qt by
1.18.0