SQLITE3.EXE批量执行点命令的方法
这两天在使用Firedac进行sqlite数据库编程,遇到了一个问题,这个问题的本身是这样的:
有一个数据库文件,其它一切都正常,但在文件中存在一个有错的INDEX,导致无法使用FIREDAC打开,需要先删除该INDEX后,才能正常使用FIREDAC打开该数据库文件,然而如果删除该INDEX,则会对该文件进行修改,所以在删除该INDEX之前,还需先行备份该文件,这两项工作我都准备通过调用sqlite3.exe来完成。
该文件的文件名是:CCA3.DB
如果在sqlite3.exe中直接执行下面的点命令即可:
.OPEN CCA3.DB .BACKUP CCA3.DBB .OPEN CCA3.DBB DROP INDEX IF EXISTS IDX1
但是因为我是在程序中通过调用shellexecute函数来实现的,不准备让程序使用者进行操作和等待,因此需要在调用函数shellexecute时批量完成这些操作,只能在sqlite3的参数上下功夫。
好吧,下面先来谈谈sqlite3.exe的参数吧,我在sqlite的官网上,只看到unix下面的操作,参数之间使用符号“|”来进行分割,依葫芦画瓢的做,结果出错了。
如果不使用“|”来进行分割呢?依然出错。
当我执行:sqlite3.exe CCA3.DB ".BACKUP CCA3.DBB",只是用一个语句时却没问题。
后来经过摸索我才发现,在windows系统下,sqlite3.exe的参数是不限制的,但是参数的分隔符是空格,所以只需要把每个命令用双引号或单引号囊括起来,并用空格分隔开即可,下面的命令就可以完成所有的操作。
sqlite3.exe CCA3.DB ".BACKUP CCA3.DBB" ".OPEN CCA3.DBB" "DROP INDEX IF EXISTS IDX1"
当然,如果需要的操作再长点,似乎命令行的长度是有限制的,只有采用另外的方法了。
tsl:=TStringList.Create; tsl.Add('.backup CCA3\\'+ss1); tsl.Add('.open CCA3\\'+ss1); tsl.Add('drop index if exists IX_alternate_destination_airport_id;') ; tsl.SaveToFile('a1.txt'); ss1:=dlgOpen1.FileName+' ".read a1.txt"'; h:=shellexecute(Self.Handle,'open','sqlite3.exe', PChar(ss1),nil,SW_SHOWNORMAL); while GetStdHandle(h)=h do begin Application.ProcessMessages; end;
.read可以读取一个sqlite3.exe的“批处理”文档,适用于需要批量处理的命令很多的情况。
这段代码很简单,就懒得解释了。
最后一段循环的目的是用于等待执行shellexecute完毕后再继续,因为windows下shellexecute调用的程序和本程序是同时进行的,在sqlite3.exe执行完毕前,你可能会得到一个不完整的数据库文件。