Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > DBXi Вставка данных


Автор: werzer 11.4.2011, 18:28
Добрый день!

Начинаю использовать DBIx::Class на проекте, база Mysql. Хочу сделать insert  в базу вида:
INSERT INTO table (some_dtime) VALUES (FROM_UNIXTIME(?)): '1302037199'. 

Проблема собственно в аргументе "FROM_UNIXTIME(?)", и именно через вопросик,  то есть данные будет экранировать сама база. У меня получилось:

Schema->resultset('table')->                                                                                          
  create({  some_dtime  => \"FROM_UNIXTIME(1302037199)" }); 

Но в этом случае запрос получается вида (без экранирования базой):
INSERT INTO table (some_dtime) VALUES (FROM_UNIXTIME(1302037199))

Как сделать, чтобы данные экранировала база?

PS: Надо бы отредактировать название темы "DBXi Вставка данных" -> "DBIx Вставка данных"

Автор: IceSunrise 11.4.2011, 21:08
werzer, А что вы хотите экранировать, там просто число?
Можете попробовать синтаксис, описанный здесь: http://search.cpan.org/~frew/SQL-Abstract-1.72/lib/SQL/Abstract.pm#Literal_SQL_with_placeholders_and_bind_values_(subqueries)

Автор: werzer 11.4.2011, 22:04
Цитата(IceSunrise @ 11.4.2011,  21:08)
werzer, А что вы хотите экранировать, там просто число?
Можете попробовать синтаксис, описанный здесь: http://search.cpan.org/~frew/SQL-Abstract-1.72/lib/SQL/Abstract.pm#Literal_SQL_with_placeholders_and_bind_values_(subqueries)

Да, просто число. Сделал, как указано по ссылке, работает, но если указать в классе с данными:
__PACKAGE__->load_components(qw/InflateColumn::DateTime/);

то вылезает ошибка, что-то типа unblessed references при вызове метода ymd, завтра подробнее напишу ошибку.

Автор: IceSunrise 12.4.2011, 10:47
Цитата(werzer @ 11.4.2011,  22:04)
Да, просто число.

А зачем экранировать просто число? Пишите, как у вас есть
Код

Schema->resultset('table')->create({  some_dtime  => \"FROM_UNIXTIME($epoch)" });

Число и есть число, там экранировать нечего smile

Автор: werzer 12.4.2011, 11:31
Цитата(IceSunrise @ 12.4.2011,  10:47)
Цитата(werzer @ 11.4.2011,  22:04)
Да, просто число.

А зачем экранировать просто число? Пишите, как у вас есть
Код

Schema->resultset('table')->create({  some_dtime  => \"FROM_UNIXTIME($epoch)" });

Число и есть число, там экранировать нечего smile

Просто я привык, что все данные нужно передавать через экранирование на всякий случай.

Вот ошибка возвращается, если вставить в класс директиву __PACKAGE__->load_components(qw/InflateColumn::DateTime/):

Can't call method "ymd" on unblessed reference at /usr/local/share/perl/5.10.1/DateTime/Format/MySQL.pm line 84.

Как эту ошибку побороть?

Автор: IceSunrise 12.4.2011, 22:10
Цитата(werzer @  12.4.2011,  11:31 Найти цитируемый пост)

Просто я привык, что все данные нужно передавать через экранирование на всякий случай.

Дело хозяйское, но экранирование здесь излишне, если в качестве параметра попадут некорректные данные все равно будет ошибка, экранированы они или нет.

Цитата(werzer @  12.4.2011,  11:31 Найти цитируемый пост)

Вот ошибка возвращается, если вставить в класс директиву __PACKAGE__->load_components(qw/InflateColumn::DateTime/):
Can't call method "ymd" on unblessed reference at /usr/local/share/perl/5.10.1/DateTime/Format/MySQL.pm line 84.
Как эту ошибку побороть?


А что вы делаете, в каком месте ошибка вылетает?

Автор: Logo 13.4.2011, 13:20
Цитата

Дело хозяйское, но экранирование здесь излишне, если в качестве параметра попадут некорректные данные все равно будет ошибка, экранированы они или нет.


http://ru.wikipedia.org/wiki/SQL_injection

Цитата

Вот ошибка возвращается, если вставить в класс директиву __PACKAGE__->load_components(qw/InflateColumn::DateTime/):


Так используйте эту директиву

Код

$rs->create({ some_dtime => DateTime->from_epoch(epoch => 1302037199) });

Автор: werzer 13.4.2011, 15:16
Цитата(IceSunrise @ 12.4.2011,  22:10)
Цитата(werzer @  12.4.2011,  11:31 Найти цитируемый пост)

Просто я привык, что все данные нужно передавать через экранирование на всякий случай.

Дело хозяйское, но экранирование здесь излишне, если в качестве параметра попадут некорректные данные все равно будет ошибка, экранированы они или нет.

Цитата(werzer @  12.4.2011,  11:31 Найти цитируемый пост)

Вот ошибка возвращается, если вставить в класс директиву __PACKAGE__->load_components(qw/InflateColumn::DateTime/):
Can't call method "ymd" on unblessed reference at /usr/local/share/perl/5.10.1/DateTime/Format/MySQL.pm line 84.
Как эту ошибку побороть?


А что вы делаете, в каком месте ошибка вылетает?

Ошибка вылезает вот тут:
Schema->resultset('table')->create({  some_dtime  => \["FROM_UNIXTIME(?)",  [some_dtime => $time]] })

Вызывать DateTime->from_epoch тоже не хочу, так как получится путаница с часовыми поясами.

Автор: sir_nuf_nuf 13.4.2011, 16:28
werzer, (Виталий ?) если у тебя стоит inflate / deflate на колонке, то в create нужно передавать "объектное" значение, т.е. экземпляр DateTime.


Может так сработает ?
Код

my $row = $Schema->resultset('table')->new_result({ ..... });
$row->set_column(some_dtime  => \["FROM_UNIXTIME(?)",  [some_dtime => $time]]);
$row->insert;



Автор: werzer 13.4.2011, 18:37
Цитата(sir_nuf_nuf @ 13.4.2011,  16:28)
werzer, (Виталий ?) если у тебя стоит inflate / deflate на колонке, то в create нужно передавать "объектное" значение, т.е. экземпляр DateTime.


Может так сработает ?
Код

my $row = $Schema->resultset('table')->new_result({ ..... });
$row->set_column(some_dtime  => \["FROM_UNIXTIME(?)",  [some_dtime => $time]]);
$row->insert;

Да это я smile

В итоге заработало, как ты описал, спасибо! Но все равно DBIx хитрая штука smile

Автор: sir_nuf_nuf 14.4.2011, 10:53
Цитата(werzer @  13.4.2011,  18:37 Найти цитируемый пост)
 Но все равно DBIx хитрая штука

Не очень хитрая =)
Для чего она не удобная - так это длинные запросы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)