2009-04-20 5 views
10

Sto lavorando con un database Oracle che memorizza l'HTML come un tipo di dati lungo. Vorrei interrogare il database per cercare una stringa specifica all'interno dei dati HTML archiviati in Long.Qual è il modo migliore per cercare il tipo di dati Long all'interno di un database Oracle?

Ho provato, "selezionare * da TABLE dove COLUMN come '% form%'". Ciò causa il seguente errore Oracle poiché "mi piace" non è supportato per i tipi di dati lunghi.

ORA-00932: datatypes contradditori: numero previsto ottenuto LUNGO

risposta

9

Non è possibile cercare direttamente long. LONG non può apparire nella clausola WHERE. Possono apparire nell'elenco SELECT anche se puoi usarlo per restringere il numero di righe che dovresti esaminare.

Oracle ha raccomandato di convertire LONG in CLOB per almeno le ultime 2 versioni. Ci sono meno restrizioni su CLOB.

+9

Tuttavia, un descrivere sulla ALL_TRIGGERS mostra la TRIGGER_BODY come una lunga. Consiglia e poi non farlo da soli? dispari ... – xQbert

+0

Lo stesso con DBA_IND_EXPRESSIONS. Se lo descrivi, COLUMN_EXPRESSION è ancora un tipo lungo in 11GR2. – pahariayogi

+0

Vorrei che Oracle aggiustasse anche le colonne LONG del dizionario, ma vista la dimensione e la complessità del dizionario dei dati, sospetto che l'aggiornamento di tutti i LONG a CLOB sarebbe un esercizio enorme che rischierebbe la corruzione durante gli aggiornamenti e così Oracle ha deciso di partire solo –

0

Non utilizzare LONG, utilizzare invece CLOB. È possibile indicizzare e cercare i CLOB come VARCHAR2.

Inoltre, l'esecuzione di query con un carattere jolly iniziale (%) comporta SEMPRE una scansione completa della tabella. Cerca invece su Oracle Text indexes.

7

Esempio:

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! 

Ma attenzione. Una funzione PL/SQL cercherà solo i primi 32K di LONG.

+0

Se si desidera eliminare le righe corrispondenti, vedere questa risposta: http://stackoverflow.com/questions/2381203/oracle-delete-where-long-like/2381600#2381600 – Sam

+0

https://forums.oracle.com /forums/thread.jspa?threadID=413669#1418208 –

+0

cosa significa rowid = r. Intendo qui "seleziona il testo in temporary_varchar da longtable dove rowid = r;" – Yashu

0

Il modo migliore è quello di convertire la colonna lunga in "clob" per tutto il tempo in cui viene deprecato. Oppure scrivi un blocco pl/sql per leggere quei dati. Vedi sotto link per una spiegazione chiara.

Riferimenti: http://www.oraclebin.com/2012/12/using-long-data-type-in-where-clause-in.html

+1

Benvenuti in Stack Overflow! Si prega di notare che i link nudi al proprio sito Web/prodotto non sono incoraggiati qui per due motivi; In primo luogo, una risposta dovrebbe essere pubblicata come risposta autonoma, non come un semplice collegamento a un sito esterno. In secondo luogo, l'auto-promozione tende a essere disapprovata qui e spesso viene segnalata come spam (specialmente se non vi è alcuna divulgazione che stai collegando al tuo sito/prodotto). –

9

È possibile utilizzare questo esempio senza utilizzare tabella temporanea:

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; 

Naturalmente v'è un problema se LONG ha più di 32K caratteri.

1

First convertire LONG tipo colonna CLOB tipo quindi utilizzare LIKE condizione, ad esempio:

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

SELECT * FROM tbl_clob WHERE lob_col LIKE '%form%'; 
Problemi correlati