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


Автор: DEER 21.11.2005, 10:00
у меня у одного поля в БД(MySQL 5) тип LONGBLOB, не могу получить, то что там записано smile
т.е. запрос а выборку срабатывает нормально, но потом, когда пытаюсь получить значение из этого поля, например в $res, ничего не возвращается smile
Как это лечиться?

Автор: korob2001 21.11.2005, 10:41
Покажи пример того, как ты пытаешься это сделать.

Автор: DEER 21.11.2005, 10:59
Код

my $res;
my $sth = $dbh->prepare("SELECT pdump.dump FROM pdump WHERE pdump.id = '1' ");
  $sth->execute();
  if (my $ref = $sth->fetchrow_hashref()) {
    $res = $ref->{'dump'};
    print "Dump : $res";
  }
  $sth->finish();

pdump.dump имеет тип LONGBLOB
этот код выводит
Цитата
Dump :

и всё, т.е. запись то отбирается, но значение не возвращается

Автор: sharq 21.11.2005, 11:53
DEER
Попробуй посмотреть, что в переменной находится:
Код

use Data::Dumper;
if (my $ref = $sth->fetchrow_hashref()) {
 print Dumper($ref);
}


Зачем ты в запросе указываешь таблицу перед полем? Ты же работаешь с одной таблицей.
В этом может быть и ошибка. Раз ты используешь хеши при выборке, то забирай все поля.
Код

"SELECT * FROM pdump WHERE id = '1'"


И используй fetchrow в цикле для получения всех записей или вообще используй selectrow_hashref.

smile

Автор: DEER 21.11.2005, 12:08
Цитата(sharq @ 21.11.2005, 11:53)
DEER
Попробуй посмотреть, что в переменной находится:
Код

use Data::Dumper;
if (my $ref = $sth->fetchrow_hashref()) {
 print Dumper($ref);
}


Спасибо, попробую
Цитата(sharq @ 21.11.2005, 11:53)

Зачем ты в запросе указываешь таблицу перед полем? Ты же работаешь с одной таблицей.
В этом может быть и ошибка. Раз ты используешь хеши при выборке, то забирай все поля.
Код

"SELECT * FROM pdump WHERE id = '1'"


И используй fetchrow в цикле для получения всех записей или вообще используй selectrow_hashref.

smile

ВОт если запрос сделать так

Код

my $res;    
my $sth = $dbh->prepare("SELECT pdump.id FROM pdump WHERE pdump.id = '1' ");    
  $sth->execute();    
  if (my $ref = $sth->fetchrow_hashref()) {    
    $res = $ref->{'id'};    
    print "Dump : $res";    
  }    
  $sth->finish();

он возвращает "1", т.е. ошибки нет, это я проверял.... просто мне кажется что этот LONGBLOB надо получать каким то иным способом.... smile

Автор: DEER 21.11.2005, 12:34
Может не в кассу, но в JAVA есть метод дла получения бинарных данных
Код

res.getBytes(1);

где res - результат запроса, что то подобное моему $ref
вот что нить подобного нету в Perl?

Автор: sharq 21.11.2005, 13:23
DEER perldoc DBI - LongReadLen.

Автор: DEER 21.11.2005, 13:36
не пошло
Цитата
C:\>perldoc DBI - LongReadLen
No documentation found for "-".
No documentation found for "LongReadLen".
NAME
    DBI - Database independent interface for Perl

SYNOPSIS
      use DBI;
------- - --- - - - -------------

Добавлено @ 13:45
Поясни плиз
Цитата
The "LongReadLen" attribute may be used to control the maximum
length of 'long' type fields (LONG, BLOB, CLOB, MEMO, etc.) which
the driver will read from the database automatically when it fetches
each row of data.

он может быть использован для контроля длины поля??? Так что ли?


а в этом коде что происхдит? он сначала "подготавливается" для того чтобы можно было получать данные из Blob'а что ли?
Код

  $dbh->{LongReadLen} = $dbh->selectrow_array(qq{
      SELECT MAX(OCTET_LENGTH(long_column_name))
      FROM table WHERE ...
  });
  $sth = $dbh->prepare(qq{
      SELECT long_column_name, ... FROM table WHERE ...
  });

Автор: DEER 21.11.2005, 13:54
Всё! по ходу понял!

Короче этот LongReadLen отвечает за максимальную длину выбираемых полей, по умолчанию он стоит в "0", что означает что длинные поля скорее всего не будут выбираться.
Для выбора этих полей сначала надо произвести изменение этого аттрибута
Код

$dbh->{LongReadLen} = $dbh->selectrow_array(qq{    
      SELECT MAX(OCTET_LENGTH(dump))    
      FROM pdump WHERE id = '1'
  });

и потом уже можно делать выборку из БД
Код

$sth = $dbh->prepare(qq{    
      SELECT ldump FROM pdump WHERE id = '1'    
  });

по идее должно заработать.

Правильно?

Автор: korob2001 21.11.2005, 21:34
Цитата

по идее должно заработать.

Правильно?

smile А почему ты не попробуешь? Хотя я вообще не пойму смысла хранения двоичных данных в базе данных. Может стоит подумать над тем, что бы их хранить отдельно, а в базу писать только ссылку?

Автор: DEER 22.11.2005, 09:32
Всё работает!!! Даже очень!!!

sharq Спасиба за ссылку!

korob2001Это не моя пререгатива, базу мне готовую дали smile

Автор: Kiber_rat 28.11.2005, 20:59
korob2001 Если хранить в базе ссылку на данные хранящиеся где-то в файлах то это нарушает целостность хранения данных и усложняет возможности для их архивироваия. С этой точки зрения хранение в базе двоичных данных - меньшее из зол. Я иногда использую хранение сериализованных данных в базе, что бы потом их можно было легко превратитьв структуру (хэш например), это тоже оправдывает хранение двоичных данных в базе.

Автор: korob2001 29.11.2005, 02:25
Да всё это понятно, но не дорого ли эта база будет обходиться, если в ней хранить изображения, mp3, flash файлы и т.п.?

Автор: Kiber_rat 29.11.2005, 07:36
Во всам важно чувство меры smile Кроме того это сильно зависит от массы факторов, начиная от предпологиемой пиковой посещаемости ресурса и заканчивая уже упомянутой необходимостью бэкапа (критичностью информации).

Автор: alSteve 15.4.2008, 19:41
Доброго дня!

Помогите пожалуйста разобраться в проблеме!
Есть код:
Код

$dbh->{LongReadLen} = $dbh->selectrow_array(qq{    
      SELECT MAX(OCTET_LENGTH(text))    
      FROM out_mail WHERE row_id = '156'});

$sth = $dbh -> prepare("SELECT  text from out_mail where row_id = 156"); 
$sth -> execute(); 
$file = $sth -> fetchrow_array(); 

print "Content-type: application/x-force-download\n";
print "Content-Disposition: attachment; filename=\"test.zip\"\n";
print "\n";
print $file;


в поле TEXT типа LONGBLOB (MySQL5) хранится zip-архив.
исходный размер архива 6714 байт. после выполнения вышеуказанного скрипта сохраняется файл test.zip размером 6732 байта и соответственно архив некорректный. Распаковать его не представляется возможным. 
Где моя ошибка?  :dash1 

Заранее благодарен!

Автор: yura_nev 16.4.2008, 08:08
после
Код
print "\n";
вставьте строку
Код
binmode STDOUT;

Автор: amg 16.4.2008, 08:49
Да, должно помочь, если в базе файл нормальный. Чтобы в этом убедится, посмотрите его размер сразу после извлечения из базы:
Код

use bytes;
print length($file), "\n";

Автор: alSteve 18.4.2008, 08:00
Цитата(yura_nev @ 16.4.2008,  08:08)
после
Код
print "\n";
вставьте строку
Код
binmode STDOUT;

большое спасибо!
заработало!

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