我有一个sqlite3 db用于通讯簿,我用以下命令创建了地址表
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设置为autoincrement,并且应该为autoincrement)。
最佳答案
它不是自动递增的,因为您已经给它提供了一个ID,$nubits[0]
。
没有列列表,INSERT INTO address VALUES (...)
将所有列插入表中。您could use NULL
as @ReenactorRob suggests,但这只是对该查询隐藏了另一个问题。INSERT INTO address VALUES (...)
需要知道创建address
的顺序,才能知道元素5是street。如果有什么改变表中的顺序,则INSERT中断。如果添加了列,查询将中断。如果您将值放在错误的位置(如您所做的那样),很难说出来。使用显式列列表会更好。
INSERT INTO address
(lastname, firstname, company, street, ...)
VALUES
(...)
现在,您的ID将增加,并且可以保护您免受将来表的更改。如果这似乎需要大量工作,则使其成为一个使用值的哈希值构建查询的函数。它比记住
$nubits[12]
是更具可读性的。但是在执行此操作之前,请先查看DBIx::Class,它已经为您完成了此操作。如果我不提及bind parameters,我将不知所措。这些速度更快,允许您使用准备好的语句,并且可以保护您免受SQL injection attacks的攻击。
关于perl - 为什么在sqlite3中自动递增主键列不能自动递增,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28518840/