加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

解决SQLite异常:library routine called out of sequence

发布时间:2020-12-12 19:35:29 所属栏目:百科 来源:网络整理
导读:解决SQLite异常:library routine called out of sequence 在平常的练习中出现了这样的问题,在网上搜寻了下,发现没有什么确定的答案。 却发现: Error Code SQLITE_MISUSE (21) "Library routine called out of sequence" The SQLITE_MISUSE error code is

intret;
ret=sqlite3_exec(db,"begin transaction"&zErrorMsg);//开始一个事务

ret"commit transaction"提交事务"rollback transaction");


例程:在进行大量的操作前使用如下语句

ret);
for(...)
{
//insert into operate


如果操作错误)
}
ret);

开发过程遇到这样的问题:

分别对两个数据库文件的不同表进行操作,执行顺序为:open db A->begin trasaction->open db B->select from db B->close db B->select from db A->rollbak or commit->close db A

测试发现,select from db B这一步会出错,错误信息为library routine called out of sequence,出错后执行rollback,这一步也会报错。

原来以为原因是:开始一个事务只能对一个数据库进行操作。

测试发现,即使不开始事务,执行顺序为:open db A->open db B->select from db B->close db B->select from db A->close db A,仍会出现ibrary routine called out of sequence的错误。

难道打开一个数据库,在关闭其之前不能打开其他数据库?

难道sqlite的并发执行需要用户自己来控制?

今天发现,以上出错原因可能是总控程序和子程序的全局变量一致(都是sqlite3 *db),导致总控程序的全局变量被修改。

具体还需进一步研究。

=========================================

SQL Error:library routine called out of sequence.


在Lazarus+ZEOSDBO连接数据库后,进行打开、修改操作SQLite数据库,本机运行正常,

可是在测试机上一跑,老是提示“SQL Error:library routine called out of sequence.”

以为是动态库的问题,鼓捣了好长时间,才发现是自已把数据库路径设为绝对路径,

它当然找不到数据库了,设为相对路径后,运行OK!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

解决SQLite异常:library routine called out of sequence


在平常的练习中出现了这样的问题,在网上搜寻了下,发现没有什么确定的答案。

却发现:

Error Code SQLITE_MISUSE (21) "Library routine called out of sequence"

The SQLITE_MISUSE error code is returned when you misuse the SQLitelibrary in some way. SQLite does not guarantee that it will detectmisuse,so you should not depend on this behavior in any way. TheSQLITE_MISUSE error code is intended to help you find the bugs inyour code.

Here are some possible causes of SQLITE_MISUSE:

  1. Calling any API routine with an sqlite3* pointer that was not obtained from sqlite3_open() or sqlite3_open16() or which has already been closed by sqlite3_close().
  2. Trying to use the same database connection at the same instant in time from two or more threads.
  3. Calling sqlite3_step() with a sqlite3_stmt* statement pointer that was not obtained from sqlite3_prepare() or sqlite3_prepare16() or that has already been destroyed by sqlite3_finalize().
  4. Trying to bind values to a statement (using sqlite3_bind_...()) while that statement is running.

这是SQLite官网上给出的问题解释。

1. 调用API所用到的指针,第一种情况是没有从sqlite3_open()或者是sqlite3_open16()获得,第二种情况是sqlite3_close()函数已经将数据库关闭了。我是第二种情况。

2. 两个或者更多的线程同时访问该数据库。对于这样的问题,可以通过加上锁进行解决。

3. sqlite3_step()所用到的变量statement指针,第一种情况是该指针不是从sqlite3_prepare()或者是sqlite3_open16()获得的,第二种情况是该指针已经被销毁或者被释放。这个和1中的情况是一样的,不同的是使用这种指针的函数,两者可以和为一种情况。

4.试图将values绑定到一个正在运行的statement上。该解释未遇到。(本人遇到:在statement绑定bind值后未reset就又重新对statement绑定bind值

===================================================================

IOS,SQLite批量插入错误

在数据库中插入数据的时候,报错:Prepare-error library routine called out of sequence

代码如下,麻烦帮我看看错误出在哪儿了。谢谢

?NSString *databaseName = @"DB.sqlite";
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    NSString *databasePath = [documentsDir stringByAppendingPathComponent:databaseName];

    sqlite3 *concertsDB;
    const char *dbpath = [databasePath UTF8String];

    if (sqlite3_open(dbpath,&concertsDB) == SQLITE_OK)
    {
        sqlite3_exec(concertsDB,"BEGIN TRANSACTION",0);
        const char *sqlStatement = "INSERT INTO concertsData VALUES (?,?,?)";
        sqlite3_stmt *compiledStatement;

        if (sqlite3_prepare_v2(concertsDB,sqlStatement,-1,&compiledStatement,NULL) == SQLITE_OK) {
            int hasError;

            for (int i=0; i<[events count]; i++) {

                sqlite3_bind_text(compiledStatement,1,[[[events objectAtIndex:i] title] UTF8String],SQLITE_TRANSIENT);
                sqlite3_bind_int(compiledStatement,2,[[[events objectAtIndex:i] date] timeIntervalSince1970]);

                sqlite3_bind_text(compiledStatement,3,[[[events objectAtIndex:i] time] UTF8String],SQLITE_TRANSIENT);

                sqlite3_bind_text(compiledStatement,4,[[[events objectAtIndex:i] shortDesription] UTF8String],5,[[[events objectAtIndex:i] conductor] UTF8String],6,[[[events objectAtIndex:i] location] UTF8String],7,[[[events objectAtIndex:i] durations] UTF8String],8,[[[events objectAtIndex:i] works] UTF8String],9,[[[events objectAtIndex:i] solists] UTF8String],10,[[[events objectAtIndex:i] fulltext] UTF8String],SQLITE_TRANSIENT);                    

                sqlite3_bind_text(compiledStatement,11,[[[[events objectAtIndex:i] concertUrl] absoluteString] UTF8String],12,[[[[events objectAtIndex:i] buyUrl] absoluteString] UTF8String],13,[[[events objectAtIndex:i] imageName] UTF8String],SQLITE_TRANSIENT);

                if (sqlite3_step(compiledStatement) != SQLITE_DONE) {
                    hasError=1;
                    NSLog(@"Prepare-error %s",sqlite3_errmsg(concertsDB));
                }

                sqlite3_clear_bindings(compiledStatement);
            }
            sqlite3_reset(compiledStatement);
            if( hasError == 0 ) {
                sqlite3_exec(concertsDB,"COMMIT",0);
            }
            else {
                sqlite3_exec(concertsDB,"ROLLBACK",0);
            }

        }

        sqlite3_close(concertsDB);
    }

1个回答


prettoyic 2012.11.29 13:09

用调用**sqlite3_reset**代替调用**sqlite3_clear_bindings**, 然后用当前的调用**sqlite3_finalize** 代替**sqlite3_reset**。

如果再使用statement要先调用**sqlite3_step**才能调用**sqlite3_reset**。

等全部完成后,在statement中调用**sqlite3_finalize**

已经在每个循环中设置了绑定变量,就不需要再调用**sqlite3_clear_bindings**。


==================================================

sqlite3使用事务处理[zz]

标签: sqlite 数据库 insert 测试 磁盘 sql 2010-09-24 12:10 10890人阅读 评论(1) 收藏 举报 分类:

<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:Verdana; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:536871559 0 0 0 415 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal,li.MsoNormal,div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} -->

在对sqlite3 insert into等操作时速度比较慢。

原因:它以文件的形式存在磁盘中,每次访问时都要打开一次文件,如果对数据库进行大量的操作,就很慢。

解决办法:用事物的形式提交,因为开始事务后,进行的大量操作语句都保存在内存中,当提交时才全部写入数据库,此时,数据库文件也只用打开一次。如果操作错误,还可以回滚事务。

接口:事务的操作没有特别的接口函数,就是一个普通的sql语句而已,分别如下:

    推荐文章
      热点阅读