Строка преобразуется в число при вставке в базу данных через функцию Perl DBI $ sth-> execute () - PullRequest
4 голосов
/ 20 марта 2012

Я использую 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, но это не помогло.

EDIT

Даже если я вставлю значение непосредственно в запрос, оно не будет работать:

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 ...

EDIT

Черт возьми, я сделал это в командной строке, и я получил это:

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 ]

3 голосов
/ 20 марта 2012

Использование связывание параметров

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.

1 голос
/ 20 марта 2012

Согласно документам, если тип столбца (сходство) - TEXT, он должен храниться в виде строки; в противном случае это будет число.

...