简体   繁体   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?

I'm trying to create a database with two tables: customer and transaction (one customer can do many transactions, one transaction can only be done by one customer). 我正在尝试创建一个包含两个表的数据库:客户表和交易表(一个客户可以做很多交易,一个交易只能由一个客户完成)。 I'm using the following Perl code: 我正在使用以下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);
}

When I run my script, I'm getting the following error: 运行脚本时,出现以下错误:

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)

The line number 28 is this one: 第28行是这个:

$dbh->do($sql);

Can you please tell me what I'm doing wrong? 你能告诉我我做错了吗?

transaction is a SQLite keyword , so you have to quote it if you want to use it as an identifier (although it's probably better to just pick a different name for your table). transaction是一个SQLite关键字 ,因此如果要将其用作标识符,则必须引用它(尽管最好为表选择一个不同的名称)。

Your foreign key constraint is also a little off. 您的外键约束也有些不足。 You need to specify a column definition for customer_id in addition to the constraint, and begin the constraint definition with FOREIGN KEY . 除了约束之外, 需要为customer_id指定列定义,并以FOREIGN KEY开头约束定义。

Your query should look like this: 您的查询应如下所示:

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

Also, foreign key constraints are only enforced if you explicitly enable them : 此外,仅在显式启用外键约束的情况下才强制实施:

SQLite has long been able to parse a schema with foreign keys, but the constraints has not been enforced. SQLite长期以来一直能够使用外键解析模式,但是约束没有得到实施。 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: 现在,您可以发出foreign_keys编译指示来启用此功能并强制执行约束,最好是在连接到数据库并且不进行事务处理后立即进行:

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

All together: 全部一起:

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.

相关问题 为什么即使我的SQLite版本支持`CREATE TABLE IF NOT EXISTS`,我仍会收到DBD :: SQLite语法错误? - Why do I get a syntax error with DBD::SQLite even though my version of SQLite supports `CREATE TABLE IF NOT EXISTS`? Perl DBD :: SQLite :: db失败:语法错误 - Perl DBD::SQLite::db do failed: syntax error 如何使用DBD :: SQLite创建表触发器? - How do I create a table trigger with DBD::SQLite? 为什么当我尝试使用 Perl 的 DBD::mysql 时出现错误? - Why do I get an error when I try to use Perl's DBD::mysql? DBD::SQLite::db 准备失败:没有这样的表 Perl - DBD::SQLite::db prepare failed: no such table Perl 尝试将值插入具有“索引”列的表时,为什么会出现SQL语法错误? - Why do I get a SQL syntax error when I try to insert values into a table with a column named “index”? 当我尝试在Linux上使用64位perl的DBD :: Advantage时,为什么会出现“Error 6060”? - Why do I get “Error 6060” when I try to use DBD::Advantage with a 64-bit perl on Linux? 为什么在此Perl代码中出现“'$ rocks ['附近的语法错误””? - Why do I get “Syntax error near '$rocks['” in this Perl code? 当我尝试为mips64交叉编译libperl时,为什么会出现语法错误? - Why do I get a syntax error when I try to cross compile libperl for mips64? 当我尝试打印包含带有冒号的键的嵌套哈希时,为什么会出现语法错误? - Why do I get a syntax error when I try to print a nested hash that has keys containing colons?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM