在SQlite中遍历一张表的同时更新这个表的内容碰到的一些问题

在一个连接中遍历一个表的时候同时使用sql语句更新这个表的值,碰到错误”database table locked”
首先尝试在遍历前使用 PRAGMA read_uncommitted = True;
在遍历完成后在执行PRAGMA read_uncommitted = False;
这么处理后在遍历过程中可以对表做更新操作,不过引起另外一个问题,只能遍历一半的表记录,且当为记录行数为基数时会出现“not an error”错误,经测试估计是在遍历过程中使用执行更新sql语句时,同时向后移动了遍历的位置。
再次尝试使用两个链接来做遍历更新处理,其中一个链接做遍历,另外一个链接做更新。 在记录数少时一切正常,但是当记录数很多时候,在后面记录的更新时会出现“SQL logic error or missing database” 的错误。
最终对要遍历的表采用limit关键字分片读取出需要的数据,然后对这些数据做更新,完成后再读入下一组数据继续处理。

   load a block data
   while has block data
      foreach record in block
       do update
      load next block data

Popularity: 7% [?]

Related

ASQLite控件的Blob类型字段内存泄漏问题

使用Delphi的ASqlite控件做Sqlite数据库的数据维护,最近打开一个大的表,总是报”out of memory while expading memory stream” 的错误,提示内存不足。

经分析,是由于ASqlite控件在默认情况下总是将数据装入内存,记录数太多时造成数据不能完整装入。经查有UniDirectional数据可是设置为单方向使用表,可以不将记录完整装入到内存。但是设置了该属性值为True后,遍历表仍然是”Out of memory while expanding memory stream” 错误,感觉没有起作用。

分析ASQlite的源码,发现其将memo类型数据当作blob类型处理,而在UniDirectional为True是,读取记录时创建的BlobStream没有释放,因此和UniDirectional为False时行为一样。

修正Bug,打开ASGSqlite3.pas,将

  1. function TASQLite3BaseQuery.GetRecord(Buffer: PAnsiChar;    GetMode: TGetMode;
  2.   DoCheck: boolean): TGetResult;

函数的末尾部分

  1.     if Result = grOK then
  2.     begin
  3.       if FUniDir then begin
  4.           ptr := Connection.SQLite3_GetNextResult(Connection.DBHandle, FStatement, FParams,self);
  5.           if ptr <> nil then begin
  6.              Move(ptr^, ActiveBuffer^, MaxStrLen);
  7.           end else Result := grEOF;
  8.       end else begin
  9.           ptr := FResult.GetData(FCurRec);
  10.           if FResult.Count = 0 then
  11.              InternalInitRecord(Buffer)
  12.           else
  13.              if ptr <> nil then Move(ptr^, Buffer^, MaxStrLen); // albert 17/11/2004
  14.       end;
  15.       …

修改为

  1.     if Result = grOK then
  2.     begin
  3.       if FUniDir then begin
  4.           // 增加部分,释放前一记录的blobstream内存
  5.           if FResult.Count > 0 then begin FResult.FreeBlobs; FResult.Delete(0); end;
  6.          
  7.           ptr := Connection.SQLite3_GetNextResult(Connection.DBHandle, FStatement, FParams,self);
  8.           if ptr <> nil then begin
  9.              FResult.Add(ptr, 0);  // 增加部分,当前行添加到缓存中,等待下次释放
  10.              Move(ptr^, ActiveBuffer^, MaxStrLen);
  11.           end else Result := grEOF;
  12.       end else begin
  13.           ptr := FResult.GetData(FCurRec);
  14.           if FResult.Count = 0 then
  15.              InternalInitRecord(Buffer)
  16.           else
  17.              if ptr <> nil then Move(ptr^, Buffer^, MaxStrLen); // albert 17/11/2004
  18.       end;
  19.      …

修改后编译程序,再次打开库文件遍历表,没有再次出现问题。

Popularity: 6% [?]

Related

SQLite出现database disk image is malformed(11)的处理

SQLite有一个很严重的缺点就是不提供Repair命令。
导致死亡提示database disk image is malformed
它的产生有很多种可能,比如,磁盘空间不足,还有就是写入数据过程中突然掉电等。
官方对产生原因的一些说明: http://www.sqlite.org/lockingv3.html#how_to_corrupt

sqlite  my.sqlite3
sqlite>PRAGMA integrity_check;

获得提示

*** in database main ***
Page 1518: btreeInitPage() returns error code 11
On tree page 1566 cell 2: Child page depth differs
On tree page 1566 cell 3: Child page depth differs
SQL error: database disk image is malformed

可以尝试通过简单的导出导入方式对损坏的库文件作回复。
首先导出数据

sqlite3 my.sqlite3
sqlite>.output tmp.sql
sqlite>.dump
sqlite>.quit

再倒入到一个新库中

sqlite3 mynew.sqlite3
sqlite>.read tmp.sql
sqlite>.quit

这时新建的mynew.sqlite3一般可用。

Popularity: 100% [?]

Related

Perforce+Trac 0.11安装笔记(附一些问题解决方法如中文乱码问题)

网上有很多svn+Trac的安装配置文档,但是有人给做了Trac的后端版本控制扩展,是Trac的应用不再限于svn版本库,在这儿就尝试着给Trac安装一个Perforce后端版本库一下。

Trac是使用Python编写的,因此首先要个机器安装Python环境

安装Python

  1. wget http://www.python.org/ftp/python/2.5.2/Python-2.5.2.tgz
  2. tar -xzvf Python-2.5.2.tgz
  3. cd Python-2.5.2
  4. ./configure
  5. make
  6. make install

为Python安装easyinstall

  1. wget http://peak.telecommunity.com/dist/ez_setup.py
  2. python ez_setup.py

安装PyProtocol

  1. wget http://peak.telecommunity.com/dist/PyProtocols-0.9.3.tar.gz
  2. tar -xzvf PyProtocols-0.9.3.tar.gz
  3. cd PyProtocols-0.9.3
  4. python setup.py install

安装SQLite3

  1. wget http://www.sqlite.org/sqlite-amalgamation-3.6.2.tar.gz
  2. tar -xzvf sqlite-amalgamation-3.6.2.tar.gz
  3. cd sqlite-3.6.2/
  4. ./configure
  5. make
  6. make install

安装 PySqlite

  1. wget http://oss.itsystementwicklung.de/download/pysqlite/2.5/2.5.0/pysqlite-2.5.0.tar.gz
  2. tar -xzvf pysqlite-2.5.0.tar.gz
  3. cd pysqlite-2.5.0
  4. python setup.py install

安装Trac

  1. wget http://ftp.edgewall.com/pub/trac/Trac-0.11.1.tar.gz
  2. tar -xzvf Trac-0.11.1.tar.gz
  3. cd Trac-0.11.1
  4. python setup.py install

官方安装配置页面 http://trac.edgewall.org/wiki/TracInstall
采用简单的独立服务启动,没有使用mod_python和fastcgi等方式

  1. trac-admin /var/trac/test initenv
  2. tracd –port 8080 /var/trac/test

可以测试trac运行正常

Trac中文化Wiki

  1. svn co http://trac-hacks.org/svn/zoomquiettranslation/trunk/0.11.x
  2. trac-admin /var/trac/test wiki load default-pages/
  3. cp ZhTracGuideToc.py /var/trac/test/plugins

在trac.ini中添加如下内容

[mainnav]
wiki.href = /wiki/ZhWikiStart

[metanav]
help.href = /wiki/ZhTracGuide

添加Perforce版本库支持

Python的Perforce支持PyPerforce

  1. wget  http://downloads.sourceforge.net/pyperforce/PyPerforce-0.4.zip?modtime=1186240132&big_mirror=0
  2. unzip PyPerforce-0.4.zip
  3. cd PyPerforce-0.4
  4. python setup.py install
  5. LD_LIBRARY_PATH=/usr/local/ssl/lib python setup.py install

下载安装Perforce Plugin

  1. unzip perforceplugin_trunk.zip
  2. cd perforceplugin/trunk
  3. python setup.py bdist_egg
  4. python setup.py install

配置PerforcePlugin
修改 /var/trac/test/conf/trac.ini 文件,在trac这一节中添加如下一些内容

[trac]
repository_type = perforce
repository_dir = /

[perforce]
port = perforce:1666
user = p4trac
password = test
unicode = 0

建议在 Perforce 的配置中添加一个 只读权限并且不过期的账号,然后在Trac的配置中使用这个账号,并使用Perforce的Ticket来替代Password验证,达到不透露账号密码做保护的目的。

安装过程碰到的问题以及解决

Popularity: 4% [?]

Related