为什么在我尝试创建带有外键约束的 SQLite table 时得到 'DBD::SQLite::db do failed: near "transaction": syntax error'?

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 keyword,所以如果你想将它用作标识符,你必须引用它(尽管最好为你的 [=33= 选择一个不同的名称) ]).

你的外键约束也有点不对劲。除了 约束之外,您还需要为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)
)

另外,外键约束只有在 explicitly enable them:

SQLite has long been able to parse a schema with foreign keys, but the constraints has not been enforced. Now you can issue a foreign_keys pragma to enable this feature and enforce the constraints, preferably as soon as you connect to a database and you're not in a transaction:

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

And you can explicitly disable the feature whenever you like by turning the pragma off:

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

As of this writing, this feature is disabled by default by the SQLite team, and by us, to secure backward compatibility, as this feature may break your applications, and actually broke some for us. If you have used a schema with foreign key constraints but haven't cared them much and supposed they're always ignored for SQLite, be prepared, and please do extensive testing to ensure that your applications will continue to work when the foreign keys support is enabled by default.

总计:

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);
}