?? qsqlquery.cpp
字號:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtSql module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qsqlquery.h"//#define QT_DEBUG_SQL#include "qatomic.h"#include "qsqlrecord.h"#include "qsqlresult.h"#include "qsqldriver.h"#include "qsqldatabase.h"#include "private/qsqlnulldriver_p.h"#include "qvector.h"#include "qmap.h"class QSqlQueryPrivate{public: QSqlQueryPrivate(QSqlResult* result); ~QSqlQueryPrivate(); QAtomic ref; QSqlResult* sqlResult; Q_GLOBAL_STATIC_WITH_ARGS(QSqlQueryPrivate, nullQueryPrivate, (0)) Q_GLOBAL_STATIC(QSqlNullDriver, nullDriver) Q_GLOBAL_STATIC_WITH_ARGS(QSqlNullResult, nullResult, (nullDriver())) static QSqlQueryPrivate* shared_null();};QSqlQueryPrivate* QSqlQueryPrivate::shared_null(){ QSqlQueryPrivate *null = nullQueryPrivate(); null->ref.ref(); return null;}/*!\internal*/QSqlQueryPrivate::QSqlQueryPrivate(QSqlResult* result): ref(1), sqlResult(result){ if (!sqlResult) sqlResult = nullResult();}QSqlQueryPrivate::~QSqlQueryPrivate(){ QSqlResult *nr = nullResult(); if (!nr || sqlResult == nr) return; delete sqlResult;}/*! \class QSqlQuery \brief The QSqlQuery class provides a means of executing and manipulating SQL statements. \ingroup database \ingroup shared \mainclass \module sql QSqlQuery encapsulates the functionality involved in creating, navigating and retrieving data from SQL queries which are executed on a \l QSqlDatabase. It can be used to execute DML (data manipulation language) statements, such as \c SELECT, \c INSERT, \c UPDATE and \c DELETE, as well as DDL (data definition language) statements, such as \c{CREATE} \c{TABLE}. It can also be used to execute database-specific commands which are not standard SQL (e.g. \c{SET DATESTYLE=ISO} for PostgreSQL). Successfully executed SQL statements set the query's state to active; isActive() then returns true. Otherwise the query's state is set to inactive. In either case, when executing a new SQL statement, the query is positioned on an invalid record; an active query must be navigated to a valid record (so that isValid() returns true) before values can be retrieved. \target QSqlQuery examples Navigating records is performed with the following functions: \list \o next() \o previous() \o first() \o last() \o seek() \endlist These functions allow the programmer to move forward, backward or arbitrarily through the records returned by the query. If you only need to move forward through the results, e.g. using next() or using seek() with a positive offset, you can use setForwardOnly() and save a significant amount of memory overhead. Once an active query is positioned on a valid record, data can be retrieved using value(). All data is transferred from the SQL backend using QVariants. For example: \quotefromfile snippets/sqldatabase/sqldatabase.cpp \skipto typical loop \skipto QSqlQuery query \printuntil } To access the data returned by a query, use value(int). Each field in the data returned by a \c SELECT statement is accessed by passing the field's position in the statement, starting from 0. This makes using \c{SELECT *} queries inadvisable because the order of the fields returned is indeterminate. For the sake of efficiency, there are no functions to access a field by name (unless you use prepared queries with names, as explained below). To convert a field name into an index, use record().\l{QSqlRecord::indexOf()}{indexOf()}, for example: \skipto field index lookup \skipto QSqlQuery query \printuntil } QSqlQuery supports prepared query execution and the binding of parameter values to placeholders. Some databases don't support these features, so for those, Qt emulates the required functionality. For example, the Oracle and ODBC drivers have proper prepared query support, and Qt makes use of it; but for databases that don't have this support, Qt implements the feature itself, e.g. by replacing placeholders with actual values when a query is executed. Use numRowsAffected() to find out how many rows were affected by a non-\c SELECT query, and size() to find how many were retrieved by a \c SELECT. Oracle databases identify placeholders by using a colon-name syntax, e.g \c{:name}. ODBC simply uses \c ? characters. Qt supports both syntaxes, with the restriction that you can't mix them in the same query. You can retrieve the values of all the fields in a single variable (a map) using boundValues(). \section1 Approaches to Binding Values Below we present the same example using each of the four different binding approaches, as well as one example of binding values to a stored procedure. \bold{Named binding using named placeholders:} \skipto named with named \skipto QSqlQuery \printuntil exec() \bold{Positional binding using named placeholders:} \skipto positional with named \skipto QSqlQuery \printuntil exec() \bold{Binding values using positional placeholders (version 1):} \skipto positional 1 \skipto QSqlQuery \printuntil exec() \bold{Binding values using positional placeholders (version 2):} \skipto positional 2 \skipto QSqlQuery \printuntil exec() \bold{Binding values to a stored procedure:} This code calls a stored procedure called \c AsciiToInt(), passing it a character through its in parameter, and taking its result in the out parameter. \skipto stored \skipto QSqlQuery \printuntil boundValue( Note that unbound parameters will retain their values. \sa QSqlDatabase, QSqlQueryModel, QSqlTableModel, QVariant*//*! Constructs a QSqlQuery object which uses the QSqlResult \a result to communicate with a database.*/QSqlQuery::QSqlQuery(QSqlResult *result){ d = new QSqlQueryPrivate(result);}/*! Destroys the object and frees any allocated resources.*/QSqlQuery::~QSqlQuery(){ if (!d->ref.deref()) delete d;}/*! Constructs a copy of \a other.*/QSqlQuery::QSqlQuery(const QSqlQuery& other){ d = other.d; d->ref.ref();}/*! \internal*/static void qInit(QSqlQuery *q, const QString& query, QSqlDatabase db){ QSqlDatabase database = db; if (!database.isValid()) database = QSqlDatabase::database(QLatin1String(QSqlDatabase::defaultConnection), false); if (database.isValid()) { *q = QSqlQuery(database.driver()->createResult()); } if (!query.isEmpty()) q->exec(query);}/*! Constructs a QSqlQuery object using the SQL \a query and the database \a db. If \a db is not specified, the application's default database is used. If \a query is not an empty string, it will be executed. \sa QSqlDatabase*/QSqlQuery::QSqlQuery(const QString& query, QSqlDatabase db){ d = QSqlQueryPrivate::shared_null(); qInit(this, query, db);}/*! Constructs a QSqlQuery object using the database \a db. \sa QSqlDatabase*/QSqlQuery::QSqlQuery(QSqlDatabase db){ d = QSqlQueryPrivate::shared_null(); qInit(this, QString(), db);}/*! Assigns \a other to this object.*/QSqlQuery& QSqlQuery::operator=(const QSqlQuery& other){ qAtomicAssign(d, other.d); return *this;}/*! Returns true if the query is active and positioned on a valid record and the \a field is NULL; otherwise returns false. Note that for some drivers, isNull() will not return accurate information until after an attempt is made to retrieve data. \sa isActive(), isValid(), value()*/bool QSqlQuery::isNull(int field) const{ if (d->sqlResult->isActive() && d->sqlResult->isValid()) return d->sqlResult->isNull(field); return true;}/*! Executes the SQL in \a query. Returns true and sets the query state to active if the query was successful; otherwise returns false. The \a query string must use syntax appropriate for the SQL database being queried (for example, standard SQL). After the query is executed, the query is positioned on an \e invalid record and must be navigated to a valid record before data values can be retrieved (for example, using next()). Note that the last error for this query is reset when exec() is called. Example: \quotefromfile snippets/sqldatabase/sqldatabase.cpp \skipto QSqlQuery_snippets() \skipto named with named \skipto QSqlQuery query \printuntil exec() \sa isActive(), isValid(), next(), previous(), first(), last(), seek()*/bool QSqlQuery::exec(const QString& query){ if (d->ref != 1) { bool fo = isForwardOnly(); *this = QSqlQuery(driver()->createResult()); setForwardOnly(fo); } else { d->sqlResult->clear(); d->sqlResult->setActive(false); d->sqlResult->setLastError(QSqlError()); d->sqlResult->setAt(QSql::BeforeFirstRow); } d->sqlResult->setQuery(query.trimmed()); if (!driver()->isOpen() || driver()->isOpenError()) { qWarning("QSqlQuery::exec: database not open"); return false; } if (query.isEmpty()) { qWarning("QSqlQuery::exec: empty query"); return false; }#ifdef QT_DEBUG_SQL qDebug("\n QSqlQuery: %s", query.toLocal8Bit().constData());#endif return d->sqlResult->reset(query);}/*! Returns the value of field \a index in the current record. The fields are numbered from left to right using the text of the
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -