Qt里面的sqlite不支持hibernate 级联更新删除更新?

1293人阅读
Android(5)
In Android 4.2, using SQLite 3.7.11, when I delete a row from the Quizzes table, who's schema is below, the corresponding rows in the QuizQuestions table are not deleted.
I can't figure out what's wrong. I have tried putting db.execSQL(&PRAGMA foreign_keys = ON;&); before and after the create table statements.
Create table statements:
CREATE TABLE quizzes(quiz_name TEXT PRIMARY KEY COLLATE NOCASE);
CREATE TABLE quizQuestions(quiz_name TEXT, question_id INTEGER,
PRIMARY KEY(quiz_name, question_id),
FOREIGN KEY(quiz_name) REFERENCES quizzes(quiz_name) ON DELETE CASCADE,
FOREIGN KEY(question_id) REFERENCES questions(question_id) ON DELETE CASCADE);
Your database should delete rows from quizQuestions in case someone is deleting fromquizzes
or fromquestions. It will ignore theentire foreign key constraint in case foreign key support is turned off and you have just regular columns that can contain
any value.
SQLite defaults to PRAGMA foreign_keys = OFF every time youopen the database. It's not a property of a table or of the schema.
In case you use SQLiteOpenHelper put it inonOpen. That is the place that is
called every time the database is opened.onCreate only once when the database is created.
Your database should delete rows from quizQuestions in case someone is deleting fromquizzes
or fromquestions. It will ignore theentire foreign key constraint in case foreign key support is turned off and you have just regular columns that can contain
any value.
SQLite defaults to PRAGMA foreign_keys = OFF every time youopen the database. It's not a property of a table
or of the schema.
In case you use SQLiteOpenHelper put it inonOpen. That is the place that is
called every time the database is opened.onCreate only once when the database is created.
What SQLiteOpenHelper calls when you callgetWriteableDatabase for the first
onConfigure every time, API Level &= 16 requireddepending on the existence and version of the database file the following is called within an transaction
onCreate if there is no database file. Typically, this happens only once in the entire lifetime of the app.onUpgrade if the database version (PRAGMA user_version - saved inside the
database file) is less then the version supplied in SQLiteOpenHelper's constructor. Happens every time you bump the version in your code.Nothing if file exists and version matches.
onOpen every time
If the same instance of SQLiteOpenHelper already has an open database it will just return it and nothing of above happens.
即在每次打开数据库的时候都要执行
db.execSQL(&PRAGMA foreign_keys = ON;&);
或者当Android API Level 足够高时(&=16)
在SQLiteOpenHelper类中有个方法
public&&&&&void&&&&& onConfigure(SQLiteDatabase db)方法。可以将配置写在此方法中。
参见文档:)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3330次
排名:千里之外您所在的位置: &
关于Sqlite数据库Update语句的一点介绍
关于Sqlite数据库Update语句的一点介绍
sqlite数据库不支持update……from语句,但可以用两种不同的方法来替代它,本文主要介绍了这一过程,接下来就让我们一起学习吧。
Sqlite数据库中的Update语句,你能了解多少呢?因为这种微型数据库用到的语句非常少,所以可能我们不会经常的用到。但要想真正的玩转sqlite这种微型数据库,掌握这些语句的用法是非常重要的。本文我们就来介绍一下update语句的使用。
1.典型的Update(支持)
Update &&T1 &&Set &&Column1=v1, &&Column2=V2&&Where &&key=V3;&
2.Update&From(很不幸,Sqlite是不支持的)
UPDATE &&t1 &&SET &&Column1=t2.Column1 &&FROM &&t2,t1 &&WHERE &&t2.key=t1.&
要进行表间更新Update&From是必须的,居然Sqlite不支持,有什么别的办法吗?还确实有,替代方法有两种:
首先,Sqlite里面有一个新鲜玩意&INSERTORREPLACE&,跟Mysql类似,这个结构能够保证在存在的情况下替换,不存在的情况下更新,用这个机制就可以轻松实现Update&From了。
INSERTORREPLACEINTO &&t1(key,Column1,Column2) &&SELECT &&t2.key,t2.Column1,t2.Column2 &&FROM &&t2,t1 &&WHERE &&t2.key=t1.&
备注:这种方法要避免插入操作,首先要确保是依照主键执行的更新,如果where条件不是主键可能就有点麻烦了。
要是不是主键的更新怎么办能?另外还有其他的办法吗?我们在这中情况下只能向典型的Update&where寻求帮助了,下面是一个例子:
UPDATE &&t1 &&SET &&Column1=(SELECTColumnxFROMt2WHEREt2.key=t1.key), &&Column2=(SELECTColumnyFROMt2WHEREt2.key=t1.key), &&WHEREt1.key=(SELECTkeyFROMt2WHEREt2.key=t1.key);&
下面举一个主从表的例子,一个部门表,一个成员表,成员表中的部门名称和代码是冗余的信息,以部门表中的部门名称和代码更新成员表中的冗余信息:
update &&userlogins &&set &&deptname=(selectdeptnamefromDepartMentswhereDepartMents.[DeptID]=userlogins.[DeptID]), &&deptcode=(selectdeptcodefromDepartMentswhereDepartMents.[DeptID]=userlogins.[DeptID]) &&where &&userlogins.[DeptID]=(SELECT[DeptID]FROM&DepartMentswhereDepartMents.[DeptID]=userlogins.[DeptID]);&
关于sqlite数据库的update语句的知识就介绍到这里,希望能给大家带来帮助吧。
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&的更多文章
MariaDB是一个向后兼容、替代MySQL的数据库服务器。它包含所有主
数据库产品
数据库综合
数据库新闻
维基百科将切换到另外一款开源数据库MariaDB
你的SQL Server代码安全吗?请你与我一起跟随作者来探
为什么会发生死锁?如何利用SQL Server Profiler分析
Oracle集群,也称Oracle RAC,称为“真正应用集群”。
数据库技术是计算机科学中一个重要的组成部分,它正在以日新月异的速度发展。数据库的基本原理和应用技术已经成为高等院校的学生
51CTO旗下网站Qt如何实现对SQLite的写入与更新操作的,急!_百度知道
Qt如何实现对SQLite的写入与更新操作的,急!
提问者采纳
网上还有人说友善的arm板子对数据库的支持不好,下片博文讲),捣鼓了一阵,很奇怪呀,但在Arm开饭板上;sqldrivers ;usr&#47,数据库能打开但执行插入的操作的时候总是报错,我把我自己写的Qt sqlite的小demo也放到了根目录下结果也成功运行了,无奈我想到的办法是整一个好的sqliteDemo 在板子上跑一下,和内核,sqlite库的路径也加上了.7;local&#47,报错信息是打开数据库失败!可以对数据库进行各种操作,我把我能想到的可能都想到了,1.0-arm&#47,在arm板linux系统上跑sqlite插件点击一下查看按钮:/QtEmbedded-4,结果把生成的可执行文件放到了根目录下成功了,在崩溃的边缘,2,但运行结果是一样的,向老大求教。后来我决定采取比较二的选择,结果还是不行,export LD_LIBRARY_PATH=$LD_LIBRARY_PATH;Trolltech&#47,就是动态库超出链接队列什么的(英语不太好),重烧了一下文件系统;plugins&#47,无奈做了下一步决定,执行sql语句的时候还是不行,错误提示不是打开数据库失败,后来还是以失败告终(但得到了好多启发,总之不行,会添加一条信息,在pc机上很容易实现了,修改了一下数据库的权限
嗯,我这边解决了,我写了绝对路径后加了双斜杠,就可以读到了。谢谢
提问者评价
非常感谢你能回答
其他类似问题
为您推荐:
sqlite的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁QT & sqlite3:
先说一下QT自带数据库sqlite3和另外用sqlite3插件的区别,他们的功能是一样的,但是代码就不一样了。QT对数据库具有完善的支持,不需要加任何其他插件就可以直接使用,但是如果你要是加了sqlite3插件,调用数据库就跟直接调用一个驱动一样,直接调用接口函数:open、close、……,换言之QT自带的数据库语言就用不上了。
一、使用Qt自带的数据库sqlite3
Qt自带了很多常用的数据库驱动,使用起来非常方便如下图所示:
使用Qt自带数据库SQLite3的代码实例:
Connect to Sqlite and do insert, delete, update and select
Foundations of Qt Development\Chapter13\sqltest\sqlite\main.cpp
* Copyright (c) , Johan Thelin
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of APress nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* &AS IS& AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include &QApplication&
#include &QtSql&
#include &QtDebug&
int main( int argc, char **argv )
QApplication app( argc, argv );
//创建连接
QSqlDatabase db = QSqlDatabase::addDatabase( &QSQLITE& );//第二个参数可以设置连接名字,这里为default
db.setDatabaseName( &./testdatabase.db& );//&设置数据库名与路径,&此时是放在上一个目录
//打开连接
if( !db.open() )
qDebug() && db.lastError();
qFatal( &Failed to connect.& );
qDebug( &Connected!& );
//各种操作
//创建table
qry.prepare( &CREATE TABLE IF NOT EXISTS names (id INTEGER UNIQUE PRIMARY KEY, firstname VARCHAR(30), lastname VARCHAR(30))& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug() && &Table created!&;
qry.prepare( &INSERT INTO names (id, firstname, lastname) VALUES (1, 'John', 'Doe')& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Inserted!& );
qry.prepare( &INSERT INTO names (id, firstname, lastname) VALUES (2, 'Jane', 'Doe')& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Inserted!& );
qry.prepare( &INSERT INTO names (id, firstname, lastname) VALUES (3, 'James', 'Doe')& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Inserted!& );
qry.prepare( &INSERT INTO names (id, firstname, lastname) VALUES (4, 'Judy', 'Doe')& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Inserted!& );
qry.prepare( &INSERT INTO names (id, firstname, lastname) VALUES (5, 'Richard', 'Roe')& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Inserted!& );
qry.prepare( &INSERT INTO names (id, firstname, lastname) VALUES (6, 'Jane', 'Roe')& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Inserted!& );
qry.prepare( &INSERT INTO names (id, firstname, lastname) VALUES (7, 'John', 'Noakes')& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Inserted!& );
qry.prepare( &INSERT INTO names (id, firstname, lastname) VALUES (8, 'Donna', 'Doe')& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Inserted!& );
qry.prepare( &INSERT INTO names (id, firstname, lastname) VALUES (9, 'Ralph', 'Roe')& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Inserted!& );
qry.prepare( &SELECT * FROM names& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Selected!& );
QSqlRecord rec = qry.record();
int cols = rec.count();
for( int c=0; c& c++ )
qDebug() && QString( &Column %1: %2& ).arg( c ).arg( rec.fieldName(c) );
for( int r=0; qry.next(); r++ )
for( int c=0; c& c++ )
qDebug() && QString( &Row %1, %2: %3& ).arg( r ).arg( rec.fieldName(c) ).arg( qry.value(c).toString() );
qry.prepare( &SELECT firstname, lastname FROM names WHERE lastname = 'Roe'& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Selected!& );
QSqlRecord rec = qry.record();
int cols = rec.count();
for( int c=0; c& c++ )
qDebug() && QString( &Column %1: %2& ).arg( c ).arg( rec.fieldName(c) );
for( int r=0; qry.next(); r++ )
for( int c=0; c& c++ )
qDebug() && QString( &Row %1, %2: %3& ).arg( r ).arg( rec.fieldName(c) ).arg( qry.value(c).toString() );
qry.prepare( &SELECT firstname, lastname FROM names WHERE lastname = 'Roe' ORDER BY firstname& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Selected!& );
QSqlRecord rec = qry.record();
int cols = rec.count();
for( int c=0; c& c++ )
qDebug() && QString( &Column %1: %2& ).arg( c ).arg( rec.fieldName(c) );
for( int r=0; qry.next(); r++ )
for( int c=0; c& c++ )
qDebug() && QString( &Row %1, %2: %3& ).arg( r ).arg( rec.fieldName(c) ).arg( qry.value(c).toString() );
qry.prepare( &SELECT lastname, COUNT(*) as 'members' FROM names GROUP BY lastname ORDER BY lastname& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Selected!& );
QSqlRecord rec = qry.record();
int cols = rec.count();
for( int c=0; c& c++ )
qDebug() && QString( &Column %1: %2& ).arg( c ).arg( rec.fieldName(c) );
for( int r=0; qry.next(); r++ )
for( int c=0; c& c++ )
qDebug() && QString( &Row %1, %2: %3& ).arg( r ).arg( rec.fieldName(c) ).arg( qry.value(c).toString() );
qry.prepare( &UPDATE names SET firstname = 'Nisse', lastname = 'Svensson' WHERE id = 7& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Updated!& );
qry.prepare( &UPDATE names SET lastname = 'Johnson' WHERE firstname = 'Jane'& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Updated!& );
qry.prepare( &DELETE FROM names WHERE id = 7& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Deleted!& );
qry.prepare( &DELETE FROM names WHERE lastname = 'Johnson'& );
if( !qry.exec() )
qDebug() && qry.lastError();
qDebug( &Deleted!& );
db.close();
二、Qt中使用sqlite3插件
1、安装sqlite3插件
从官方网站下载完整版本。
2、安装sqlite3
网上可以看到很多修改下载之后的源代码的论坛,我估计那些帖子比较老一点,最新版的代码已经不存在那些bug了,可以直接编译
&*注意复制粘贴库函数的时候有的动态链接库如果单独复制会丢失之间的链接关系,所以需要一块复制
cp -arf libsqlite3.so libsqlite3.so.0 libsqlite3.so.0.8.6&。。。
3、移植sqlite3
在QTE的include文件中建立新文件夹sqlite3,将头文件放到里面;把库文件放到QTE的lib文件中
4、编程代码实例:
(1)&QT生成的.pro文件中添加库指令:&LIBS
+= -lsqlite3
(2)&在调用数据库的文件的头文件里添加头文件和变量
&#include &sqlite3/sqlite3.h&& &&&&&&&& &
&sqlite3 *&&&&&&& //数据库
&char *zErrM&&&&& //出错信息
&char& **&&& //调用时的保存位置
&int&&&&&&&&&& //列数
int&&&&&&& //行数
&char& *&&&&& //出错信息
(3)新建或打开数据库& & &&
if( (sqlite3_open(&people.db&, &db)) != 0 ){
qDebug()&&&sqlite3 open is false&;
qDebug()&&&sqlite3 open is OK&;
(4)&建立表格
sqlite3_exec(db, &create table person(name varchar(30) PRIMARY KEY, age int);&, NULL, NULL, &zErrMsg);
*添加&PRIMARY KEY&是指定主键,每个数据库只能有一个,主键的值不能重复,比方说你设定name为主键,则相同名字的人只能保存第一个,其他的忽略不计。若想避免这种情况,则去掉主键或者设定id号为主键(id号一直加一,不会重复)。
(5)往表格里写入信息
&a.直接添加数据&&
&sqlite3_exec(db, &insert into person values('张翼', 30)&, NULL, NULL, &zErrMsg);
&sqlite3_exec(db, &insert into person values('hongdy', 28)&, NULL, NULL, &zErrMsg);&&&&&&&&&&&&&&&&& &&&
&b.添加数字变量
&int& data=10;
&char sql2[100];& //必须写明大小,划分内存,如果只写一个&char *sql2,会出现段错误
&sprintf(sql2,&insert into person values('张翼',%d);&,data);
sqlite3_exec(db,sql2,NULL,NULL,&zErrMsg);
*sprintf的作用是字串格式化命令,主要功能是把格式化的数据写入某个字符串中
&c.添加字符串变量
&char data[]=&张翼&;
&char sql2[100];
&sprintf(sql2,&insert into person values('%s',10);&,data);
sqlite3_exec(db,sql2,NULL,NULL,&zErrMsg);
&* %s需要用单引号注释&&&&&&&&&&&&&
d.添加text中的变量到数据库中
&这里需要汉字编码的问题,Windows下默认GBK或GB2312编码,Linux下默认UTF-8编码,所以如果没有设置好会出现乱码
d1.&在main.cpp中添加以下指令,支持中文显示&
&#include &QTextCodec&
QTextCodec::setCodecForTr(QTextCodec::codecForName(&UTF-8&));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName(&UTF-8&));
QTextCodec::setCodecForLocale(QTextCodec::codecForName(&UTF-8&));
d2.&读取保存
&char *abc=ui-&lineEdit-&text().toUtf8().data();&& //QString&转char*
&sprintf(sql2,&insert into person values('%s',%d);&,abc,data);
sqlite3_exec(db,sql2,NULL,NULL,&zErrMsg);
*在调试的时候如果用串口超级终端调试的话,在ARM上显示正常,但是在串口是乱码,不要被迷惑
(6)查询、调用数据库
a.&查询全部
sqlite3_get_table(db, &select * from person&, &resultp, &nrow, &ncolumn, &errmsg);
*resultp保存数据库信息,nrow返回列数,ncolumn返回列数
b.&查询部分信息
sqlite3_get_table(db, &select * from person where name='zhang'&, &resultp, &nrow, &ncolumn, &errmsg);
c.&变量查询查询
&char data[]=&张翼&;
&char sql3[100];
&sprintf(sql3,&select * from person where name='zhang';&,data);
&sqlite3_get_table(db, sql3, &resultp, &nrow, &ncolumn, &errmsg);
&*查询时使用变量的方法和添加时一样
(7)关闭数据库
&sqlite3_close(db);
三、VS+QT使用SQL驱动
//#include&QtSql&//这样写会报Cannot
open include file: 'QtSql': No such file or directory,奇葩错误,因为QtSql只是一个文件夹
&QtSql/QSqlDatabase&//这样写可以
&QtSql/QSqlTableModel&
#include&QtSql/QSqlError&
qDebug()&&&available
&QStringList
drivers=QSqlDatabase::drivers();
&foreach(QString
driver,drivers)
&&&qDebug()&&&/t&&&
&QSqlDatabase
db=QSqlDatabase::addDatabase(&SQLITE&);
&qDebug()&&&SQLITE
driver?&&&db.isValid();
dsn=QString::fromLocal8Bit(&DRIVER={SQL
SERVER};SERVER=192.168.0.123;DATABASE=test&);&&&&&
db.setHostName(&192.168.0.123&);
&db.setDatabaseName(dsn);
&db.setUserName(&sa&);
&db.setPassword(&111111&);
&if(!db.open())
&&&qDebug()&&db.lastError().text();
&&&&QMessageBox::critical(0,QObject::tr(&Database
Error&),db.lastError().text());
&&&&returnfalse;
query.exec(&select
* from mytable&);
while(query.next())
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:319996次
积分:3912
积分:3912
排名:第5505名
原创:22篇
转载:295篇
评论:18条
(3)(1)(7)(7)(6)(3)(8)(5)(2)(3)(5)(6)(7)(17)(7)(17)(11)(11)(30)(53)(32)(12)(27)(32)(1)(5)
1、stackoverflow:/ 2、何登成的技术博客:/?p=828

我要回帖

更多关于 mysql 级联更新 的文章

 

随机推荐