Каков наилучший способ поиска типа данных Long в базе данных Oracle?

Я работаю с базой данных Oracle, которая хранит HTML как тип данных Long. Я хотел бы запросить базу данных для поиска определенной строки в данных HTML, хранящихся в Long.

Я пробовал "выбрать * из ТАБЛИЦЫ, где КОЛОНКА как"% form% "". Это вызывает следующую ошибку Oracle, потому что «подобное» не поддерживается для типов данных Long.

ORA-00932: несогласованные типы данных: ожидаемый НОМЕР стал ДЛИННЫМ


person Community    schedule 20.04.2009    source источник


Ответы (5)


Вы можете использовать этот пример без использования временной таблицы:

DECLARE

  l_var VARCHAR2(32767); -- max length

BEGIN

FOR rec IN (SELECT ID, LONG_COLUMN FROM TABLE_WITH_LONG_COLUMN) LOOP
  l_var := rec.LONG_COLUMN;
  IF l_var LIKE '%350%' THEN -- is there '350' string?
    dbms_output.put_line('ID:' || rec.ID || ' COLUMN:' || rec.LONG_COLUMN);
  END IF;
END LOOP;

END;

Конечно, возникает проблема, если LONG содержит более 32 КБ символов.

person Martin Selecký    schedule 09.12.2014

Вы не можете искать LONG напрямую. LONG не могут появляться в предложении WHERE. Они могут отображаться в списке SELECT, поэтому вы можете использовать его, чтобы сузить количество строк, которые вам нужно изучить.

Oracle рекомендовала преобразовывать LONG в CLOB как минимум в последних двух выпусках. Ограничений на CLOB меньше.

person Shea    schedule 20.04.2009
comment
Тем не менее, описание ALL_TRIGGERS показывает TRIGGER_BODY как длинное. Рекомендовать, а потом сами не делать? странный... - person xQbert; 15.01.2012
comment
То же самое с DBA_IND_EXPRESSIONS. Если вы описываете это, COLUMN_EXPRESSION по-прежнему является длинным типом в 11GR2. - person pahariayogi; 03.03.2015
comment
Я бы хотел, чтобы Oracle исправила и словарные столбцы LONG, но, учитывая размер и сложность словаря данных, я подозреваю, что обновление всех LONG до CLOB было бы огромным упражнением, которое могло бы привести к повреждению во время обновлений, поэтому Oracle до сих пор решила оставить его. в одиночестве. - person William Robertson; 20.02.2018
comment
Если вы ищете текст триггера, вы можете использовать вместо него DBA_SOURCE, USER_SOURCE или ALL_SOURCE. - person ScrappyDev; 07.09.2018

Пример:

create table longtable(id number,text long);

insert into longtable values(1,'hello world');
insert into longtable values(2,'say hello!');

commit;

create or replace function search_long(r rowid) return varchar2 is
temporary_varchar varchar2(4000);
begin
select text into temporary_varchar from longtable where rowid=r;
return temporary_varchar;
end;
/


SQL> select text from longtable where search_long(rowid) like '%hello%';                                                                              

TEXT
--------------------------------------------------------------------------------
hello world
say hello!

Но будь осторожен. Функция PL / SQL будет искать только первые 32 КБ LONG.

person Thomas Aregger    schedule 21.04.2009
comment
Если вы хотите удалить совпадающие строки, см. Этот ответ: stackoverflow.com/questions/2381203/ - person Sam; 05.03.2010
comment
что означает rowid = r. Я имею в виду выделение текста во временную_варчар из длинной таблицы, где rowid = r; - person AlphaBetaGamma; 18.12.2014

Сначала преобразуйте столбец типа LONG в тип CLOB, затем используйте условие LIKE, например:

CREATE TABLE tbl_clob AS
   SELECT to_lob(long_col) lob_col FROM tbl_long;

SELECT * FROM tbl_clob WHERE lob_col LIKE '%form%';
person nikli    schedule 25.04.2016

Не используйте LONG, вместо этого используйте CLOB. Вы можете индексировать и искать такие CLOB, как VARCHAR2.

Кроме того, запрос с ведущим подстановочным знаком (%) ВСЕГДА приводит к полному сканированию таблицы. Вместо этого изучите индексы Oracle Text.

person Neil Kodner    schedule 21.04.2009