2016-06-21 7 views
0

2 Samples Code:PL/SQL, regexp, eine Verbindung von

 WITH A AS 
    (SELECT 'this is a test:12/01/2015 01/05/2018' 
    || chr(13) 
    ||chr(10) 
    || ' this is the 2nd line: 07/07/2017' Description 
    FROM dual 
) 
SELECT to_date(regexp_substr(A.Description , '\d{1,2}/\d{1,2}/\d{4}',1,level),'MM/DD/YYYY') 
FROM A 
    CONNECT BY level <= regexp_count(a.description, '\d{1,2}/\d{1,2}/\d{4}'); 
/

und eine andere:

SELECT DISTINCT REGEXP_SUBSTR ('23,34,45,56','[^,]+',1,LEVEL) as "token" 
FROM DUAL 
CONNECT BY REGEXP_SUBSTR ('23,34,45,56','[^,]+',1,LEVEL) IS NOT NULL 
order by 1; 

Kann jemand mir erklären, warum in erster Fall, dass wir '< =' verwenden und in 2. Wir nicht?

+0

Im ersten Beispiel können Sie auch 'IS NOT NULL' ==> nur' CONNECT BY regexp_substr (a.description, '\ d {1,2}/\ d {1,2}/\ d {4 } ', 1, level) ist nicht null'. Und im zweiten Beispiel kann man 'CONNECT BY level <= REGEXP_count ('23, 34, 45, 56 ',' [\,] + ') + 1' anstelle von' IS NOT NULL' benutzen.Es ist schwer zu sagen, warum einige "ist nicht null" anstelle von "regexp_count" gewählt haben, es könnte einfach eine persönliche Vorliebe sein, meiner Meinung nach. – krokodilko

+0

Vermeiden Sie es, die Regex in dieser Sekunde zu verwenden, um getrennte Listen zu analysieren. Es behandelt keine NULL-Listenelemente und gibt falsche Werte im Hintergrund zurück. Weitere Informationen finden Sie hier: http://stackoverflow.com/questions/31464275/split-comma-separated-values-to-columns-in-oracle/31464699#31464699 –

Antwort

0
Introduced in Oracle 10g 

REGEXP_SUBSTR - Gibt die Zeichenfolge zurück, die dem regulären Ausdruck entspricht.

Introduced in Oracle 11g 

REGEXP_COUNT - Gibt die Anzahl der Vorkommen des regulären Ausdrucks in der Zeichenfolge zurück.

Sie können dasselbe erreichen, ohne den relationalen Operator '< =' zu verwenden. In Ihrem obigen Code zählen Sie das Auftreten.

WITH A AS 
     (SELECT 'this is a test:12/01/2015 01/05/2018' 
     || chr(13) 
     ||chr(10) 
     || ' this is the 2nd line: 07/07/2017' Description 
     FROM dual 
    ) 
    SELECT to_date(regexp_substr(A.Description , '\d{1,2}/\d{1,2}/\d{4}',1,level),'MM/DD/YYYY') 
    FROM A 
     CONNECT BY 
     regexp_substr(A.Description , '\d{1,2}/\d{1,2}/\d{4}',1,LEVEL) is not null; 

In Ihrer zweiten Abfrage Sie von ‚< =‘ als je die Notwendigkeit zu machen.

SELECT DISTINCT REGEXP_SUBSTR ('23,34,45,56','[^,]+',1,LEVEL) as "token",LEVEL 
     FROM DUAL 
    CONNECT BY LEVEL <= regexp_count(('23,34,45,56'),'[^,]+'); 
0

Manchmal ist die Anzahl der Zeilen, die gleiche wie die Anzahl der Zeilen von REGEXP_COUNT mit IS NOT NULL am Ausgang des REGEXP_SUBSTR ist gefunden und dann tun sie das gleiche und es ist eine Frage des persönlichen Geschmacks:

SELECT REGEXP_SUBSTR('1,2,3', '\d+', 1, LEVEL) AS value 
FROM DUAL 
CONNECT BY LEVEL <= REGEXP_COUNT('1,2,3', '\d+') 

und

SELECT REGEXP_SUBSTR('1,2,3', '\d+', 1, LEVEL) AS value 
FROM DUAL 
CONNECT BY REGEXP_SUBSTR('1,2,3', '\d+', 1, LEVEL) IS NOT NULL 

beiden Ausgänge:

VALUE 
----- 
1 
2 
3 

jedoch manchmal die Unterkette abgestimmt können Null-Breite (welche der NULL äquivalent ist), und dann haben sie nicht:

SELECT REGEXP_SUBSTR('1,2,,4', '(\d*)(,|$)', 1, LEVEL, 1) AS value 
FROM DUAL 
CONNECT BY LEVEL <= REGEXP_COUNT('1,2,3', '(\d*)(,|$)') 

Ausgänge:

VALUE 
------ 
1 
2 
(null) 
4 
(null) 

und:

SELECT REGEXP_SUBSTR('1,2,,4', '(\d*)(,|$)', 1, LEVEL, NULL, 1) AS value 
FROM DUAL 
CONNECT BY REGEXP_SUBSTR('1,2,,4', '(\d*)(,|$)', 1, LEVEL, NULL, 1) IS NOT NULL 

Ausgänge:

VALUE 
------ 
1 
2 

und stoppt bei der ersten NULL Wert.

Um alle Ergebnisse zu erhalten, müssen Sie entweder REGEXP_COUNT verwenden oder nicht, die REGEXP_SUBSTR() Funktion Rückkehr NULL Werte haben in der CONNECT BY Klausel (also in diesem Beispiel wir es durch Extraktion der vollständige Übereinstimmung und nicht nur die Erfassungsgruppe beheben könnte; dh REGEXP_SUBSTR('1,2,,4', '(\d*)(,|$)', 1, LEVEL) IS NOT NULL).