我有一个用于地址簿的 sqlite3 数据库,我使用以下命令创建了地址表
my $dbcreate = qq(CREATE TABLE IF NOT EXISTS address
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
LASTNAME TEXT NOT NULL,
FIRSTNAME TEXT NOT NULL,
COMPANY TEXT,
STREET TEXT,
CITY TEXT,
STATE TEXT,
COUNTRY TEXT,
ZIPCODE TEXT,
MOBILE TEXT,
OTHERPHONE TEXT,
FAX TEXT,
EMAIL TEXT,
EMAIL2 TEXT,
WEBSITE TEXT,
WEBSITE2 TEXT,
DOB DATE,
NOTES TEXT,
TAGS TEXT););
因此,据我了解,第一列应该是一个自动增量主 ID,只是它不是自动增量。我从阅读 sqlite 教程中了解到,我应该只需要输入其他 18 个值,并且该列应该自动增量,但如果我插入 18 个值,我会被告知缺少一个值。 如果我手动设置 ROWID,我只能插入行。 给出了什么?
以下是我添加行的方法(未成功)
#!/usr/bin/perl -w
# script to enter a new addressbook entry
use DBI;
use strict;
use warnings;
print "Please enter a DB username? \n";
my $userid=<STDIN>;
chomp($userid);
print "Please enter a DB password? \n";
my $password=<STDIN>;
chomp($password);
my $driver = "SQLite";
my $database = "myaddress.db";
my $dsn = "DBI:$driver:dbname=$database";
my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
or die $DBI::errstr;
print "Successfull DB connection\n";
print "Creating new address book entry\n";
my $arval = 0;
my @dbits = ('LASTNAME','FIRSTNAME','COMPANY','STREET','CITY','STATE','COUNTRY','ZIPCODE','MOBILE','OTHERPHONE','FAX','EMAIL','EMAIL2','WEBSITE','WEBSITE2','DOB','NOTES','TAGS');
# print "@dbits";
# for $b (0 .. 17) {
# print "\'$dbits[$b]\', ";
# }
print "-----\n";
my @nubits = ();
foreach my $databit(@dbits) {
print "Enter $databit: \n";
my $nubit = <STDIN>;
chomp($nubit);
print "$databit = $nubit\n\n";
push(@nubits,$nubit);
print "$databit = $nubits[$arval]\n";
my $arval = (++$arval);
print "$arval\n";
}
# print "new entry will be:\n";
# for $b (0 .. 17) {
# print "$nubits[$b] | ";
# }
my $entry = qq(INSERT INTO address VALUES('$nubits[0]','$nubits[1]','$nubits[2]','$nubits[3]','$nubits[4]','$nubits[5]','$nubits[6]','$nubits[7]','$nubits[8]','$nubits[9]','$nubits[10]','$nubits[11]','$nubits[12]','$nubits[13]','$nubits[14]','$nubits[15]','$nubits[16]','$nubits[17]'););
my $retval = $dbh->do($entry);
if($retval < 0){
print $DBI::errstr;
} else {
print "entry created successfully\n";
}
my $query = qq(select * from address);
print $query;
$dbh->disconnect();
我可以从 cli 手动使用 sqlite3 来输入行,但是,正如前面提到的,我必须手动设置 ROWID/Primary ID。
过去,我只将 sqlite 与 tcl/tk 一起使用,从未使用过 perl,但即使我是一个完全的 perl n00b,我也不认为 perl 是我的问题。 sqlite3 的行为不符合预期(除非我完全误读了十几个教程,这些教程指出设置为自动增量的主键 id 应该是自动增量)。
最佳答案
它不会自动递增,因为您已经为其指定了 ID,$nubits[0]
。
如果没有列列表,INSERT INTO address VALUES (...)
将插入表中的所有列。您could use NULL
as @ReenactorRob suggests ,但这只是隐藏了该查询的另一个问题。
INSERT INTO address VALUES (...)
需要了解 address
的创建顺序才能知道元素 5 是街道。如果表中的顺序发生任何更改,您的 INSERT 就会中断。如果添加一列,您的查询就会中断。如果您将一个值放入错误的槽中(就像您所做的那样),则很难辨别。使用明确的列列表会更好。
INSERT INTO address
(lastname, firstname, company, street, ...)
VALUES
(...)
现在您的 ID 将增加并且您可以免受 future 表更改的影响。如果这看起来工作量很大,请将其设为一个采用值哈希来构建查询的函数。它比记住 $nubits[12]
更具可读性。但在此之前,请先查看 DBIx::Class它已经为您完成了此操作。
如果我没有提到bind parameters,那就是我的失职了。 。这些速度更快,允许您使用准备好的语句,并且它们可以保护您免受 SQL injection attacks 的影响。 .
关于perl - 为什么自动增量主键列在sqlite3中不自动增量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28518840/