簡體   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