Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.10.2010, 07:47   #1
eldalex
Пользователь
 
Регистрация: 01.09.2010
Сообщений: 52
По умолчанию Загруprf больших файлов в blob

добрый день! возникла такая проблема, необходимо с помощью пакетной процедуры оракла взять на клиентском приложении файл и поместить его в базу.
есть вот такая табличка:
Код:
create table test_lob
(
test_id number(12),
file_name varchar2(80),
file_size number,
orig_file blob
)
tablespace users
lob (orig_file)
store as securefile
(
tablespace users
enable storage in row
chunk 4096
pctversion 20
nocache
nologging
)
и пока я нашел единственное решение
Код:
create or replace directory my_files as 'C:\test_lob'
create sequence sq_lob_test;

declare
l_size number;
l_file_ptr bfile;
l_blob blob;
begin
l_file_ptr := bfilename('my_files', '10.mpg');
dbms_lob.fileopen(l_file_ptr);
l_size := dbms_lob.getlength(l_file_ptr);
insert into test_lob
(
test_id,
file_name,
file_size,
orig_file
)
values
(
sq_lob_test.nextval,
'file1',
null,
empty_blob()
)
returning orig_file into l_blob;
dbms_lob.loadfromfile(l_blob, l_file_ptr, l_size);
commit;
dbms_lob.close(l_file_ptr);
end;
в чем минус, эта процедура может взять файлы только с сервера, на клиентском приложении она вполне естественно не будет искать папку C:\test_lob. некоторые советуют использовать SQL*Loader но это тоже не подходит. вот собственно и вопрос, как можно загрузить файл с диска клиента (например тот же "C:\test_lob\10.mpg") в переменную типа blob?

ну или если уж совсем грубо перефразировать то ситуация такая. есть сервер напрямую к которому у меня нет доступа, я не могу например создать там свою папку и положить туда свой файл. есть SQL*Developer и есть файл на моем диске. sql*loader отсутствует. вот используя все что есть надо положить файл в базу процедуркой девелопера.

-----------------------------------------------------

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

Последний раз редактировалось eldalex; 01.10.2010 в 13:33.
eldalex вне форума Ответить с цитированием
Старый 01.10.2010, 14:54   #2
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

именно
нужно написать небольшую приладу для работы на клиентской стороне
читаем из файла, грузим в стрим, стрим сохраняем в блоб-поле таблицы
soleil@mmc вне форума Ответить с цитированием
Старый 12.10.2010, 08:08   #3
eldalex
Пользователь
 
Регистрация: 01.09.2010
Сообщений: 52
По умолчанию

в двух словах, я передаю файл кусочками по 32к в хранимую процедуру. файл принимается и сохраняется. 750 метров на данный момент лежат в тестовом поле.
принимает и сохраняет его следующая процедура:
(в базе есть запись с id 1 и полем ORIG_FILE типа blob = null)

Код:
procedure dbst_save_lob( 
  id in number
 ,blb in blob
) is
  bl blob;
  len     BINARY_INTEGER;
begin
 select ORIG_FILE into bl from test_lob_2 where ID=1 for update;
 --prog_debug_info_save(length(bl));
 if bl is null then 
   begin
     update test_lob_2 set ORIG_FILE=blb where ID=1;
   end;
 else
   begin
     len := length(blb);
     dbms_lob.writeappend(bl, len, blb);
     update test_lob_2 set ORIG_FILE=blb where ID=1;
   end;
 end if;
end;
вроде все работает, но есть одно но. можно ли как нибудь избежать постоянного select'а и update'а?
в том плане чтоб как то складировать это в какую нибудь переменную и update делать только в самом конце?

Последний раз редактировалось eldalex; 12.10.2010 в 08:14.
eldalex вне форума Ответить с цитированием
Старый 12.10.2010, 14:29   #4
eldalex
Пользователь
 
Регистрация: 01.09.2010
Сообщений: 52
По умолчанию

все, вроде как работает...
вобщем сделал так
Код:
procedure dbst_save_lob( 
  id in number
 ,blb in blob
) is
  len     BINARY_INTEGER;
begin
  if loc is null then 
    begin
      update test_lob set ORIG_FILE=EMPTY_BLOB (); 
      select ORIG_FILE into loc from test_lob where TEST_ID=1 for update;
      --prog_debug_info_save('старт');
    end;
  end if;  
  if loc is not null then
    begin 
      len := length(blb);
      if len<>32000 then
        begin
          dbms_lob.writeappend(loc, len, blb);
          update test_lob set ORIG_FILE=loc where TEST_ID=1;
          --prog_debug_info_save('финиш');
        end;
      else
        dbms_lob.writeappend(loc, len, blb);
      end if;  
    end;
  end if;
end;
loc это глобальная пакетная переменная - локатор, ставится в null при записи нового файла. и пока надцать раз вызывается процедура не меняется. в итоге всего один селект чтоб инициализировать локатор и всего один update при получении последней части файла. есть конечно одно но, вполне возможно, что когда нибудь, кто нибудь, попытается залить файл, размер которого будет кратен 32000 байт... вот тут то кривые руки и всплывут)) надо еще подумать...
eldalex вне форума Ответить с цитированием
Старый 12.10.2010, 16:10   #5
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

заведи еще один вх.параметр - is_eof
с последним куском его выставишь, а в коде проверишь и сделаешь апдейт
soleil@mmc вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
сложение больших чисел SacReD_89 Общие вопросы C/C++ 21 25.04.2010 16:42
Проблема с загрузкой больших файлов на сервер. Air PHP 6 03.02.2010 19:50
Передача больших файлов чрез сокет D_E_N Работа с сетью в Delphi 0 18.01.2010 19:17
С# Сложение больших чисел SL1CK Помощь студентам 4 23.11.2009 21:07
Открытие больших текстовых файлов sht0p0r Помощь студентам 4 16.12.2008 12:42