在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,将
-
function TASQLite3BaseQuery.GetRecord(Buffer: PAnsiChar; GetMode: TGetMode;
-
DoCheck: boolean): TGetResult;
函数的末尾部分
-
if Result = grOK then
-
begin
-
if FUniDir then begin
-
ptr := Connection.SQLite3_GetNextResult(Connection.DBHandle, FStatement, FParams,self);
-
if ptr <> nil then begin
-
Move(ptr^, ActiveBuffer^, MaxStrLen);
-
end else Result := grEOF;
-
end else begin
-
ptr := FResult.GetData(FCurRec);
-
if FResult.Count = 0 then
-
InternalInitRecord(Buffer)
-
else
-
if ptr <> nil then Move(ptr^, Buffer^, MaxStrLen); // albert 17/11/2004
-
end;
-
…
修改为
-
if Result = grOK then
-
begin
-
if FUniDir then begin
-
// 增加部分,释放前一记录的blobstream内存
-
if FResult.Count > 0 then begin FResult.FreeBlobs; FResult.Delete(0); end;
-
-
ptr := Connection.SQLite3_GetNextResult(Connection.DBHandle, FStatement, FParams,self);
-
if ptr <> nil then begin
-
FResult.Add(ptr, 0); // 增加部分,当前行添加到缓存中,等待下次释放
-
Move(ptr^, ActiveBuffer^, MaxStrLen);
-
end else Result := grEOF;
-
end else begin
-
ptr := FResult.GetData(FCurRec);
-
if FResult.Count = 0 then
-
InternalInitRecord(Buffer)
-
else
-
if ptr <> nil then Move(ptr^, Buffer^, MaxStrLen); // albert 17/11/2004
-
end;
-
…
修改后编译程序,再次打开库文件遍历表,没有再次出现问题。
Popularity: 7% [?]
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
-
wget http://www.python.org/ftp/python/2.5.2/Python-2.5.2.tgz
-
tar -xzvf Python-2.5.2.tgz
-
cd Python-2.5.2
-
./configure
-
make
-
make install
为Python安装easyinstall
-
wget http://peak.telecommunity.com/dist/ez_setup.py
-
python ez_setup.py
安装PyProtocol
-
wget http://peak.telecommunity.com/dist/PyProtocols-0.9.3.tar.gz
-
tar -xzvf PyProtocols-0.9.3.tar.gz
-
cd PyProtocols-0.9.3
-
python setup.py install
安装SQLite3
-
wget http://www.sqlite.org/sqlite-amalgamation-3.6.2.tar.gz
-
tar -xzvf sqlite-amalgamation-3.6.2.tar.gz
-
cd sqlite-3.6.2/
-
./configure
-
make
-
make install
安装 PySqlite
-
wget http://oss.itsystementwicklung.de/download/pysqlite/2.5/2.5.0/pysqlite-2.5.0.tar.gz
-
tar -xzvf pysqlite-2.5.0.tar.gz
-
cd pysqlite-2.5.0
-
python setup.py install
安装Trac
-
wget http://ftp.edgewall.com/pub/trac/Trac-0.11.1.tar.gz
-
tar -xzvf Trac-0.11.1.tar.gz
-
cd Trac-0.11.1
-
python setup.py install
官方安装配置页面 http://trac.edgewall.org/wiki/TracInstall
采用简单的独立服务启动,没有使用mod_python和fastcgi等方式
-
trac-admin /var/trac/test initenv
-
tracd –port 8080 /var/trac/test
可以测试trac运行正常
-
svn co http://trac-hacks.org/svn/zoomquiettranslation/trunk/0.11.x
-
trac-admin /var/trac/test wiki load default-pages/
-
cp ZhTracGuideToc.py /var/trac/test/plugins
在trac.ini中添加如下内容
[mainnav] wiki.href = /wiki/ZhWikiStart [metanav] help.href = /wiki/ZhTracGuide
添加Perforce版本库支持
Python的Perforce支持PyPerforce
-
wget http://downloads.sourceforge.net/pyperforce/PyPerforce-0.4.zip?modtime=1186240132&big_mirror=0
-
unzip PyPerforce-0.4.zip
-
cd PyPerforce-0.4
-
python setup.py install
-
LD_LIBRARY_PATH=/usr/local/ssl/lib python setup.py install
下载安装Perforce Plugin
-
unzip perforceplugin_trunk.zip
-
cd perforceplugin/trunk
-
python setup.py bdist_egg
-
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验证,达到不透露账号密码做保护的目的。
安装过程碰到的问题以及解决
- 安装Python包过程中碰到 ImportError: No module named _md5
- 安装Trac是碰到global name ‘sqlite’ is not defined
- 使用Perforce时提示 Unsupported version control system “perforce”
- Trac 显示中文乱码
-
cs = CharSet(self._connection.charset)
-
if cs is CharSet.UTF_8:
-
self._codec = 'utf8'
-
elif cs is CharSet.NOCONV:
-
self._codec = 'iso-8859-1'
-
else:
-
raise NotImplementedError("Charset '%s' not supported" % str(cs))
-
cs = CharSet(self._connection.charset)
-
if cs is CharSet.UTF_8:
-
self._codec = 'utf8'
-
elif cs is CharSet.NOCONV:
-
self._codec = 'gbk'
-
else:
-
raise NotImplementedError("Charset '%s' not supported" % str(cs))
- 单击数字rev号时,提示previous_rev() takes exactly 2 arguments (3 given)
-
def previous_rev(self, rev, path=''):
-
if self.has_linear_changesets:
-
return self._next_prev_rev('<', rev, path)
-
else:
-
return self.repos.previous_rev(rev, path)
-
def previous_rev(self, rev, path=''):
-
if self.has_linear_changesets:
-
return self._next_prev_rev('<', rev, path)
-
else:
-
return self.repos.previous_rev(rev)
- 登陆时提示Authentication information not available.
-
/usr/local/apache/bin/htpasswd -c /var/trac/.passwd test
-
tracd –port 8080 –basic-auth=*,/var/trac/.passwd,test.com /var/trac/test
网上查找问题,发现是openssl 版本低的原因(0.9.7a),升级Openssl 库到0.9.8g,修改 /etc/ld.so.conf 文件,添加一行 /usr/local/ssl/lib ,ldconfig -v 问题解决 缺少ld的搜索路径,修改 /etc/ld.so.conf 文件,添加一行 /usr/local/lib ,然后再 ldconfig -v 一下,正常 经过n多次尝试和网上查找资料后发现只要在trac.ini中添加如下一段,正常。 1. 文件中的中文乱码 2. Browse 中的文件名列表和changelist中的中文文字乱码 替换成
然后重新安装一下perforceplugin,不要忘记将trac工作环境重新做一下,要不然修订信息还会是乱码,为了这个折腾了我好长时间(我的猜想:这个应该和sqlite中存放的数据编码格式有关系)。 将Trac的versioncontrol目录下cache.py中 修改为
为了不重新安装Trac,可以直接修改site-packages目录下的Trac中的文件 lib/python2.5/lib/site-packages\Trac-0.1….egg/trac/versioncontrol/cache.py 因为是StandAlone的Tracd运行,缺少apache那样的basic auth,所以要按照Tracd的要求来建立验证文件。 修改Trac的启动命令,添加basic_auth参数
官方完整的tracd配置说明
LD_LIBRARY_PATH=/usr/local/ssl/lib python setup.py install
[components]
p4trac.* = enabled
通过修改 trac.ini 中过的 default_charset = utf-8 就可以了,当然如果自己的文件是其他格式的,则需要修改为其他编码,如果文件内容中的编码有两种以上,那就比较麻烦了。
修改perforceplugin的repos.py文件,将
使用apache的htpasswd制作验证文件
Popularity: 5% [?]