📄 sql.html
字号:
<a name="x2170"></a> if ( ! query.<a href="qsqlquery.html#isActive">isActive</a>() ) return 1; // 查询失败
int i;
<a name="x2173"></a> i = query.<a href="qsqlquery.html#size">size</a>(); // 在这个实例中我们有9个记录,i==9。
<a name="x2169"></a> query.<a href="qsqlquery.html#first">first</a>(); // 移动到第一条记录。
<a name="x2168"></a> i = query.<a href="qsqlquery.html#at">at</a>(); // i==0
<a name="x2171"></a> query.<a href="qsqlquery.html#last">last</a>(); // 移动到最后一条记录。
i = query.<a href="qsqlquery.html#at">at</a>(); // i==8
<a name="x2172"></a> query.<a href="qsqlquery.html#seek">seek</a>( query.<a href="qsqlquery.html#size">size</a>() / 2 ); // 移动到中间那条记录。
i = query.<a href="qsqlquery.html#at">at</a>(); // i==4
}
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-navigating-main-cpp.html">sql/overview/navigating/main.cpp</a>
</em></p>
</blockquote><p> 以上实例显示了一些定位函的用法。
<p> 注意不是所有的驱动程序都支持size(),我们可以通过以下的示例来获知驱动程序是否支持这一特征:
<p> <pre>
<a href="qsqldatabase.html">QSqlDatabase</a>* defaultDB = QSqlDatabase::<a href="qsqldatabase.html#database">database</a>();
if ( defaultDB-><a href="qsqldatabase.html#driver">driver</a>()->hasFeature( QSqlDriver::QuerySize ) ) {
// QSqlQuery::size()支持
}
else {
// QSqlQuery::size()不能被依赖
}
</pre>
<p> 当我们定位了一定记录录后我们往往希望取出这条记录的内容。
<p>
<pre> if ( createConnections() ) {
<a href="qsqlquery.html">QSqlQuery</a> query( "SELECT id, surname FROM staff;" );
<a name="x2174"></a> if ( query.<a href="qsqlquery.html#isActive">isActive</a>() ) {
<a name="x2175"></a> while ( query.<a href="qsqlquery.html#next">next</a>() ) {
<a href="qapplication.html#qDebug">qDebug</a>( query.<a href="qsqlquery.html#value">value</a>(0).toString() + ": " +
<a name="x2176"></a> query.<a href="qsqlquery.html#value">value</a>(1).toString() );
}
}
}
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-retrieve1-main-cpp.html">sql/overview/retrieve1/main.cpp</a>
</em></p>
</blockquote><p> 注意如果你只是希望扫描整个记录集你只需不断地进行next()操作。
<p> 提示:函数lastQuery()返回最后一次的的Sql语句,有时你可能想检查一下最后那次操作是否是你所想象中的操作。
<p> <a name="Using_QSqlCursor"></a>
<h2> 使用<a href="qsqlcursor.html">QSqlCursor</a>
</h2>
<a name="7"></a><p> <a href="qsqlcursor.html">QSqlCursor</a>类提供了一个更高层次的接口来浏览与编辑记录,它不需要你写SQL语句。
<p> QSqlCursor几乎可以做<a href="qsqlquery.html">QSqlQuery</a>所能做的所有事情。有两点例外:由于其代表的是数据库中的一张表或视图。默认情况下 当你浏览记录时<a href="qsqlcursor.html">QSqlCursor</a>对象总是取出记录中的所有字段。如果你只关心其中的一部分字段你需要进行一些配置,或者使用<a href="qsqlrecord.html#setGenerated">QSqlRecord::setGenerated</a>()来屏蔽掉一些字段。当然你也可以使用<a href="qsqlquery.html">QSqlQuery</a>来完成这个功能。 如果表或者视图有其唯一索引你可以通过<a href="qsqlcursor.html">QSqlCursor</a>来编辑记录。否则就只能通过<a href="qsqlquery.html">QSqlQuery</a>来编辑了。(请注意不是所有的数据库支持可编辑的视图。)
<p> <a href="qsqlcursor.html">QSqlCursor</a>一次只操作一条记录。无论是执行insert、update还是 delete,QSqlCursor都只是影响一条记录。当浏览记录集时无论何时都只有一条记录处于应用状态。也就是说QSqlCursor只维护了一条记录的“可编辑缓冲区”。“定位缓冲区”单独放置,因此当你浏览记录时该缓冲并不会受其影响。
<p> 当我们使用<a href="qsqlcursor.html">QSqlCursor</a>对象前我们必须先创建与打开一个数据库连接。数据库连接在上面的<a href="#Connecting_to_Databases">连接数据库</a>一节中已经被讲述。在实例中我们假设已经通过createConnections()创建了连接如同在<a href="#create_connections">QSqlDatabase实例</a>描述的那样。
<p> 在随后的<a href="#Data-Aware_Widgets">基于数据的窗口部件</a>一节中我们将展示如何连接窗口部件至数据库,当我们了解了游标和基于数据的窗口部件后我们就可以讨论<a href="#Subclassing_QSqlCursor">继承QSqlCursor</a>。
<p> <a href="qsqlcursor.html">QSqlCursor</a>类需要<a href="qsqlcursor-h.html">qsqlcursor.h</a>这个头文件。
<p> <a name="Retrieving_Records"></a>
<h3> 检索记录
</h3>
<a name="7-1"></a><p>
<pre> #include <<a href="qapplication-h.html">qapplication.h</a>>
#include <<a href="qsqldatabase-h.html">qsqldatabase.h</a>>
#include <<a href="qsqlcursor-h.html">qsqlcursor.h</a>>
#include "../login.h"
bool createConnections();
int main( int argc, char *argv[] )
{
<a href="qapplication.html">QApplication</a> app( argc, argv );
if ( createConnections() ) {
<a href="qsqlcursor.html">QSqlCursor</a> cur( "staff" ); // 指定表/视图名称
<a name="x2177"></a> cur.<a href="qsqlcursor.html#select">select</a>(); // 我们将检索每一条记录
while ( cur.<a href="qsqlquery.html#next">next</a>() ) {
<a name="x2178"></a> <a href="qapplication.html#qDebug">qDebug</a>( cur.<a href="qsqlquery.html#value">value</a>( "id" ).toString() + ": " +
cur.<a href="qsqlquery.html#value">value</a>( "surname" ).toString() + " " +
cur.<a href="qsqlquery.html#value">value</a>( "salary" ).toString() );
}
}
return 0;
}
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-retrieve2-main-cpp.html">sql/overview/retrieve2/main.cpp</a>
</em></p>
</blockquote><p> 我们指定表或视图的名字来创建<a href="qsqlcursor.html">QSqlCursor</a>对象,如果我们使用的不是缺省的数据库我们需要在<a href="qsqlcursor.html">QSqlCursor</a>的构造函数中指明。
<p> cur.select()将自动执行以下的Sql语句:
<p> <pre>
SELECT staff.id, staff.forename, staff.surname, staff.salary, staff.statusid FROM staff
</pre>
<p> 然后我们通过cur.next()来遍历整个记录集。获取字段值的方法与<a href="qsqlquery.html">QSqlQuery</a>类似,不过它指明的是字段名而不是value()和 setValue()的数字索引。
<p> <a name="Sorting_Data"></a>
<h4> 排序和过滤记录
</h4>
<a name="7-1-1"></a><p> 如果我们需要取记录子集,我们可以在select()函数中指定过滤条件,随后取到的结果集就都是满足条件的记录(过滤条件在SQL语言中由WHERE负责))。
<p> <pre>
cur.select( "id > 100" );
</pre>
<p> 这个select()调用将执行SQL命令:
<pre>
SELECT staff.id, staff.forename, staff.surname, staff.salary, staff.statusid
FROM staff WHERE staff.id > 100
</pre>
<p> 这将检索出<tt>id</tt>大于100的职员。
<p> 与过滤类似我们也可以对指定记录集进行排序。这个功能需要通过<a href="qsqlindex.html">QSqlIndex</a>对象来实现,它可以包括排序的字段的名称并且可以传递这个对象给select()调用。
<p> <pre>
<a href="qsqlcursor.html">QSqlCursor</a> cur( "staff" );
<a href="qsqlindex.html">QSqlIndex</a> nameIndex = cur.<a href="qsqlcursor.html#index">index</a>( "surname" );
cur.<a href="qsqlcursor.html#select">select</a>( nameIndex );
</pre>
<p> 以上语句使用“surname”字段创建了一个<a href="qsqlindex.html">QSqlIndex</a>对象,当我们把该对象与select()函数集合起来以后,得到的记录集就是按staff.surname进行排序的,在索引对象中的每个字段通过ORDER BY组织起来,被执行的SQL语句如下所示:
<pre>
SELECT staff.id, staff.forename, staff.surname, staff.salary, staff.statusid
FROM staff ORDER BY staff.surname ASC
</pre>
<p> 把过滤与排序结合起来的方法也是简单易懂的。
<p> <pre>
cur.select( "surname LIKE 'A%'", nameIndex );
</pre>
<p> 过滤字符串引起WHERE操作,<a href="qsqlindex.html">QSqlIndex</a>对象引起ORDER BY的操作,最后的命令如下:
<p> <pre>
SELECT staff.id, staff.forename, staff.surname, staff.salary, staff.statusid
FROM staff WHERE staff.surname LIKE 'A%' ORDER BY staff.surname ASC
</pre>
<p> 如果需要对不止一个字段进行排序,则索引对象创建时可包含多个字段。顺序还是倒序也可以通过<a href="qsqlindex.html#setDescending">QSqlIndex::setDescending</a>()来指定,默认是升序排序。
<p>
<pre> <a href="qsqlcursor.html">QSqlCursor</a> cur( "staff" );
<a href="qstringlist.html">QStringList</a> fields = QStringList() << "surname" << "forename";
<a name="x2180"></a> <a href="qsqlindex.html">QSqlIndex</a> order = cur.<a href="qsqlcursor.html#index">index</a>( fields );
<a name="x2181"></a> cur.<a href="qsqlcursor.html#select">select</a>( order );
while ( cur.<a href="qsqlquery.html#next">next</a>() ) {
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-order1-main-cpp.html">sql/overview/order1/main.cpp</a>
</em></p>
</blockquote><p> 以上代码中我们通过一个字符串队列来存放不止一个字段,排序中它们都将被用到。然后我们基于这些字段创建了<a href="qsqlindex.html">QSqlIndex</a>对象,最后的select()操作将执行以下语句:
<pre>
SELECT staff.id, staff.forename, staff.surname, staff.salary, staff.statusid
FROM staff ORDER BY staff.surname ASC, staff.forename ASC
</pre>
<p> 你可以在多重排序中加入过滤条件。
<p>
<pre> <a href="qsqlcursor.html">QSqlCursor</a> cur( "staff" );
<a href="qstringlist.html">QStringList</a> fields = QStringList() << "id" << "forename";
<a name="x2183"></a> <a href="qsqlindex.html">QSqlIndex</a> order = cur.<a href="qsqlcursor.html#index">index</a>( fields );
<a href="qsqlindex.html">QSqlIndex</a> filter = cur.<a href="qsqlcursor.html#index">index</a>( "surname" );
<a name="x2186"></a> cur.<a href="qsqlrecord.html#setValue">setValue</a>( "surname", "Bloggs" );
<a name="x2184"></a> cur.<a href="qsqlcursor.html#select">select</a>( filter, order );
while ( cur.<a href="qsqlquery.html#next">next</a>() ) {
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-order2-main-cpp.html">sql/overview/order2/main.cpp</a>
</em></p>
</blockquote><p> 这将执行以下的SQL语句:
<pre>
SELECT staff.id, staff.forename, staff.surname, staff.salary, staff.statusid
FROM staff WHERE staff.surname='Bloggs' ORDER BY staff.id ASC, staff.forename ASC
</pre>
<p> <a href="qsqlindex.html">QSqlIndex</a>对象“order”包含了两个字段:“id”和“forename”,它们被用来对记录集排序。<a href="qsqlindex.html">QSqlIndex</a>对象“filter”包含了一个字段:“surname”。当索引对象被作为过滤条件传给select()函数的时候,该对象中的字段名将被用来进行条件限制的列名,即<em>fieldname=value</em>。其中的value即是对应字段的限定值。我们可以用setValue()来确定每一个过滤字段的限定值。
<p> <a name="Extracting_Data"></a>
<h4> 提取数据
</h4>
<a name="7-1-2"></a><p>
<pre> <a href="qsqlcursor.html">QSqlCursor</a> cur( "creditors" );
<a href="qstringlist.html">QStringList</a> orderFields = QStringList() << "surname" << "forename";
<a name="x2187"></a> <a href="qsqlindex.html">QSqlIndex</a> order = cur.<a href="qsqlcursor.html#index">index</a>( orderFields );
<a href="qstringlist.html">QStringList</a> filterFields = QStringList() << "surname" << "city";
<a href="qsqlindex.html">QSqlIndex</a> filter = cur.<a href="qsqlcursor.html#index">index</a>( filterFields );
<a name="x2191"></a> cur.<a href="qsqlrecord.html#setValue">setValue</a>( "surname", "Chirac" );
cur.<a href="qsqlrecord.html#setValue">setValue</a>( "city", "Paris" );
<a name="x2188"></a> cur.<a href="qsqlcursor.html#select">select</a>( filter, order );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -