我有一个XML存储在CLOB中。为了显示来自XML的特定数据,我需要运行各种substr和instr函数。
我当前的代码使用varchar2(32000)变量处理它,如下所示:
select xml_data into xmlclob
from test.test_data_v6
where test_id =r1.test_id;
start_position := dbms_lob.instr(xmlclob,'<DataSheet>',1,1)+11;
end_position := dbms_lob.instr(xmlclob,'</DataSheet>',start_position,1);
l_str := (dbms_lob.substr(xmlclob, end_position - start_position, start_position));
l_str := substr(l_str, instr(l_str, '<SummaryParameters>'),instr(l_str, '</SummaryParameters>')-instr(l_str, '<SummaryParameters>')+20);
select xml_data into xmlclob
from test.test_data_v6_temp
where test_id =r1.test_id;
start_position := dbms_lob.instr(xmlclob,'<DataSheet>',1,1)+11;
end_position := dbms_lob.instr(xmlclob,'</DataSheet>',start_position,1);
l_str := dbms_lob.substr(xmlclob, end_position - start_position, start_position);
l_str1 := substr(l_str, instr(l_str, '<SummaryParameters>'), instr(l_str, '</SummaryParameters>')-instr(l_str, '<SummaryParameters>')+20);
我编写了一个匿名块来测试子字符串的限制,如下所示:
declare
error_reason varchar2(32000);
start_position number;
end_position number;
str_length number;
str_length2 number;
l_clob2 clob;
l_str varchar2(32000);
e_clob clob;
temp_clob clob;
begin
select xml_data into l_clob2 from test.test_data_v6_temp where test_id=(hard coded the test id);
start_position := dbms_lob.instr(l_clob2,'<DataSheet>',1,1)+11;
dbms_output.put_line('startposition='||start_position);
end_position := dbms_lob.instr(l_clob2,'</DataSheet>',start_position,1);
dbms_output.put_line('end position='||end_position);
str_length := end_position-start_position;
str_length2 := 30000;
dbms_output.put_line('str_length='||str_length);
dbms_output.put_line('str_length2='||str_length2);
dbms_output.put_line('str_length='||str_length);
temp_clob := dbms_lob.substr(l_clob2, str_length2, start_position);
--dbms_output.put_line('temp_clob1='||temp_clob);
--temp_clob := substr(temp_clob, instr(temp_clob, '<SummaryParameters>'), instr(temp_clob, '</SummaryParameters>')-instr(temp_clob, '<SummaryParameters>')+20);
insert into test.temp values(temp_clob);
commit;
end;
--select * from test.temp
我注释掉了第二个子字符串,只是为了看看如果我将str_length更改为32000以下,表是否会填充数据,并且它确实被填充了。
这是我的输出
startposition=202134
end position=237746
str_length=35612
str_length2=30000
declare
start_position number;
end_position number;
str_length number;
str_length2 number;
sp2 number;
ep2 number;
str_len number;
str_len2 number;
l_clob2 clob;
temp_clob clob;
temp_clob2 clob;
begin
select xml_data into l_clob2 from test.test_data_v6_temp where test_id=211230309;
start_position := dbms_lob.instr(l_clob2,'<DataSheet>',1,1)+11;
dbms_output.put_line('startposition='||start_position);
end_position := dbms_lob.instr(l_clob2,'</DataSheet>',start_position,1);
dbms_output.put_line('end position='||end_position);
str_length := end_position-start_position;
dbms_output.put_line('Original clob size: ' || dbms_lob.getlength(l_clob2));
dbms_lob.createtemporary(temp_clob, false);
while str_length > 0
loop
str_length2 := least(str_length, 32768);
str_length := str_length - str_length2;
dbms_lob.copy(temp_clob, l_clob2, str_length2,dbms_lob.getlength(temp_clob) + 1, start_position);
start_position := start_position + str_length;
end loop;
dbms_output.put_line('Copied clob 1 size: ' || dbms_lob.getlength(temp_clob));
sp2 := dbms_lob.instr(temp_clob,'<SummaryParameters>')+20;
dbms_output.put_line('sp2 = '|| sp2);
ep2 := instr(temp_clob, '</SummaryParameters>');
dbms_output.put_line('ep2 = '|| ep2);
str_len :=ep2 - sp2;
dbms_lob.createtemporary(temp_clob2, false);
while str_len > 0
loop
str_len2 := least(str_len, 32768);
str_len := str_len - str_len2;
dbms_lob.copy(temp_clob2, temp_clob, str_len2,dbms_lob.getlength(temp_clob2) + 1, sp2);
sp2 := sp2 + str_len;
end loop;
dbms_output.put_line('Copied 2 clob size: ' || dbms_lob.getlength(temp_clob2));
insert into test.temp values(temp_clob2);
commit;
end;
下面是我的输出:
startposition=202134
end position=237746
Original clob size: 1723831
Copied clob 1 size: 35612
sp2 = 703
ep2 = 0
Copied 2 clob size: 0
下面是一个使用copy
过程避免切换到varchar2
的示例:
dbms_output.put_line('Original clob size: ' || dbms_lob.getlength(l_clob2));
dbms_lob.createtemporary(temp_clob, false);
while str_length > 0 loop
str_length2 := least(str_length, 32768);
str_length := str_length - str_length2;
dbms_lob.copy(temp_clob, l_clob2, str_length2,
dbms_lob.getlength(temp_clob) + 1, start_position);
start_position := start_position + str_length2;
end loop;
dbms_output.put_line('Copied clob size: ' || dbms_lob.getlength(temp_clob));
使用我填充的'xml'值,它给出了输出:
startposition=17
end position=40456
str_length=40439
str_length2=30000
str_length=40439
Original clob size: 40473
Copied clob size: 40439
因此temp_clob
包含原始CLOB的40K+“子字符串”。
您可以通过使用以下内容从XML中提取相关数据来避免这项工作:
select xmlquery('*/DataSheet/SummaryParameters/*'
passing xmltype(xml_data) returning content))
from ...
或在旧版本中(在11GR2中不推荐):
select extract(xmltype(xml_data), '*/DataSheet/SummaryParameters/*')
from ...
其中任何一个都将为您提供
中的部分。从您的问题中看不出datasheet
是顶部元素,还是summaryparameters
直接位于该元素内部,因此您可能需要尝试将通配符放在哪里。有关XMLQuery的更多信息请参见文档。
declare
start_position number;
end_position number;
str_length number;
str_length2 number;
l_clob2 clob;
temp_clob clob;
temp_clob2 clob;
begin
select xml_data into l_clob2 from t42 where id = 1;
start_position := dbms_lob.instr(l_clob2,'<DataSheet>',1,1)+11;
dbms_output.put_line('startposition='||start_position);
end_position := dbms_lob.instr(l_clob2,'</DataSheet>',start_position,1);
dbms_output.put_line('end position='||end_position);
str_length := end_position-start_position;
dbms_lob.createtemporary(temp_clob, false);
while str_length > 0 loop
str_length2 := least(str_length, 32768);
str_length := str_length - str_length2;
dbms_lob.copy(temp_clob, l_clob2, str_length2,
dbms_lob.getlength(temp_clob) + 1, start_position);
start_position := start_position + str_length2;
end loop;
dbms_output.put_line('temp_clob length: ' || dbms_lob.getlength(temp_clob));
start_position := dbms_lob.instr(temp_clob,'<SummaryParameters>',1,1)+19;
dbms_output.put_line('startposition='||start_position);
end_position := dbms_lob.instr(temp_clob,'</SummaryParameters>',start_position,1);
dbms_output.put_line('end position='||end_position);
str_length := end_position-start_position;
dbms_lob.createtemporary(temp_clob2, false);
while str_length > 0 loop
str_length2 := least(str_length, 32768);
str_length := str_length - str_length2;
dbms_lob.copy(temp_clob2, temp_clob, str_length2,
dbms_lob.getlength(temp_clob2) + 1, start_position);
start_position := start_position + str_length2;
end loop;
dbms_output.put_line('temp_clob2 length: ' || dbms_lob.getlength(temp_clob2));
insert into t42 values (2, temp_clob2);
end;
/
给出(用我编造的数据):
startposition=17
end position=40456
temp_clob length: 40439
startposition=220
end position=420
temp_clob2 length: 200
我正在使用spark 2.4.2读取包含600条记录的csv。最后100条记录有大量数据。我遇到的问题是, 我已经增加了到2g(最大允许设置)和火花驱动程序内存到1g,能够处理更多的记录,但仍然不能处理csv中的所有记录。 我试着翻页600条记录。e、 对于6个分区,我可以在每个分区处理100条记录,但由于最后100条记录太多,因此会发生缓冲区溢出。 在这种情况下,最后100条记录很大,但这可能是
我有一个PL/SQL过程,它对参数执行大量s。我想删除长度限制,所以尝试将其更改为。 工作正常,但性能受到影响,所以我做了一些测试(基于2005年的这些测试)。 更新:我可以用不同的Oracle版本和不同的硬件在几个不同的实例上重现这个过程,总是明显比慢,而且比慢得多。 Bob的结果和上面链接中的测试讲述了一个不同的故事。 有人能解释这一点吗,或者至少重现鲍勃或我的结果吗?谢了! 测试结果:
问题内容: 我知道XHTML不支持嵌套的表单标记,但是我仍然没有找到解决该问题的优雅方法。 有人说您不需要它,并且他们无法想到是否需要这样做。嗯,我个人不认为一个场景,我的 没有 需要它。 让我们看一个非常简单的例子: 您正在制作一个博客应用程序,您有一个表单,其中包含一些用于创建新帖子的字段以及一个带有“操作”(如“保存”,“删除”,“取消”)的工具栏。 我们的目标是以 不需要JavaScrip
问题内容: 我正在使用扫描仪的方法读取文本文件行。但是,当我在文件行中达到一定大小时,扫描仪不再允许我读取它,而是返回一个空行。 我应该如何配置缓冲区以接收大量数据? 只是一个文件,行中有许多整数,并用空格分隔。例如,一行中有40000个整数。(请注意,它适用于小于或等于10000整数的文件行,但不适用于40000) 234 544 765 45 34 67 67 87 98 43 [… n =
刚刚开始使用scala和spark来运行这个简单的程序:
我有一个向CLOB追加字符串的场景。我遇到的问题是,一旦CLOB达到一定大小,如果我试图向CLOB追加更多内容,就会出现ORA-06502:PL/SQL:numeric或value错误。我假设它的大小已经用完了,但我不知道如何克服这个问题(即指定如何使clob变大)。 有人能帮帮我吗。 我就是这样宣布我的衣服的... 然后我像这样插入它.... 谢谢