为什么DBD :: SQLite不能通过我的Perl CGI脚本插入数据库?

时间:2009-07-14 00:32:31

标签: perl apache sqlite dbi

我在Perl CGI脚本中运行SQLite数据库,DBD::SQLite正在访问该脚本。这是在Apache上直接运行的CGI。

DBI连接正常,选择能够运行。但是,当我尝试插入时,我得到一个带有以下错误的模具:

DBD::SQLite::st execute failed: unable to open database file(1) at dbdimp.c line 402 at index.cgi line 66

我已尝试将数据库文件权限更改为666以尝试修复此问题,但我仍然收到错误。

有什么建议吗?

5 个答案:

答案 0 :(得分:22)

看起来目录需要写权限,原因是:

  

在进行任何修改之前,SQLite需要能够在与DB相同的目录中创建日志文件。该期刊用于支持交易回滚。

来自:seem to need write permission on db's parent directory

答案 1 :(得分:1)

SQLite在执行插入和更新时会暂时锁定整个文件(没有记录级锁定)。你确定你正在释放锁吗?

SQLite文献建议您启动事务,收集该事务中的所有插入和更新,然后提交。这避免了许多连续的文件锁定,并提高了性能。

答案 2 :(得分:1)

由于SQLite锁定整个数据库文件,您可能希望使用基于超时的重试机制。当我问这个相关的question时,我正在研究几乎相同的问题。

我最后写了一些类似于Mark Fowler的Attempt的东西,如果sub抛出的异常与正则表达式匹配,我会重试:在我的情况下:

qr(already in a transaction|database is locked)i

答案 3 :(得分:1)

db文件所在目录的路径应设置可​​执行和可写位,以便从脚本中访问它。

此外,如果你不想要db文件要直接访问(即使没有使用特殊的服务器文件),它应具有访问权限,如600,如果不应直接浏览包含目录(再次,即使不使用特殊服务器文件),它应具有访问权限例如700.

我使用这个设置,它在本地和我托管我的网站的服务器上工作正常。

当然,包含目录的权限不能如果其中有任何其他文件应该可以通过html,css或javascript访问,则为700。它应该是755而已。

答案 4 :(得分:0)

如果您不想按照Todd Hunter的回答中所述对整个目录设置写权限,则可以将journal_mode PRAGMA设置为“ MEMORY”。

在这种情况下,请注意:

  

MEMORY日记记录模式将回滚日记存储在volatile中   内存。这样可以节省磁盘I / O,但要以牺牲数据库安全性和   诚信。如果使用SQLite的应用程序在中间崩溃   设置MEMORY日记记录模式时进行事务处理,然后数据库   文件很可能会损坏。

因此,这是否是一个好的解决方案取决于您的数据库及其使用方式。

其他人也提到了temp_store pragma。我不需要进行设置,但这可能取决于数据库的使用方式。

因此,在您的Perl CGI脚本中,您可以尝试以下操作:

$dbh->do("PRAGMA journal_mode = MEMORY");
$dbh->do("PRAGMA temp_store   = MEMORY");