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

发布于 2024-07-27 14:24:46 字数 404 浏览 10 评论 0原文

我正在 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 以尝试修复此问题,但我仍然收到错误。

有什么建议吗?

I am running a SQLite database within a Perl CGI script which is being accessed by DBD::SQLite. This is being run as a straight CGI on Apache.

The DBI connection works fine and selects are able to be run. However, when I attempt to do an insert I get a die with the following error:

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

I have tried changing the database file permission to 666 to try to fix this however I am still receiving the error.

Any advice?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

笑咖 2024-08-03 14:24:46

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

在进行任何修改之前,SQLite 需要能够在与数据库相同的目录中创建日志文件。 日志用于支持事务回滚。

来自:似乎需要对数据库父目录的写权限

It looks like the directory needs write permission, the reason is:

SQLite needs to be able to create a journal file in the same directory as the DB, before any modifications can take place. The journal is used to support transaction rollback.

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

浸婚纱 2024-08-03 14:24:46

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

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

SQLite momentarily locks the entire file when it is doing inserts and updates (there is no record-level locking as such). Are you sure you're freeing the locks?

The SQLite literature recommends that you start a transaction, collect all of your inserts and updates du jour in that transaction, and then commit. This avoids numerous successive file locks, and improves performance.

裸钻 2024-08-03 14:24:46

由于 SQLite 锁定整个数据库文件,因此您可能需要使用基于超时的重试机制。 当我问这个相关的

我最终写了一些类似于 Mark Fowler 的 Attempt 的内容,如果抛出异常则重试by sub 匹配正则表达式,在我的例子中:

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

Since SQLite locks the entire database file, you may want to use a timeout-based retry mechanism. I was working on pretty much the same problem when I asked this related question.

I ended up writing something similar to Mark Fowler's Attempt that retries if the exception thrown by the sub matches a regular expression, in my case:

qr(already in a transaction|database is locked)i
怪我鬧 2024-08-03 14:24:46

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

此外,如果您不希望直接访问 db 文件(即使不使用特殊的服务器文件),它也应该具有访问权限,例如 600,并且如果不应直接浏览包含的目录(同样,即使不使用特殊的服务器文件),它也应该具有访问权限,例如 700。< br>
我使用这个设置,它在本地和我托管站点的服务器上都运行良好。

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

The path to the directory where the db file resides should have both executable and writable bits set, in order to access it from the script.

Furthermore, if you don't want the db file to be directly accessed (even without the use of special server files), it should have access permissions such as 600 and if the containing directory should not be directly browsed (again, even without the use of special server files) it should have access permissions such as 700.

I use this setup and it works fine both locally and on the server where I host my site.

Of course, the permission of the containing directory cannot be 700 if there exists any other file inside it that should be accessible via html, css or javascript. It should be 755 instead.

错々过的事 2024-08-03 14:24:46

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

在这种情况下,请注意:

MEMORY日志模式将回滚日志存储在易失性中
内存。 这节省了磁盘 I/O,但代价是数据库安全和
正直。 如果使用 SQLite 的应用程序在执行过程中崩溃
设置MEMORY日志模式时的事务,则数据库
文件很可能会损坏。

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

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

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

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

If you don't want to set write permissions on the whole directory as explained in Todd Hunter's answer, you could instead set the journal_mode PRAGMA to "MEMORY".

In that case, beware that:

The MEMORY journaling mode stores the rollback journal in volatile
RAM. This saves disk I/O but at the expense of database safety and
integrity. If the application using SQLite crashes in the middle of a
transaction when the MEMORY journaling mode is set, then the database
file will very likely go corrupt.

So whether this is a good solution depends on your database and how it is used.

Others also mention the temp_store pragma. I didn't need to set that, but it may depend on how the database is used.

So in your Perl CGI script, you could try this:

$dbh->do("PRAGMA journal_mode = MEMORY");
$dbh->do("PRAGMA temp_store   = MEMORY");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文