perl - 为什么自动增量主键列在sqlite3中不自动增量

标签 perl sqlite

我有一个用于地址簿的 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/

相关文章:

Perl 将@ARGV 数组分配给变量

perl - unix 或 perl 一个 liner 用于同时跟踪多个文件

perl - 了解开发::泄漏

perl - 我们如何在Perl中创建唯一ID

mysql - 使用类似和自定义排序对标题字段进行 SQL 搜索

windows - 我该如何从子进程的 STDIN 读取/写入 STDOUT?

android - 下面的 SQLite 语句抛出异常 : Table TABLE_NAME has no column named COLUMN_NAME 有什么问题

linux - 在带有 sqlite 绑定(bind)的 tcl 中, "eval"命令没有为 "ATTACH DATABASE"做任何事情

mysql - Django 从 sqlite 迁移到 MySQL。夹具错误

sql - 如何组合表中的值