2017-01-12 3 views
0

Ich habe eine Oracle-Tabelle, die fast 150k Datensätze und 65 Spalten hat. Es gibt eine Anforderung von meinem Kunden, dass Sie die ganze Tabelle mit einem einzelnen Suchwert durchsuchen müssen und das auch Wildcard-Suche sein kann.Durchsuchen einer Oracle-Tabelle nach einem Wert

Und das Schlimmste ist, dass ich PHP-Sprache verwende, um das zu tun.

Also habe ich eine Abfrage erstellt, die alle 65 Spalten hat, um nach einem einzelnen Zeichenfolgenwert zu suchen.

Beispielabfrage:

SELECT * FROM <TABLE_NAME> 
WHERE (col1 || col2 || col3 ... || col65) LIKE '%<SEARCH_VALUE>%' 

Die Abfrage wird geben Ausgang für einige Felder und manchmal ist es versagt, wenn wir einige Adresse verwandten Bereichen bestehen.

In einigen Szenarien, insbesondere bei Wildcard-Typ-Suche und wenn es mehr als 1000 Zeilen ausgibt.

Ich habe diese Tests mit PHP Sprache durchgeführt. aber gleichzeitig, wenn ich versuche, die Abfrage mit SQL Developer auszuführen. Es gibt ständig Ergebnisse. Also war ich verwirrt.

Und noch mehr über den Oracle-Server, auf den ich zugreifen möchte, ist ein externer Server, der sich nicht in unserer Umgebung befindet.

Bitte schlagen Sie mir vor, wie Sie diese Funktion oder Idee implementieren und ich schätze Ihre Assistentin sehr.

+1

Wenn Sie keine Platzhalter verwenden, denke ich, dass Sie eine 'WHERE: Suche IN (col1, col2, col3, ..., col65)' tun könnten. Mit Platzhaltern denke ich, dass Sie einen anderen Ansatz benötigen. –

Antwort

0

Das sieht wie ein ziemlich schreckliches Design aus. Ein Problem, das in den Sinn kommt, ist im Beispiel unten gezeigt

col1 col2 
=========== 
ABC DEF 
CDX ZZZ 

Wenn Ihr Suchbedingung ist „CD“, die beide dieser Zeilen wird übereinstimmen, da Sie auf der Verkettung aller Spalten suchen.

2

Wenn Sie Oracle 11g verwenden, können Sie eine virtuelle Spalte der Tabelle hinzufügen

ALTER TABLE <TABLE_NAME> ADD 
SEARCH_COLUMN GENERATED ALWAYS AS (col1 || ' ' || col2 || ' ' || col3 ... || col65); 

Dann einen Index für die neu erstellte virtuelle Spalte erstellen. Der Index speichert den verketteten String-Wert aller 65 Spalten. Sie müssen keine Abfragen in Ihrer Anwendung ändern, da Oracle automatisch den Wert der virtuellen Spalte mit den Werten der anderen 65 Spalten berechnet.

Dann können Sie einfach den Index virtuelle Spalte für Ihre Suche verwenden

SELECT * FROM <TABLE_NAME> 
WHERE SEARCH_COLUMN LIKE '%<SEARCH_VALUE>%' 
0

ich diesen Trick bin mit über Spalten suchen Und ich weiß, dass die Lösung langsam ist.

create table test_example as select * from user_objects where rownum <= 1000; 

select t2.* from 
xmltable('for $i in ora:view("test_example")/ROW 
      where fn:exists($i/*[contains(.,$var_text_to_serach)]) 
      return $i' passing 'change_here' as "var_text_to_serach" columns id varchar(100) path 'OBJECT_ID') t1 
    join test_example t2 on t1.id = t2. OBJECT_ID 
; 

ora:view - ermöglicht Abfragen von Tabellen innerhalb von XQuery-Ausdruck. Funktion erstellt XML-s aus Tabellenzeilen.

xmltable - Ermöglicht die Zuordnung von xquery-xml-Ergebnis zum relationalen Modell.

FLWOR expresion - innen xmltable ich bin FLWOR expresion mit es ist Akronym aus Worten FOR, LET, WHERE, ORDER,

fn:exists($i/*[contains(.,$var_text_to_serach)]) RETURN - überprüfen, ob alle Spalten Muster enthält.

columns id varchar(100) path 'OBJECT_ID' ID-Spalte aus XML extrahieren. In meinem Beispiel ist OBJECT_ID ein eindeutiger Wert in der Tabelle.

passing 'change_here' as "var_text_to_serach" - „change_here“ ist Text

zu verwenden, um dieses Beispiel Sie test_example auf den Tisch wechseln müssen zu suchen, und kümmern uns kommen über Zustand und.

0

Betrachten Sie einen benutzerdefinierten Datenspeicher unter Verwendung eines Textindex für alle Spalten zu erstellen und dann die Suche mit dem Operator enthält ..

Sonething wie diese

begin 
    begin 
    ctx_ddl.drop_preference('mymcds'); 
    exception 
    when others then 
    null; 
    end; 
    ctx_ddl.create_preference('mymcds', 'multi_column_datastore'); 
    ctx_ddl.set_attribute('mymcds', 'columns', 'NAME, POI_STREET_NAME,  
               POI_CITY, POI_POSTCODE, ACTUAL_ADDRESS'); 
end; 
/
create index ADDRESS_SEARCH_IDX 
     on MAP_POI(NAME) 
      indextype is ctxsys.context 
      parameters ('datastore mymcds section group  ctxsys.auto_section_group') 
/

Eine Suche mit enthält (NAME , 'Foo') sollte alle indizierten Spalten durchsuchen.

Verwandte Themen