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

前端之家收集整理的这篇文章主要介绍了解决SQLite异常:library routine called out of sequence前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

解决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**。

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

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语句而已,分别如下:

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.


@H_166_301@

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

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

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

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

原文链接:https://www.f2er.com/sqlite/199147.html

猜你在找的Sqlite相关文章