Кто нибудь работал со связкой DBIX::Class и DBI драйвер к MS Access да еще что бы в таблицах наименования полей были на русском языке?P.S. понимаю что дикость, но из cgi не хочется ручками запросы писать.
Проблема с поиском русскоязычного наполнения.Схема DBIx описана так:
-------------------------------------------------
package MyApp::Schema::ODBC::Result::Customer;use strict;
use warnings;
use Moose;
use MooseX::NonMoose;
use namespace::autoclean;
extends 'DBIx::Class::Core';__PACKAGE__->load_components("InflateColumn::DateTime", "TimeStamp");
__PACKAGE__->table("Контрагенты");
__PACKAGE__->add_columns(
"Контрагент_Код",
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
"Контрагент_Обозначение",
{
data_type => "varchar", is_nullable => 0, size => 250
}
);
__PACKAGE__->set_primary_key("Контрагент_Код");
__PACKAGE__->meta->make_immutable;
1;
---------------------------------------------Поиск из контроллера выполняется так:
my @search_res = $c->model("ODBC::Customer")->search({'me.Контрагент_Обозначение' => 'Сидоров'},{});
DBIC_TRACE показывает:
SELECT me.Контрагент_Код, me.Контрагент_Обозначение FROM ( Контрагенты me ) WHERE ( me.Контрагент_Обозначение = ? ): 'Сидоров'Поиск вида ->search({'me.Контрагент_Код' => 100}) работает нормально.
Файлы проекта все в cp1251
Консоль выводит все тоже в cp1251
Пробовал 'Сидоров', "Сидоров", "\'Сидоров\'" - не находит.
В Access'e запрос работает:
SELECT me.Контрагент_Код, me.Контрагент_Обозначение FROM ( Контрагенты me ) WHERE ( me.Контрагент_Обозначение = 'Сидоров' )У кого есть идеи?
> У кого есть идеи?Попробуй обратиться к DBI напрямую в тестовом примере.
my $sth = $db->prepare("SELECT me.Контрагент_Код, me.Контрагент_Обозначение FROM ( Контрагенты me ) WHERE ( me.Контрагент_Обозначение = 'Сидоров' )");
$sth->execute();потом
my $sth = $db->prepare("SELECT me.Контрагент_Код, me.Контрагент_Обозначение FROM ( Контрагенты me ) WHERE ( me.Контрагент_Обозначение = ? )");
$sth->execute('Сидоров');
Если работают оба, наблюдаешь глюк DBIx. Если #1 работает, а #2 - нет, наблюдаешь глюк DBI. Если не работают оба, наблюдаешь глюк ODBC.
> my $sth = $db->prepare("SELECT me.Контрагент_Код, me.Контрагент_Обозначение FROM ( Контрагенты
> me ) WHERE ( me.Контрагент_Обозначение = ? )");
> $sth->execute('Сидоров');
> Если работают оба, наблюдаешь глюк DBIx. Если #1 работает, а #2 -
> нет, наблюдаешь глюк DBI. Если не работают оба, наблюдаешь глюк ODBC.Вариант №2 не работает. ковыряю дальше..
> Если работают оба, наблюдаешь глюк DBIx. Если #1 работает, а #2 -
> нет, наблюдаешь глюк DBI. Если не работают оба, наблюдаешь глюк ODBC.Бинго!
$dbh->{odbc_force_bind_type} = 1; # помогло
Попробовал сделать трассировку DBI в файл:
-----------------------------------------------
SQLPrepare = 0
<- prepare= ( DBI::st=HASH(0x10485ec) ) [1 items] at C:/WWW/winters/cgi-bin/ac.cgi line 62
-> bind_param for DBD::ODBC::st (DBI::st=HASH(0x10485ec)~0x116e0f4 1 'Аир') thr#822b7c
+dbd_bind_ph(f2a0f4, name=1, value=''Сидоров'', attribs=, sql_type=0(unknown), is_inout=0, maxlen=0
-dbd_bind_ph=rebind_param
+rebind_param 1 ''Аир'' (size svCUR=3/SvLEN=12/max=0) svtype 4, value type:1 sql type:0
+get_param_type(f2a0f4,1)
SQLDescribeParam not supported, sv=3 bytes, defaulting to -9
bind 1 'А...' value_len=6 maxlen=10 null=0)
bind 1 value_type:-8 UNICODE VARCHAR cs=6 dd=0 bl=6
MSAccess - setting chrs not bytes
SQLBindParameter: idx=1: io_type=1, name=1, value_type=-8 (SQL_C_WCHAR), SQLType=-9 (UNICODE VARCHAR), column_size=3, d_digits=0, value_ptr=130687c, buffer_length=6, ind=6, param_size=0
-rebind_param
-----------------------------------------
"SQLDescribeParam not supported" - ошибочка натолкнула на настройки DBD::ODBCodbc_force_bind_type
This value defaults to 0.
If set to anything other than 0 this will force bound parameters to be bound as this type and SQLDescribeParam will not be used.
Модель для подключения DBIX::Class к MS Access
---------------------------------
package MyApp::Model::ODBC;use strict;
use base 'Catalyst::Model::DBIC::Schema';__PACKAGE__->config(
schema_class => 'Batbaza::Schema::ODBC',
connect_info => {
dsn => 'dbi:ODBC:mysystemdsn',
user => 'dbcuser',
password => 'dbcpassword',
odbc_force_bind_type => 1
},
);
1;
> Модель для подключения DBIX::Class к MS AccessЯ плюнул на DBIx - они полагают, что "модель" это подмножество схемы базы данных. А если у меня множество схем, между которыми есть связи? Обычное дело для data warehouse.
Между делом обнаружил, что SQL::Abstract какой-то очень абстрактный - не знает даже про GROUP BY и знать не хочет. Разработчики DBIx его используют через хак ORDER BY.
После полугода сексуальных извращений сдался и написал Class::DBIm. Сегодня [вроде] доделал update и delete.
Что умеет -
смешанные подключения - SQLite + MySQL + XXX. Из каждого вытащит список схем, таблиц и foreign keys.
JOIN между подключениями (client-side) невозможен и пока не планируетсяЕсли для таблиц есть описания в словаре данных - получаешь кучу бонусов. Названия колонок, связи между таблицами, списки для lookup, единицы измерения.
SELECT:
Скажи хоть что-нибудь - select, where, from, order_by, group_by. Достроит недостающее через словарь данных.Например - если в "select" упомянуты a.b и y.z, а в словаре данных или через foreign keys можно нарыть relation между a и y, то слепит осмысленный JOIN - где INNER, где OUTER, кому надо - ON, кому можно - USING. Прямая связь a->y необязательна, достаточно иметь какую-нибудь a->c->d->f->y. Так как порядок a-y имеет смысл, то не нужно решать задачу k-MST - y-a имеет совершенно иную цель
Есть метод для указания своего JOIN, если вообще никому не веришь.
INSERT:
для тех, кто не умеет INSERT ... RETURNING, лепит транзакцию из INSERT + SELECT ... last_inserted_rowid()UPDATE:
то же, что SELECT. Есть возможность UPDATE xxx JOIN yyy для тех DBD, кто такое умеет.DELETE:
без фокусов
Есть Catalyst::Helper::Model::DBIm, хоть и кривоватый.Нет ли желающих присоединиться? Тестер, контрибутор, anyone - стучитесь acca<at>cpan.org.