⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qsqlquery.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** 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    \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(    \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    \c SELECT statement, e.g. in    \code        SELECT forename, surname FROM people;    \endcode    field 0 is \c forename and field 1 is \c    surname. Using \c{SELECT *} is not recommended because the order    of the fields in the query is undefined.    An invalid QVariant is returned if field \a index does not    exist, if the query is inactive, or if the query is positioned on    an invalid record.    \sa previous() next() first() last() seek() isActive() isValid()*/QVariant QSqlQuery::value(int index) const{    if (isActive() && isValid() && (index > QSql::BeforeFirstRow))        return d->sqlResult->data(index);    qWarning("QSqlQuery::value: not positioned on a valid record");    return QVariant();}/*!    Returns the current internal position of the query. The first    record is at position zero. If the position is invalid, the    function returns QSql::BeforeFirstRow or    QSql::AfterLastRow, which are special negative values.    \sa previous() next() first() last() seek() isActive() isValid()*/int QSqlQuery::at() const{    return d->sqlResult->at();}/*!    Returns the text of the current query being used, or an empty    string if there is no current query text.    \sa executedQuery()*/QString QSqlQuery::lastQuery() const{    return d->sqlResult->lastQuery();}/*!    Returns the database driver associated with the query.*/const QSqlDriver *QSqlQuery::driver() const{    return d->sqlResult->driver();}/*!    Returns the result associated with the query.*/const QSqlResult* QSqlQuery::result() const{    return d->sqlResult;}/*!    Retrieves the record at position \a index, if available, and    positions the query on the retrieved record. The first record is    at position 0. Note that the query must be in an active state and    isSelect() must return true before calling this function.    If \a relative is false (the default), the following rules apply:    \list    \o If \a index is negative, the result is positioned before the    first record and false is returned.    \o Otherwise, an attempt is made to move to the record at position    \a index. If the record at position \a index could not be retrieved, the    result is positioned after the last record and false is returned. If    the record is successfully retrieved, true is returned.    \endlist    If \a relative is true, the following rules apply:    \list    \o If the result is currently positioned before the first    record or on the first record, and \a index is negative, there is no    change, and false is returned.    \o If the result is currently located after the last record, and    \a index is positive, there is no change, and false is returned.    \o If the result is currently located somewhere in the middle,    and the relative offset \a index moves the result below zero, the    result is positioned before the first record and false is    returned.    \o Otherwise, an attempt is made to move to the record \a index    records ahead of the current record (or \a index records behind the    current record if \a index is negative). If the record at offset \a index    could not be retrieved, the result is positioned after the last    record if \a index >= 0, (or before the first record if \a index is    negative), and false is returned. If the record is successfully    retrieved, true is returned.    \endlist    \sa next() previous() first() last() at() isActive() isValid()*/bool QSqlQuery::seek(int index, bool relative){    if (!isSelect() || !isActive())        return false;    int actualIdx;    if (!relative) { // arbitrary seek        if (index < 0) {            d->sqlResult->setAt(QSql::BeforeFirstRow);            return false;        }        actualIdx = index;    } else {        switch (at()) { // relative seek        case QSql::BeforeFirstRow:            if (index > 0)                actualIdx = index;            else {                return false;            }            break;        case QSql::AfterLastRow:            if (index < 0) {                d->sqlResult->fetchLast();                actualIdx = at() + index;            } else {                return false;            }            break;        default:            if ((at() + index) < 0) {                d->sqlResult->setAt(QSql::BeforeFirstRow);                return false;            }            actualIdx = at() + index;            break;        }    }    // let drivers optimize

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -