Строка преобразуется в число при вставке в базу данных через функцию Perl DBI $sth->execute()
Я использую Perl DBI и базу данных SQLite (у меня установлен DBD::SQLite). У меня есть следующий код:
my $dbh = DBI->connect("dbi:SQLite:dbname=$db", "", "", { RaiseError => 1, AutoCommit => 1 });
...
my $q = "INSERT OR IGNORE INTO books (identica, book_title) VALUES (?, ?)";
my $sth = $dbh->prepare($q);
$sth->execute($book_info->{identica}, $book_info->{book_title});
У меня проблема в том, когда $book_info->{identica}
начинается с 0, они отбрасываются, и я получаю номер, вставленный в базу данных.
Например, identica
из 00123
будет преобразован в 123
,
Я знаю, что SQLite не имеет типов, так как мне сделать DBI для вставки identica
как строка, а не число?
Я попытался процитировать это как "$book_info->{identica}"
при переходе к $sth->execute
но это не помогло
РЕДАКТИРОВАТЬ
Даже если я вставлю значение непосредственно в запрос, это не сработает:
my $i = $book_info->{identica};
my $q = "INSERT OR IGNORE INTO books (identica, book_title) VALUES ('$i', ?)";
my $sth = $dbh->prepare($q);
$sth->execute($book_info->{book_title});
Это еще кроет 00123
в 123
, а также 0000000009
в 9
...
РЕДАКТИРОВАТЬ
Черт возьми, я сделал это в командной строке, и я получил это:
sqlite> INSERT INTO books (identica, book_title) VALUES ('0439023521', 'a');
sqlite> select * from books where id=28;
28|439023521|a|
Он был сброшен SQLite!
Вот как выглядит схема:
CREATE TABLE books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
identica STRING NOT NULL,
);
CREATE UNIQUE INDEX IDX_identica on books(identica);
CREATE INDEX IDX_book_title on books(book_title);
Есть идеи, что происходит?
РЕШЕНИЕ
Это проблема sqlite, см. Ответ в комментариях Джима. STRING
должен быть TEXT
в sqlite. В противном случае он рассматривает это как число!
Изменение схемы на следующее решило это:
CREATE TABLE books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
identica TEXT NOT NULL,
);
2 ответа
Используйте параметры связывания
my $sth = $dbh->prepare($q);
$sth->bind_param(1, 00123, { TYPE => SQL_VARCHAR });
$sth->bind_param(2, $book_info->{book_title});
$sth->execute();
ОБНОВИТЬ:
Читайте о сходстве типов в SQLite. Потому что ваш тип столбца STRING
(технически не поддерживается), по умолчанию используется сходство INTEGER. Вы должны создать свой столбец как TEXT
вместо.
Согласно документам, если тип столбца (сходство) - TEXT, он должен хранить его как строку; в противном случае это будет число.