繁体   English   中英

当我尝试创建具有外键约束的SQLite表时,为什么会出现“ DBD :: SQLite :: db失败:靠近“事务”:语法错误”的问题?

[英]Why do I get 'DBD::SQLite::db do failed: near “transaction”: syntax error' when I try to create a SQLite table with a foreign key constraint?

我正在尝试创建一个包含两个表的数据库:客户表和交易表(一个客户可以做很多交易,一个交易只能由一个客户完成)。 我正在使用以下Perl代码:

my $dbh = DBI->connect("dbi:SQLite:dbname=$RealBin/active.db","","")
    or die $DBI::errstr;

my @ddl = (
    "CREATE TABLE IF NOT EXISTS customer (
      id INTEGER PRIMARY KEY UNIQUE,
      id_1 INTEGER,
      id_2 INTEGER,
      name TEXT
    )",
    "CREATE TABLE IF NOT EXISTS transaction (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      customer_id INTEGER REFERENCES customer(id),
    )"
);

for my $sql (@ddl){
  $dbh->do($sql);
}

运行脚本时,出现以下错误:

DBD::SQLite::db do failed: near "transaction": syntax error at
    t/oneToMany.t line 28 (#1)
DBD::SQLite::db do failed: near "transaction": syntax error at t/oneToMany.t line 28.
DBD::SQLite::db do failed: near "transaction": syntax error at
    t/oneToMany.t line 38 (#1)

第28行是这个:

$dbh->do($sql);

你能告诉我我做错了吗?

transaction是一个SQLite关键字 ,因此如果要将其用作标识符,则必须引用它(尽管最好为表选择一个不同的名称)。

您的外键约束也有些不足。 除了约束之外, 需要为customer_id指定列定义,并以FOREIGN KEY开头约束定义。

您的查询应如下所示:

CREATE TABLE IF NOT EXISTS "transaction" (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    customer_id INTEGER,
    FOREIGN KEY (customer_id) REFERENCES customer(id)
)

此外,仅在显式启用外键约束的情况下才强制实施:

SQLite长期以来一直能够使用外键解析模式,但是约束没有得到实施。 现在,您可以发出foreign_keys编译指示来启用此功能并强制执行约束,最好是在连接到数据库并且不进行事务处理后立即进行:

 $dbh->do("PRAGMA foreign_keys = ON"); 

而且,您可以随时通过关闭编译指示来显式禁用该功能:

 $dbh->do("PRAGMA foreign_keys = OFF"); 

在撰写本文时,SQLite团队和我们默认禁用此功能,以确保向后兼容性,因为此功能可能会破坏您的应用程序,并实际上破坏了我们的某些功能。 如果您使用了具有外键约束的架构,但又不太在意它们,并认为对于SQLite总是忽略它们,请做好准备,请进行大量测试,以确保当外键支持得到支持时,您的应用程序将继续运行默认情况下启用。

全部一起:

use strict;
use warnings 'all';

use DBI;

my $dbh = DBI->connect('dbi:SQLite:dbname=foo.sqlite', '', '', {
    RaiseError => 1,
    PrintError => 0,
});

$dbh->do('PRAGMA foreign_keys = ON');

my @ddl = (
    'CREATE TABLE IF NOT EXISTS customer (
        id INTEGER PRIMARY KEY UNIQUE,
        id_1 INTEGER,
        id_2 INTEGER,
        name TEXT
    )',
    'CREATE TABLE IF NOT EXISTS "transaction" (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        customer_id INTEGER,
        FOREIGN KEY (customer_id) REFERENCES customer(id)
    )'
);

for my $sql (@ddl) {
    $dbh->do($sql);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM