DBD::SQLite高版本下只读库执行SELECT触发execute报错如何解决
问题原因
该问题是DBD::SQLite 1.38及以上版本的默认行为变更导致的:
- 1.37及更早版本的DBD::SQLite打开数据库时,若检测到文件不可写,会自动降级为只读模式,仅做SELECT查询时不会触发报错
- 1.38版本之后,模块默认移除了自动降级逻辑,且默认以读写模式打开数据库。你当前的连接配置关闭了
AutoCommit,就算仅执行SELECT查询,SQLite也会默认申请写权限以支持后续可能的写入操作,若文件不可写就会触发attempt to write a readonly database报错。
解决方案
最简单的方案是显式指定数据库的打开模式为只读,修改你的DSN连接串即可:
my $dbh = DBI->connect( 'dbi:SQLite:dbname=<fileName>;mode=ro', undef, undef, { RaiseError => 0, AutoCommit => 0, PrintError => 1 } );
mode=ro参数会明确告知SQLite本次连接仅执行读操作,不需要申请写权限,哪怕数据库文件本身是只读属性也可以正常执行SELECT查询。
如果你的业务场景需要同时支持读写和只读的动态切换,也可以通过连接参数指定打开标志实现:
use DBD::SQLite::Constants qw/:open_flags/; my $dbh = DBI->connect( 'dbi:SQLite:dbname=<fileName>', undef, undef, { RaiseError => 0, AutoCommit => 0, PrintError => 1, sqlite_open_flags => OPEN_READONLY, } );
内容的提问来源于stack exchange,提问作者rick7morty
相关产品推荐
相关产品推荐

