2016-05-23 12 views
0

Wir haben unter Tabellenstruktur.Oracle regulären Ausdruck für alphanumerische Überprüfung

 
From To Output 
A001 A555 "A" 
A556 A999 "B" 
AA01 AA55 "C" 
AA56 AA99 "D" 
B001 B555 "C" 

Wenn mein Eingabewert größer als von Spalte Von und kleiner als Bis ist, dann gebe diese Ausgabe zurück. Z.B. Wenn ich A222 erhalten habe, dann gebe die Ausgabe als "A" zurück. Wenn ich AA22 empfangen habe, dann gebe die Ausgabe als "C" zurück.

Derzeit habe ich dies in Java behandeln aber wollte überprüfen, ob ich eine Oracle-Abfrage (mit Regex) schreiben kann, um über die Ausgabe zu erhalten.

Dank Sach

+0

Was ist Ihr Eingabewert? Es ist wirklich nicht klar, wie AA "C" wird ... – Ben

+0

Was ist der Bereich der Buchstaben? –

+0

Angenommen, ich habe Input als A123 erhalten, also ist dieser Wert größer als A001 und kleiner als A555, daher sollte die Abfrage "A" aus der Ausgabespalte zurückgeben. Wenn ich Input als AA12 erhalten habe, dann ist dieser Wert größer als AA01 und kleiner als AA99, daher sollte die Abfrage "A" zurückgeben. Abfrage sollte zuerst die anfänglichen Alphabete überprüfen und dann die Zahlen für diese Zeile vergleichen. Ich hoffe, dass ich hier klar bin. – sach

Antwort

0

Sie haben varchar und Zahlenwert von Spalten und Eingabewert zu extrahieren und sie sich

with tabl("FROM","TO",Output) as (
select 'A001','A555','A' from dual union all 
select 'A556','A999','B' from dual union all 
select 'AA01','AA55','C' from dual union all 
select 'AA56','AA99','D' from dual union all 
select 'B001','B555','C' from dual) 
select * from tabl 
where to_number(regexp_substr('AA22','[0-9]+')) between to_number(regexp_substr("FROM",'[0-9]+')) and to_number(regexp_substr("TO",'[0-9]+')) 
and regexp_substr('AA22','[^0-9]+') = regexp_substr("FROM",'[^0-9]+') 
1

Erstellen Sie Ihre Tabelle mit den entsprechenden (virtuellen) Spalten und Indizes vergleichen:

Oracle-Setup:

CREATE TABLE table_name (
    "from"  VARCHAR2(10) UNIQUE, 
    "to"   VARCHAR2(10) UNIQUE, 
    output  CHAR(1)  NOT NULL, 
    prefix  VARCHAR2(9) GENERATED ALWAYS AS (
           CAST(
           REGEXP_SUBSTR("from", '^\D+') 
           AS VARCHAR2(9) 
          ) 
          ) VIRTUAL, 
    from_postfix NUMBER(9) GENERATED ALWAYS AS (
          TO_NUMBER(REGEXP_SUBSTR("from", '\d+$')) 
          ) VIRTUAL, 
    to_postfix NUMBER(9) GENERATED ALWAYS AS (
           TO_NUMBER(REGEXP_SUBSTR("to", '\d+$')) 
          ) VIRTUAL, 
    CONSTRAINT table_name__from_to__u PRIMARY KEY (
    prefix, from_postfix, to_postfix 
), 
    CONSTRAINT table_name__f_t_prefix__chk CHECK (
    REGEXP_SUBSTR("from", '\^\D+') = REGEXP_SUBSTR("to", '\^\D+') 
) 
); 

INSERT INTO table_name ("from", "to", output) 
SELECT 'A001', 'A555', 'A' FROM DUAL UNION ALL 
SELECT 'A556', 'A999', 'B' FROM DUAL UNION ALL 
SELECT 'AA01', 'AA55', 'C' FROM DUAL UNION ALL 
SELECT 'AA56', 'AA99', 'D' FROM DUAL UNION ALL 
SELECT 'B001', 'B555', 'C' FROM DUAL; 

COMMIT; 

Abfrage:

dann Ihre Abfrage den Index benötigen verwenden kann und nicht einen vollständigen Tabellenscan zu tun:

SELECT output 
FROM table_name 
WHERE REGEXP_SUBSTR(:input, '^\D+') = prefix 
AND TO_NUMBER(REGEXP_SUBSTR(:input, '\d+$')) 
     BETWEEN from_postfix 
     AND  to_postfix; 

Ausgang:

Wenn der input Bind Variable AA22 ist dann ist das Ergebnis:

OUTPUT 
------ 
C 

Erklären-Plan:

PLAN_TABLE_OUTPUT 
------------------------------------------- 
Plan hash value: 2408507965 
------------------------------------------------------------------------------------------------------ 
| Id | Operation     | Name     | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------------------ 
| 0 | SELECT STATEMENT   |      |  1 | 35 |  2 (0)| 00:00:01 | 
| 1 | TABLE ACCESS BY INDEX ROWID| TABLE_NAME    |  1 | 35 |  2 (0)| 00:00:01 | 
|* 2 | INDEX RANGE SCAN   | TABLE_NAME__FROM_TO__U |  1 |  |  2 (0)| 00:00:01 | 
------------------------------------------------------------------------------------------------------ 

Predicate Information (identified by operation id): 
--------------------------------------------------- 
     2 - access("PREFIX"= REGEXP_SUBSTR (:INPUT,'^\D+') AND "TO_POSTFIX">=TO_NUMBER(
       REGEXP_SUBSTR (:INPUT,'\d+$')) AND "FROM_POSTFIX"<=TO_NUMBER(REGEXP_SUBSTR (:INPUT,'\d+$'))) 
     filter("TO_POSTFIX">=TO_NUMBER(REGEXP_SUBSTR (:INPUT,'\d+$'))) 
+0

Diese Lösung hat für mich funktioniert. Danke vielmals. – sach

Verwandte Themen