powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / clob построчно
25 сообщений из 51, страница 2 из 3
clob построчно
    #35971605
mvici
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VBRНапример такой вариант.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
...
  public static oracle.sql.CLOB replaceClob(oracle.sql.CLOB cont, String find,String replace) throws SQLException,IOException {
...
               char buffer[] = new char[ 8192 ];
               while((length=is.read(buffer, 0 , 8192 )) != - 1 )
                 buf.append(buffer, 0 ,length);
               content=buf.toString();
               content=replace(content,find,replace);
               //content.replaceAll(find,replace);
...


Кстати, а что вы обычно предпринимаете, когда заменяемая строка делится кусками размером 8192 на две части?
...
Рейтинг: 0 / 0
clob построчно
    #35971677
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mviciVBR
Код: plaintext
1.
2.
               while((length=is.read(buffer, 0 , 8192 )) != - 1 )
                 buf.append(buffer, 0 ,length);
Кстати, а что вы обычно предпринимаете, когда заменяемая строка делится кусками размером 8192 на две части?А где ты видишь замену в маленьком буфере? :)
...
Рейтинг: 0 / 0
clob построчно
    #35972191
r900000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет все равно
select
*
from (
select
extract(column_value,'/b/text()').getStringVal() str
from
table(
xmlsequence(xmltype(
'<a><b>'
||
replaceclob ((select t from t2),chr(10),'</b><b>')
||
'</b></a>'
).extract('//b')
)
)
)
возвращает одну пустую строку, может версия oracle влияет у меня 9(в таблице одно заполненое поле clob и одна запись да и текста в нем на 9 мгб).
Ну и естетсвенно это не работает
with t1 as (
select rownum rn, str from (
select extract(column_value,'/b/text()').getStringVal() str from
table( xmlsequence(xmltype('<a><b>'||
java_pck.replaceclob ((select reestr from sverkareestr t where t.id=1),chr(10),'</b><b>')||
'</b></a>').extract('//b'))))
)
SELECT rn, (REGEXP_SUBSTR(str,
'[^ ]+', 1, Level)) wrd
FROM t1
CONNECT BY
prior rn=rn and prior dbms_random.random is not null
and
REGEXP_SUBSTR(str, '[^ ]+', 1, LEVEL) IS not NULL

а к тому же здесь REGEXP_SUBSTR

Что касается
WITH ttt
AS (SELECT DBMS_LOB.getlength (txt) - DBMS_LOB.getlength (REPLACE (txt, CHR (13), '')) ln_cnt
FROM loader.bonus_mates)
SELECT lvl num, to_char(','||SUBSTR (txt, start_pos+2, end_pos - start_pos -2)) line
FROM (SELECT LEVEL lvl, NVL (DBMS_LOB.INSTR (txt, CHR (13) || CHR (10), 1, LEVEL - 1), 0) start_pos
,DBMS_LOB.INSTR (txt, CHR (13) || CHR (10), 1, LEVEL) end_pos, txt
FROM loader.bonus_mates
CONNECT BY LEVEL < (SELECT ln_cnt FROM ttt))

Что за строка CONNECT BY LEVEL < (SELECT ln_cnt FROM ttt))

у меня на эту строку ошибка выдается
...
Рейтинг: 0 / 0
clob построчно
    #35972423
mvici
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ElicmviciVBR
Код: plaintext
1.
2.
               while((length=is.read(buffer, 0 , 8192 )) != - 1 )
                 buf.append(buffer, 0 ,length);
Кстати, а что вы обычно предпринимаете, когда заменяемая строка делится кусками размером 8192 на две части?А где ты видишь замену в маленьком буфере? :)
Черт, не заметил. Но тогда непонятно, зачем тут Ява, если там аналогично гоняются байты из буфера в буфер.
...
Рейтинг: 0 / 0
clob построчно
    #35972682
VBR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBR
Гость
Тогда по шагам.
что выдает (заменяет или нет chr(10) на '</b><b>'):
Код: plaintext
1.
select replaceclob ((select t from t2),chr( 10 ),'</b><b>') from dual;

потом
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select 
'<a><b>'
||
replaceclob ((select t from t2),chr( 10 ),'</b><b>')
||
'</b></a>'
from dual;

2 mvici, Java использовал для replace в clob'e.
Пробовал через dbms_lob - тормозило.

Прикольно. Сейчас попробовал, на 10g обычный replace отработал ок.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select 

extractvalue(column_value,'/b/c[1]') c1,
extractvalue(column_value,'/b/c[2]') c2,
extractvalue(column_value,'/b/c[3]') c3,
extractvalue(column_value,'/b/c[4]') c4,
extractvalue(column_value,'/b/c[5]') c5,
extractvalue(column_value,'/b/c[6]') c6,
extractvalue(column_value,'/b/c[7]') c7

from
table(xmlsequence(xmltype(
 '<a><b><c>'
    ||
    replace (
      replace ((select f from clob_table t where t.id= 2431  ),chr( 13 )||chr( 10 ),'</c></b><b><c>')
    ,chr( 9 ),'</c><c>')||'</c></b></a>' 
  ).extract('//b')
  )
f - clob 650 кб.
...
Рейтинг: 0 / 0
clob построчно
    #35972707
mvici
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VBR
2 mvici, Java использовал для replace в clob'e.
Пробовал через dbms_lob - тормозило.

А в PL/SQL вы использовали временные clob с кэшированием? аналогично вот этому вызову явы:
Код: plaintext
1.
  clob = CLOB.createTemporary(con, true, CLOB.DURATION_SESSION);
здорово ускоряет производительность.
...
Рейтинг: 0 / 0
clob построчно
    #35972763
VBR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
VBR
Гость
Использовал DBMS_LOB.CREATETEMPORARY(v_lob, true);
Но сейчас для меня все это уже не имеет смысла, раз обычный replace для 10g работает c clob.
...
Рейтинг: 0 / 0
clob построчно
    #35974396
r900000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Запрос
select replaceclob ((select t from t2),chr(10),'</b><b>') from dual;
возвращает одну пустую строку.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
clob построчно
    #39020713
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А что делать если clob поле у нас на 300 мегабайт?
...
Рейтинг: 0 / 0
clob построчно
    #39020717
estro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VBR,
спустя 6 лет, может подскажете как разбить построчно clob поле на 300 мегабайт. Вообще задача стоит разместить это поле построчно в таблицу.
...
Рейтинг: 0 / 0
clob построчно
    #39020719
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro,

Застрелиться.
...
Рейтинг: 0 / 0
clob построчно
    #39020721
Vint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro,
чисто для собственного интереса.... а зачем было грузить 300 метров в базу?)))
не проще было loaderом загрузить как любой csv..... или стрелять себе в ногу опять становиться модным?)
...
Рейтинг: 0 / 0
clob построчно
    #39020732
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
estro,

читай последовательными кусками и ищи разделители уже в прочитанном куске. Если разделить более одного символа, читать куски с перекрытием.
Но вероятно быстрее будет выгрузить и загрузить лоадером/внешней таблицей.
...
Рейтинг: 0 / 0
clob построчно
    #39257473
Dennica
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Писал для себя сегодня:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
type tp_clob_list is table of clob;
function splitcloblines(p_clob in clob) return tp_clob_list pipelined
is
	l_cloblen       number;
	l_buffersize    number          := 32767;
	l_clobpos       number          := 1;
	l_bufferpos     number          := 1;
	l_line          clob;
	l_chunk         varchar2(32767) := '';
	l_buffer        varchar2(32767) := '';
	l_pos           number          := 0;
begin
	l_cloblen := dbms_lob.getlength(p_clob);

	dbms_lob.createtemporary(l_line, true);

	while l_clobpos < l_cloblen
	loop
		dbms_lob.read(lob_loc => p_clob, amount => l_buffersize, offset => l_clobpos, buffer => l_buffer);
		l_clobpos := l_clobpos + l_buffersize;

		l_bufferpos := 1;
		loop
			l_pos := instr(l_buffer, chr(10), l_bufferpos);

			l_chunk := '';

			if l_pos > 0
			then
				l_chunk := substr(l_buffer, l_bufferpos, l_pos - l_bufferpos - 1);
			elsif l_pos = 0
				and l_clobpos >= l_cloblen
			then
				l_chunk := substr(l_buffer, l_bufferpos);
			end if;

			if length(l_chunk) > 0 then
				dbms_lob.writeappend(l_line, length(l_chunk), l_chunk);
			end if;


			if length(l_chunk) > 0
				or (l_pos = 0
					and l_clobpos >= l_cloblen
					and dbms_lob.getlength(l_line) > 0
				)
			then
				pipe row( l_line );
				dbms_lob.trim(l_line, 0);
			end if;

			if l_pos = 0
			then
				exit;
			else
				l_bufferpos := l_pos + 1;
			end if;

		end loop;

	end loop;

	return;

exception
	when others then
		begin
			raise_application_error(-20000
				, dbms_utility.format_error_stack
					|| dbms_utility.format_error_backtrace
			);
		end;
end;
...
Рейтинг: 0 / 0
clob построчно
    #39260075
Dennica
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Немного дописал, т.к. понадобилось разделять по crlf. Сделал учет перекрытий при считывании. Убрал отбрасывание разделителя, теперь строка возвращается с ним.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
	type tp_clob_list is table of clob;
	function splitcloblines(
		p_clob	in		clob
		,p_delimiter	varchar2	:= chr(10)
	) return tp_clob_list pipelined
	-- --------------------------------------------------------------------
	is
		l_cloblen		number;
		l_buffersize	number			:= 20000;
		l_clobpos		number			:= 1;
		l_bufferpos		number			:= 1;
		l_line			clob;
		l_chunk			varchar2(30000)	:= '';
		l_chunkrest		varchar2(30000)	:= '';
		l_buffer		varchar2(30000)	:= '';
		l_pos			number			:= 0;
		l_delimiterlen	varchar2(256)	:= 1;
	begin
		l_cloblen := dbms_lob.getlength(p_clob);
		l_delimiterlen := length(p_delimiter);

		if l_delimiterlen > 10
		then
			raise_application_error(-20000, 'The maximum delimiter size is 10');
		end if;

		dbms_lob.createtemporary(l_line, true);

		while l_clobpos <= l_cloblen
		loop
			dbms_lob.read(lob_loc => p_clob, amount => l_buffersize, offset => l_clobpos, buffer => l_buffer);
			l_buffer := l_chunkrest || l_buffer;
			l_clobpos := l_clobpos + l_buffersize;

			l_bufferpos := 1;
			loop
				l_pos := instr(l_buffer, p_delimiter, l_bufferpos);

				l_chunk := '';

				if l_pos > 0
				then
					l_chunk := substr(l_buffer, l_bufferpos, l_pos - l_bufferpos + l_delimiterlen);
					dbms_lob.writeappend(l_line, length(l_chunk), l_chunk);
				elsif l_pos = 0
				then

					if l_clobpos > l_cloblen
					then
						l_chunk := substr(l_buffer, l_bufferpos);
					else
						l_chunk := substr(l_buffer, l_bufferpos);

						if l_delimiterlen > 1
						then
							l_chunkrest := substr(l_chunk, least(l_delimiterlen - 1, length(l_chunk)) * -1);
							l_chunk := substr(l_chunk, 1, length(l_chunk) - length(l_chunkrest));
						end if;

					end if;

					if length(l_chunk) > 0
					then
						dbms_lob.writeappend(l_line, length(l_chunk), l_chunk);
					end if;

				end if;

				if l_pos > 0
					or (l_pos = 0
					and l_clobpos > l_cloblen
					and dbms_lob.getlength(l_line) > 0
					)
				then
					pipe row (l_line);
					dbms_lob.trim(l_line, 0);
					l_chunkrest := '';
				end if;

				if l_pos = 0
				then
					exit;
				else
					l_bufferpos := l_pos + l_delimiterlen;
				end if;

			end loop;

		end loop;

		return;
	end;
...
Рейтинг: 0 / 0
clob построчно
    #39273110
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
givanovПишем простой автомат. Должно работать быстрее всего.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
declare 
  cl clob:= 'qwerty
asdfgh
zxcvb';
  l_amount pls_integer:= 1;
  l_length pls_integer:= dbms_lob.getlength(cl);
  token varchar2(4000);
  sobch varchar2(4000);
begin
  for i in 1..l_length loop
    dbms_lob.read
    ( lob_loc => cl
    , amount => l_amount
    , offset => i
    , buffer => token
    );
    if token = chr(10) then
      dbms_output.put_line(sobch);
      dbms_output.put_line('----------');
      sobch:= null;
    elsif i = l_length then
      sobch:= sobch||token;
      dbms_output.put_line(sobch);
      dbms_output.put_line('----------');
    else
      sobch:= sobch||token;
    end if;
  end loop;
end;




Проверил несколько вариантов - вариант от givanov действительно самый быстрый.

Для малых объемов самый компактный наверное такой

Код: plsql
1.
2.
3.
4.
select level as id,
           cast(REGEXP_SUBSTR(cl, '[^' || chr(13) || chr(10) || ']+', 1, level) as varchar2(200)) as data
      from dual
    connect by REGEXP_SUBSTR(cl, '[^' || chr(13) || chr(10) || ']+', 1, level) is not null
...
Рейтинг: 0 / 0
clob построчно
    #39273131
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorDgivanov
Код: plsql
1.
2.
3.
4.
5.
l_amount pls_integer:= 1;
…
  for i in 1..l_length loop
…
    , amount => l_amount

Проверил несколько вариантов - вариант от givanov действительно самый быстрый.Slow-by-slow в отношении LOB-а - это slow-by-slow в квадрате.
...
Рейтинг: 0 / 0
clob построчно
    #39273285
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dennica,

спасибо! Воспользовался этим решением.
...
Рейтинг: 0 / 0
clob построчно
    #39273286
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

согласен
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
clob построчно
    #39832397
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VBRНапример такой вариант.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
create or replace and compile java source named out_reestr as
import java.io.BufferedReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.*;
import java.util.StringTokenizer;
import java.sql.*;
import oracle.sql.CLOB;
import oracle.jdbc.driver.*;


 public class OUT_CSV_REESTR {

 public static String  replace(String str, String find,String replace) {
    StringBuffer sb = new StringBuffer("");
    int index;
    int offset = 0;
    for(index = str.indexOf(find); index != -1; index = str.indexOf(find)){
      sb.append( str.substring(0, index) );
      sb.append( replace );
      offset = index + find.length();
      str = str.substring( offset );
    }
   sb.append(str);
   return sb.toString();
}


  public static oracle.sql.CLOB replaceClob(oracle.sql.CLOB cont, String find,String replace) throws SQLException,IOException {

      String content;
      int length;
      StringBuffer buf;
      CLOB clob=null;
      java.io.Writer out=null;
      Connection con = null;
        try {
            if (cont != null) {
               buf = new StringBuffer("");
               Reader is = cont.getCharacterStream();
               char buffer[] = new char[8192];
               while((length=is.read(buffer,0,8192)) != -1)
                 buf.append(buffer,0,length);
               content=buf.toString();
               content=replace(content,find,replace);
               //content.replaceAll(find,replace);
             }
             else
             return null;
             
            con=new OracleDriver().defaultConnection();
            clob = CLOB.createTemporary(con, true, CLOB.DURATION_SESSION);
            out=clob.setCharacterStream(0);
            out.write(content);
             
        } catch (Exception ex) {
           return null;
        }
        finally {
           if(out!=null) out.close();
     }
        return clob;
    }
}



Попробовал, работает в 2-3 раза быстрее стандартной replaceAll.
Вероятно из-за того, что replaceAll поддерживает регулярные выражения.

Огромное вам человеческое спасибо за выложенный кусок кода. Пол дня курил инет, не мог понять как clob инициализировать в хранимке, а тут есть! Спасибо!
...
Рейтинг: 0 / 0
clob построчно
    #39832459
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorDкак clobПро clob откуда узнал?
...
Рейтинг: 0 / 0
clob построчно
    #39832576
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-,

Clob инициализируется через Connection (как один из немногих вариантов). Не мог понять, как в хранимке описать подключение к собственной базе. Решение было в коде - new OracleDriver().defaultConnection();

Код: java
1.
2.
3.
4.
       Connection con = null;
       CLOB clob = null;
       con = new OracleDriver().defaultConnection();
       clob = CLOB.createTemporary(con, true, CLOB.DURATION_SESSION);
...
Рейтинг: 0 / 0
clob построчно
    #39832779
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorDНе мог понять, как в хранимке описать подключение к собственной базе.
И правильно. Штатную документацию читает только беспонтовое ламерьё.
...
Рейтинг: 0 / 0
clob построчно
    #39832783
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousIgorDНе мог понять, как в хранимке описать подключение к собственной базе.
И правильно. Штатную документацию читает только беспонтовое ламерьё.

Я читать не умею. Только писать :)
...
Рейтинг: 0 / 0
clob построчно
    #39832786
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorDТолько писать
Культурный обмен однако.
В подписи указан Киев, в то время как фольклорный элемент, которому приписывается авторство тезиса, был родом с Чукотки.
...
Рейтинг: 0 / 0
25 сообщений из 51, страница 2 из 3
Форумы / Oracle [игнор отключен] [закрыт для гостей] / clob построчно
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]