2015-07-09 32 views
7

Ho scritto un frasario che sta formando una stringa abbastanza lunga in piccoli pezzi, dopo che il fraseggio di un elemento è completato, lo rimuove da @input e continua, finché non sarà in grado di trovare alcun elementi per frase. Sto selezionando gli articoli in base al modello LIKE.LIKE pattern T-SQL

In alcuni casi, tuttavia, è in corso la selezione di altre parti del messaggio, quindi termina nel ciclo infinito.

Il modello Sto cercando di essere selezionati mediante clausola LIKE è in formato di:

(qualsiasi numero da 1 a 9) + (lunghezza variabile AZ solo) + '/' + (variabile lunghezza solo AZ) + spazio di Cr o Lf o CrLf.

--This is what I do have: 
DECLARE @match NVarChar(100) 
    SET @match = '%[1-9][a-z]%' 

DECLARE @input1 varchar(max),@input2 varchar(max) 
    SET @input1 ='1ABCD/EFGH *W/17001588 *RHELLO SMVML1C' 

DECLARE @position Int 
    SET @position = PATINDEX(@match, @input1); 

SELECT @position; 

--after the loop- it is also 'catching' the 1C at the end of the string: 

SET @input2  = '*W/17001588 *RHELLO SMVML1C' 
SET @position = PATINDEX(@match, @input2); 

SELECT @position 

---In order to eliminate this, I have tried to change @match: 

SET @match = '%[1-9][a-z][/][a-z]%' 

SET @position = PATINDEX(@match, @input1); 
SELECT @position --postion is 0, so the first item, that should have been selected, wasn't selected 
SET @position = PATINDEX(@match, @input2); 
SELECT @position --postion is 0 

Molte grazie per l'aiuto!

+0

T-SQL non ha espressioni regolari o qualsiasi altro built-in pattern matcher che farà quello che vuoi. In particolare, le parti "qualsiasi numero di" e "lunghezza variabile" sono ciò che causerà problemi. –

+0

Quindi nella tua nuova corrispondenza, per '@ input1',' @ position' dovrebbe essere 1 e per '@ input2',' @ position' dovrebbe essere 0? Corretta? –

+0

Non è possibile analizzare tale input utilizzando le funzionalità limitate di PATINDEX. È necessario utilizzare espressioni regolari nel codice o scrivere un parser effettivo. –

risposta

1

prova a modificare le variabili partita/criteri a questo:

SET @match = '%[1-9][a-z]%[/][a-z]%' 

questo modo si ottiene il risultato desiderato. Tradotto liberamente dice "Prendi la posizione iniziale della prima partita in cui il modello è [nulla] - [numero 1-9] - [lettera singola da az] - [nulla] - [barra] - [lettera singola da . az] - [qualcosa]
Spero che questo aiuti

+0

sfortunatamente che non corrisponderà alle parti di lunghezza variabile della sua ricerca, 1a/a corrisponde a 1abc/def no. nore corrisponde al carattere terminale. –

+0

Attualmente corrisponde a 1abc/def .... è ciò che gestisce il secondo carattere jolly.Anche la domanda è cambiata da quando ho dato la mia risposta (inizialmente non c'era un carattere terminale, né la stringa immediatamente prima della barra A-Z) –

0

sono d'accordo con le osservazioni di cui sopra, questo è un problema regex che deve essere risolto con gli strumenti regex mi sento di raccomandare l'assemblaggio creato da SimpleTalk You can get their code and read their very thorough article

!...

Sfortunatamente questa soluzione richiede seri diritti di amministratore per il database e il server, quindi non sarà portatile come uno script, ma penso che queste funzioni valgano ogni sforzo necessario per ottenere l'installazione se si sviluppa sullo stesso database una base regolare

Basta essere avvisati, l'espressione regolare è un vero hog di elaborazione e mina la maggior parte dell'efficienza di indicizzazione in SQL Server. Usalo solo quando non puoi usare come.

0

Non so se questo risolve l'intero problema, ma se si può prefissare il proprio input con uno spazio, è possibile modificare il modello per evitare la corrispondenza con un numero senza uno spazio precedente.

set @input = ' '[email protected]; 
set @match = '% [1-9][a-z]%'; 

Se è necessario il vostro modello per tenere conto di altri spazi bianchi come CR e LF, il vostro modello potrebbe essere la seguente:

set @match = '%[ '+char(13)+char(10)+'][1-9][a-z]%';