Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разбиение CLOB-текста на строки в поля таблицы 
V
    Опции темы
davidoffpk
Дата 3.5.2010, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 1.3.2010

Репутация: нет
Всего: 1



Начинаю программировать. Версия Oracle 10g. Решил написать программу, которая будет брать текст из одного поля одной таблицы и раскидывать его по строкам в поля другой таблицы.

Вот только где-то ошибка... Выводится все время только 2-я строка текста. Помогите, пожалуйста

Беру данные из таблицы Source, в ней 2 столбца - ID, Content. В последнем поле столбца Content запись:

Content
Я
Я не
Я не умею
Я не умею писать
Я не умею писать на
Я не умею писать на PL\SQL

Раскидываю в таблицу Source_out.

Код:

Код

DECLARE

c clob; -- переменная для чтения символов
m integer; -- длина записи поля Source.Content
f integer := 1; -- количество строк записи в поле Source.Content
l integer; -- переменая для подсчета символов конца строки "chr(10)"
n integer; -- размерность массива MY_LENGTH
k INTEGER := 1; -- переменная для чтения по строкам

TYPE is_length IS TABLE OF INTEGER
INDEX BY BINARY_INTEGER;

MY_LENGTH is_length;

TYPE is_source IS TABLE OF SOURCE%ROWTYPE
INDEX BY BINARY_INTEGER;

MY_SOUR is_source;

BEGIN

-- Подсчет количества строк

SELECT ID, CONTENT, 1 INTO MY_SOUR(1)
FROM SOURCE
WHERE ID = (select count(*) from source);

m := LENGTH(MY_SOUR(1).CONTENT);

for i in 1..m loop

c := substr(MY_SOUR(1).CONTENT, i, 1);

if c = chr(10) then

f := f+1;

end if;

end loop;

-- Разбиение по полям в табличку SOURCE_OUT

FOR i IN 1..f LOOP

select instr(MY_SOUR(1).CONTENT, chr(10),1,i) into l
from dual;

IF L>0 THEN

MY_LENGTH(i):=l;

END IF;

END LOOP;

MY_LENGTH(f) := m;

n:=MY_LENGTH.COUNT;

FOR j IN 1..n LOOP

INSERT INTO SOURCE_OUT
VALUES (j, SUBSTR(MY_SOUR(1).CONTENT, k, MY_LENGTH(j)-k+1));

k:=MY_LENGTH(j);

END LOOP;

-- Удаление лишних символов конца строки

for i in 2..f loop

update source_out
set content = (select ltrim(content, chr(10))
from source_out
where id = i);
end loop;

END;


PM MAIL   Вверх
Zloxa
Дата 4.5.2010, 08:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(davidoffpk @  3.5.2010,  20:10 Найти цитируемый пост)
брать текст из одного поля одной таблицы и раскидывать его по строкам в поля другой таблицы.


Код

create table src (id primary key, val)
as select 1,to_clob('Я
Я не
Я не умею
Я не умею писать
Я не умею писать на
Я не умею писать на PL\SQL
') from dual
union all select 2,to_clob('пора
пора нучиться
давно пора
ага')
from dual;
 
Table created
create table dst(src_id number
               ,line_num number
               ,line varchar2(4000)
               ,primary key (src_id,line_num)
               ,foreign key (src_id) references src(id)
               );
 
Table created
declare
  start_pos number;
  next_pos number;
  lob_len number;
  line dst.line%type;
  line_num number;
  itt number;
begin
  for i in (select * from src)
  loop
    lob_len := nvl(dbms_lob.getlength(i.val),0);
    start_pos := 1;
    line_num := 0;
    while start_pos < lob_len
    loop
      itt := 1;
      next_pos := nvl(dbms_lob.instr(i.val,chr(10),start_pos),0);
      if next_pos < 1
      then
        next_pos := start_pos + greatest(0,lob_len - start_pos + 1);
      end if;
      if next_pos - start_pos >= 4000
      then
        next_pos := start_pos + 4000;
        itt := 0;
      end if;
      exit when next_pos <= 0;
      line_num := line_num + 1;
      line := dbms_lob.substr(lob_loc => i.val
                              ,amount => next_pos - start_pos
                              ,offset => start_pos);
      insert into dst values ( i.id,line_num,line);
      start_pos := next_pos + itt;
    end loop;
  end loop;
end;
/
 
PL/SQL procedure successfully completed
select * from dst;
 
    SRC_ID   LINE_NUM LINE
---------- ---------- --------------------------------------------------------------------------------
         1          1 Я
         1          2 Я не
         1          3 Я не умею
         1          4 Я не умею писать
         1          5 Я не умею писать на
         1          6 Я не умею писать на PL\SQL
         2          1 пора
         2          2 пора нучиться
         2          3 давно пора
         2          4 ага
 
10 rows selected
 


Цитата(davidoffpk @  3.5.2010,  20:10 Найти цитируемый пост)
Вот только где-то ошибка... Выводится все время только 2-я строка текста. Помогите, пожалуйста

В вашем исходном тексте нет строки, которая не вызывала бы замечеание, потому указание ошибки бессмыслено. 
Во первых три цикла - избыток.
Во вторых не следует исползовать в pl/sq вызовы вроде "slect instr(var,val) into result from dual". SQL и PL/SQL это разные движки и большинство функций SQL имеют прототип в PL/SQL
В третьих с LOB работайте как с LOB а не с неявно преобразованными в varchar значениями

в пятых.. вот это убило навзнич:
Код

WHERE ID = (select count(*) from source);




--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
davidoffpk
Дата 4.5.2010, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 1.3.2010

Репутация: нет
Всего: 1



Большое спасибо! Я всего этого пока не знал. PL\SQL я только начинаю изучать, а программы нужны уже "сегодня".
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.0403 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.