如何对CLOB字段的内容进行排序

时间:2014-02-21 08:14:21

标签: sql oracle11g

我有一个表格,某些字段为CLOB类型,CLOB中的内容由某些分隔符(例如'|')分隔,并且字段中的内容通常如下所示: name2|name1|name3...,实际上内容的长度超过40000个字符,那么有sort the content by asc的方法吗?我希望看到这样的内容:name1|name2|name3...

任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:2)

如果它甚至可以远程实现,我强烈建议您更改数据模型 - 添加名称的详细信息表。这将解决你未来痛苦的很多

无论如何,如果您绝对需要在CLOB字段中存储以管道分隔的名称列表,我建议采用这种方法:

  • 将CLOB分成不同的行(使用流水线函数)
  • 对行进行排序
  • 将行聚合为新的CLOB

这种方法的实施(有点天真和未经测试):

create type stringtabletype as table of varchar2(4000);

create or replace function split_CLOB(p_Value     in CLOB,
                                      p_Separator in varchar2 default '|')
  return stringtabletype
  pipelined as
  l_Offset number default 1;
  l_Str    varchar2(4000);
  idx      number;
begin
  idx := dbms_lob.instr(lob_loc => p_Value,
                        pattern => p_Separator,
                        offset  => l_Offset);
  dbms_output.put_line(idx);
  while (idx > 0)
  loop
    l_Str := dbms_lob.substr(p_Value,
                             idx - l_Offset,
                             l_Offset);
    pipe row(l_Str);
    l_Offset := idx+1;
    idx      := dbms_lob.instr(p_Value,
                               p_Separator,
                               l_Offset);
    dbms_output.put_line(idx);
  end loop;
  -- pipe remainder of string
  l_Str := dbms_lob.substr(p_Value,
                           dbms_lob.getlength(p_Value) - l_Offset + 1,
                           l_Offset);
  pipe row(l_str);
  return;
end;

create or replace function sort_stringtabletype(p_Values in stringtabletype)
  return stringtabletype as
  l_Result stringtabletype;
begin
  select column_value bulk collect
    into l_Result
    from table(p_Values)
   order by column_value;
  return l_Result;
end;

create or replace function stringtabletype_to_CLOB(p_Values    in stringtabletype,
                                                   p_Separator in varchar2 default '|')
  return CLOB as
  l_Result CLOB;
begin
  dbms_lob.createtemporary(l_Result, false);
  for i in 1 .. p_Values.count - 1
  loop
    dbms_lob.writeappend(l_Result,
                         length(p_Values(i)),
                         p_Values(i));
    dbms_lob.writeappend(l_Result,
                         length(p_Separator),
                         p_Separator);
  end loop;
  dbms_lob.writeappend(l_Result,
                       length(p_Values(p_Values.count)),
                       p_Values(p_Values.count));
  return l_Result;
end;

使用示例:

select stringtabletype_to_CLOB (
  sort_stringtabletype(
    split_CLOB('def|abc|ghic', '|')
  )
) from dual

然后您可以使用像

这样的UPDATE语句
  update my_table
   set clob_field = stringtabletype_to_CLOB (
      sort_stringtabletype(
        split_CLOB(my_table, '|')
      )