📄 sql.html
字号:
while ( cur.<a href="qsqlquery.html#next">next</a>() ) {
<a name="x2189"></a> int id = cur.<a href="qsqlquery.html#value">value</a>( "id" ).toInt();
<a href="qstring.html">QString</a> name = cur.<a href="qsqlquery.html#value">value</a>( "forename" ).toString() + " " +
cur.<a href="qsqlquery.html#value">value</a>( "surname" ).toString();
<a name="x2192"></a> <a href="qapplication.html#qDebug">qDebug</a>( QString::<a href="qstring.html#number">number</a>( id ) + ": " + name );
}
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-extract-main-cpp.html">sql/overview/extract/main.cpp</a>
</em></p>
</blockquote><p> 在以上的实例中,我们为creditors表创建了一个游标,我们创建了两个<a href="qsqlindex.html">QSqlIndex</a>对象,第一个“order”创建于“orderFields”字串列,第二个“filter”创建于“filterFields”字串列,我们为过滤字段“surname”与“city”分别设定了条件值。现在我们调用select(),产生的SQL语句如下:
<pre>
SELECT creditors.city, creditors.surname, creditors.forename, creditors.id
FROM creditors
WHERE creditors.surname = 'Chirac' AND creditors.city = 'Paris'
ORDER BY creditors.surname ASC, creditors.forename ASC
</pre>
过滤字段用于WHERE语句,排序字段用于ORDER BY语句。
<p> 现在我们遍历整个符合条件的记录集(如果有的话),我们得到字段id、forename与surname的值并把它们传入我们需要处理的函数中去,在这个实例是一个简单的<a href="qapplication.html#qDebug">qDebug</a>()调用。
<p> <a name="Manipulating_Records"></a>
<h3> 处理记录
</h3>
<a name="7-2"></a><p> 当一张表或视图有唯一索引的情况下,使用<a href="qsqlcursor.html">QSqlCursor</a>可对表或视图的记录进行插入、更新与删除操作。否则只能用<a href="qsqlquery.html">QSqlQuery</a>来进行操作。(注意不是所有数据库都支持可编辑的视图。)
<p> 每一个游标有一个内部的编辑缓冲区用于编辑操作(insert、update和delete)。 编辑过程对于每种操作都是类似是:获取指向相关缓冲区的指针,调用setValue()来更新缓冲,调用insert()或update()或del()来执行所需要的操作。举例来说,当通过游标来插入记录时,你通过primeInsert()来获得一个指向编辑缓冲区的指针,调用setValue()来刷新缓冲区中每个字段的值,然后调用QSQlCursor::insert()把缓冲区的数据插入数据库。类似的,当刷新(或删除)一条记录的时候,缓冲区中的数据将刷新(或删除)至数据库。你调用任何一个<a href="#Navigating_Result_Sets">游标定位</a>的函数都不会影响缓冲区中的内容。请注意如果你调用setValue()传入的是一个单引号括起来的字符串,单引号将被忽略,因为单引号在SQL中有着特殊的意义。
<p> primeInsert()、primeUpdate()和primeDelete()这样的方法都返回一个指向内部可编辑缓冲区的指针,每一种方法在返回前都会在可编辑缓冲区上执行一些不同的隐藏操作,默认情况下,<a href="qsqlcursor.html#primeInsert">QSqlCursor::primeInsert</a>()清空缓冲区上所有字段的值。(请参考<a href="qsqlrecord.html#clearValues">QSqlRecord::clearValues</a>())。<a href="qsqlcursor.html#primeUpdate">QSqlCursor::primeUpdate</a>()和<a href="qsqlcursor.html#primeDelete">QSqlCursor::primeDelete</a>()在缓冲区中初始化当前游标处的各个字段值,这三个函数都是虚函数,因些你可以重新定义它们的行为。(比如重载primeInsert()以便对自动数值型的字段作出处理)。用户界面的数据感知组件会发出信号,比如primeInsert(),这样就可以进行连接,这些操作都会传递一个指针至合适的缓冲,因些子数据操作可能并不需要。相应信息请见<a href="#Subclassing_QSqlCursor">继承QSqlCursor</a>。参考<em>Qt设计器</em>的用户手册可了解与primeInsert()有关的信号。
<p> 当你调用了insert()、update()或del()之后,游标将无法定位至一条有效的记录并且实际上是不可用的。如果你还想继续浏览记录的话你必须调用select()以便从数据库读取更改后的记录。
<p> <a name="Inserting_Records"></a>
<h4> 插入记录
</h4>
<a name="7-2-1"></a><p>
<pre> <a href="qsqlcursor.html">QSqlCursor</a> cur( "prices" );
<a href="qstringlist.html">QStringList</a> names = QStringList() <<
"Screwdriver" << "Hammer" << "Wrench" << "Saw";
int id = 20;
for ( QStringList::Iterator name = names.<a href="qvaluelist.html#begin">begin</a>();
<a name="x2197"></a> name != names.<a href="qvaluelist.html#end">end</a>(); ++name ) {
<a name="x2194"></a> <a href="qsqlrecord.html">QSqlRecord</a> *buffer = cur.<a href="qsqlcursor.html#primeInsert">primeInsert</a>();
<a name="x2195"></a> buffer-><a href="qsqlrecord.html#setValue">setValue</a>( "id", id );
buffer-><a href="qsqlrecord.html#setValue">setValue</a>( "name", *name );
buffer-><a href="qsqlrecord.html#setValue">setValue</a>( "price", 100.0 + (double)id );
<a name="x2193"></a> count += cur.<a href="qsqlcursor.html#insert">insert</a>();
id++;
}
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-insert-main-cpp.html">sql/overview/insert/main.cpp</a>
</em></p>
</blockquote><p> 在以上的实例中我们为“prices”表创建了一个游标,然后我们创建了一个产品名列表并进入了一个循环。在循环中我们调用了游标的primeInsert()方法。该方法返回了一个指向<a href="qsqlrecord.html">QSqlRecord</a>缓冲区的指针,该缓冲区的所有字段均置为空值。(请注意<a href="qsqlcursor.html#primeInsert">QSqlCursor::primeInsert</a>()是虚函数,可以在继承类中定制,请参考<a href="qsqlcursor.html">QSqlCursor</a>)。然后我们调用setValue()来设置每一个字段,最后调用insert()来实际插入记录。insert()返回值告诉我们有多少记录被实际插入。
<p> 我们通过primeInsert()调用来获得指向<a href="qsqlrecord.html">QSqlRecord</a>对象的指针。<a href="qsqlrecord.html">QSqlRecord</a>对象存储一条记录的数据以及相关的中间数据。在实际的应用程序中大多数与<a href="qsqlrecord.html">QSqlRecord</a>有关的操作只是简单进行value()与setValue()的调用。就象上面以及下面的实例一样。
<p> <a name="Updating_Records"></a>
<h4> 更新记录
</h4>
<a name="7-2-2"></a><p>
<pre> <a href="qsqlcursor.html">QSqlCursor</a> cur( "prices" );
<a name="x2199"></a> cur.<a href="qsqlcursor.html#select">select</a>( "id=202" );
if ( cur.<a href="qsqlquery.html#next">next</a>() ) {
<a name="x2198"></a> <a href="qsqlrecord.html">QSqlRecord</a> *buffer = cur.<a href="qsqlcursor.html#primeUpdate">primeUpdate</a>();
<a name="x2203"></a> double price = buffer-><a href="qsqlrecord.html#value">value</a>( "price" ).toDouble();
double newprice = price * 1.05;
<a name="x2202"></a> buffer-><a href="qsqlrecord.html#setValue">setValue</a>( "price", newprice );
<a name="x2200"></a> cur.<a href="qsqlcursor.html#update">update</a>();
}
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-update-main-cpp.html">sql/overview/update/main.cpp</a>
</em></p>
</blockquote><p> 以上代码我们先在价格表上创建了一个游标。调用select()把需更新的记录选出来,通过next()进行定位。再调用primeUpdate()来获得一个指向<a href="qsqlrecord.html">QSqlRecord</a>的指针,该缓冲区中的内容将被当前记录的数据所填充。我们获得当前字段的价格值再计算出一个新的价格。最后调用update()来更新记录,update()返回实际被更新的记录数。
<p> 如果有许多同样的更新需要执行,比如说更新一批价格,通过<a href="qsqlquery.html">QSqlQuery</a>来执行一条SQL语句的效率可能更高一些。
<p> <pre>
<a href="qsqlquery.html">QSqlQuery</a> query( "UPDATE prices SET price = price * 1.05" );
</pre>
<p> <a name="Deleting_Records"></a>
<h4> 删除记录
</h4>
<a name="7-2-3"></a><p>
<pre> <a href="qsqlcursor.html">QSqlCursor</a> cur( "prices" );
<a name="x2206"></a> cur.<a href="qsqlcursor.html#select">select</a>( "id=999" );
if ( cur.<a href="qsqlquery.html#next">next</a>() ) {
<a name="x2205"></a> cur.<a href="qsqlcursor.html#primeDelete">primeDelete</a>();
<a name="x2204"></a> cur.<a href="qsqlcursor.html#del">del</a>();
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-del-main-cpp.html">sql/overview/del/main.cpp</a>
</em></p>
</blockquote><p>需要删除记录时,选择相应的记录然后定位,调用primeDelete()使缓冲区保存当前记录的值,然后调用<a href="qsqlcursor.html#del">QSqlCursor::del</a>()来进行删除操作。
<p> 与更新操作一样,如果有多条类似的记录需要删除,使用一条SQL语句的效率可能更高一些。
<p> <pre>
<a href="qsqlquery.html">QSqlQuery</a> query( "DELETE FROM prices WHERE id >= 2450 AND id <= 2500" );
</pre>
<p> <a name="Data-Aware_Widgets"></a>
<h2> 基于数据的窗口部件
</h2>
<a name="8"></a><p> 基于数据的窗口部件通过简便而强有力的方法把数据与用户界面结合起来。使用<em>Qt设计器</em>来创建与维护基于数据的窗口部件是一件方便的事情。本节为那些致力于完全用编程语言实现下述实例的开发人员们做出一个导引。请注意在<em>Qt设计器</em>的手册中“创建数据库应用程序”这一节所讲述的应用以及附带的实例。
<p> <a name="Data-Aware_Tables"></a>
<h3> 基于数据的表
</h3>
<a name="8-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 <<a href="qdatatable-h.html">qdatatable.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> staffCursor( "staff" );
<a href="qdatatable.html">QDataTable</a> *staffTable = new <a href="qdatatable.html">QDataTable</a>( &staffCursor, TRUE );
app.<a href="qapplication.html#setMainWidget">setMainWidget</a>( staffTable );
<a name="x2210"></a> staffTable-><a href="qdatatable.html#refresh">refresh</a>();
staffTable-><a href="qwidget.html#show">show</a>();
return app.<a href="qapplication.html#exec">exec</a>();
}
return 0;
}
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-table1-main-cpp.html">sql/overview/table1/main.cpp</a>
</em></p>
</blockquote><p> 基于数据的表需要<a href="qdatatable-h.html">qdatatable.h</a>和<a href="qsqlcursor-h.html">qsqlcursor.h</a>这两个头文件。我们创建应用程序对象,然后调用createConnections()并创建游标。之后使用游标的指针创建<a href="qdatatable.html">QDataTable</a>对象,设置autoPopulate标志为TRUE。再把<a href="qdatatable.html">QDataTable</a>设为主窗口部件,调用 refresh()来获取数据,调用show()使其为用户可见。
<p> autoPopulate标志告诉<a href="qdatatable.html">QDataTable</a>是否根据当前游标创建列。该标志并不影响数据的的读入。数据的读入是由refresh()完成的。
<p>
<pre> <a href="qsqlcursor.html">QSqlCursor</a> staffCursor( "staff" );
<a href="qdatatable.html">QDataTable</a> *staffTable = new <a href="qdatatable.html">QDataTable</a>( &staffCursor );
app.<a href="qapplication.html#setMainWidget">setMainWidget</a>( staffTable );
<a name="x2213"></a> staffTable-><a href="qdatatable.html#addColumn">addColumn</a>( "forename", "Forename" );
staffTable-><a href="qdatatable.html#addColumn">addColumn</a>( "surname", "Surname" );
staffTable-><a href="qdatatable.html#addColumn">addColumn</a>( "salary", "Annual Salary" );
<a href="qstringlist.html">QStringList</a> order = QStringList() << "surname" << "forename";
<a name="x2215"></a> staffTable-><a href="qdatatable.html#setSort">setSort</a>( order );
<a name="x2214"></a> staffTable-><a href="qdatatable.html#refresh">refresh</a>();
staffTable-><a href="qwidget.html#show">show</a>();
</pre><blockquote><p align="center"><em> 来自<a href="sql-overview-table2-main-cpp.html">sql/overview/table2/main.cpp</a>
</em></p>
</blockquote><p> 在以上代码中我们创建了一个空的<a href="qdatatable.html">QDataTable</a>,然后人工指定将显示的列,每一列我们都可以指定显示的标题。
<p> 我们可以在表中对记录进行排序,或者也可以让设置游标让其完成排序工作。
<p> 当所有设置工作完成后就可以调用refresh()以便从数据库中获得数据,然后调用show()使其可见。
<p> QDataTables只接收可见的记录集(依赖于驱动程序),这样做使得即使是一张大表也可以被迅速地显示同时消耗较少的内存。
<p> <a name="Creating_Forms"></a>
<h3> 创建基于数据的窗体
</h3>
<a name="8-2"></a><p> 创建一个基于数据的窗体要比使用基于数据的窗口部件要麻烦很多,这是因为我们必须单独处理每一个数据列,以下所示的代码绝大部分都可以由<em>Qt设计器</em>所产生,相关资料可参考<em>Qt设计器</em>的用户手册。
<p> <a name="Displaying_a_Record"></a>
<h4> 显示记录
</h4>
<a name="8-2-1"></a><p>
<pre> #include <<a href="qapplication-h.html">qapplication.h</a>>
#include <<a href="qdialog-h.html">qdialog.h</a>>
#include <<a href="qlabel-h.html">qlabel.h</a>>
#include <<a href="qlayout-h.html">qlayout.h</a>>
#include <<a href="qlineedit-h.html">qlineedit.h</a>>
#include <<a href="qsqldatabase-h.html">qsqldatabase.h</a>>
#include <<a href="qsqlcursor-h.html">qsqlcursor.h</a>>
#include <<a href="qsqlform-h.html">qsqlform.h</a>>
#include "../login.h"
bool createConnections();
class FormDialog : public <a href="qdialog.html">QDialog</a>
{
public:
FormDialog();
};
FormDialog::FormDialog()
{
<a href="qlabel.html">QLabel</a> *forenameLabel = new <a href="qlabel.html">QLabel</a>( "Forename:", this );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -