2013-04-08 1 views
1

Я хочу, чтобы добавить новую запись в table1 на SQLite(Perl) Создать запрос для DBI с SQL :: Abstract

use SQL::Abstract; 
my %data = (
    id => \'max(id)', # it is doesn't work so which variant is right? 
    record => 'Something' 
); 

my $sql = SQL::Abstract->new; 

my ($stmt, @bind) = $sql->insert('table1', \%data); 


... 
my $sth = $dbh->prepare($stmt); 

Если бы я использовал DBIx :: Class в Catalyst приложение, которое я бы написал так:

id => $c->model('Model')->get_column('id')->max()

и он будет работать нормально. Итак, как я могу достичь той же цели, но используя только SQL :: Abstract, который также используется в DBIx :: Class. Может ли кто-нибудь его исправить? Благодарю.

+2

Это кажется очень неэффективным. Почему бы не сделать автоматическое увеличение столбца или использовать таблицу счетчиков? – Lucas

+1

Это также зависит от условий гонки, если у вас более одного процесса, выполняющего вставки. – cjm

+0

Я просто хочу понять, как использовать этот модуль для создания сложных запросов. – edem

ответ

2

Это фрагмент кода. Как вы можете видеть, сначала вам нужно получить max id + 1, а затем выполнить команду insert. Я должен заметить, что это небезопасно, потому что в среде с несколькими пользователями (пользователем, процессом, потоком) второй процесс может выполнять один и тот же код и получать условия гонки. Но я предполагаю, что вы просто изучение SQL :: Аннотация апи, и эта проблема не имеет значения

use DBI; 
use SQL::Abstract; 

#create table TEST(ID integer, NAME varchar); 
my $dbh = DBI->connect('dbi:SQLite:dbname=test.db', '', '', {AutoCommit=>1}); 

my $sql = SQL::Abstract->new; 

my($stmt, @bind) = $sql->select("TEST", [ 'max(ID)+1 as ID' ]); 
my $sth = $dbh->prepare($stmt); 
$sth->execute(@bind); 

my ($id) = $sth->fetchrow_array // 1; 

print "Select ID: $id", "\n"; 
$sth->finish; 

($stmt, @bind) = $sql->insert("TEST", { ID=>$id, NAME=>"test-name"}); 
$sth = $dbh->prepare($stmt); 
$sth->execute(@bind); 

$dbh->disconnect; 
+0

Спасибо за ваш совет. Вы показали мне вариант, который состоит из двух шагов, но я хотел бы сделать то же самое на один шаг. Что-то вроде этого: 'id => {-in => \ 'выберите max (id) из таблицы1'}' – edem