Questa sembra essere un'altra delle molte limitazioni degli indici filtrati. Cercare di bypassarlo con l' LIKE
utilizzo WHERE column01 LIKE '_____'
non funziona neanche, producendo lo stesso messaggio di errore ( "clausola WHERE errata ..." ).
Oltre alla VIEW
soluzione, un altro modo sarebbe convertire la colonna calcolata in una colonna normale e aggiungere un CHECK
vincolo in modo che abbia sempre dati validi:
CREATE TABLE Table01 (column01 nvarchar(100),
column01_length int,
CHECK ( column01_length = len(column01)
AND column01 IS NOT NULL
AND column01_length IS NOT NULL
OR column01 IS NULL
AND column01_length IS NULL )
) ;
CREATE UNIQUE INDEX UIX_01 ON Table01 (column01) WHERE column01_length >= 5 ;
Testato su rextester.com
Naturalmente, ciò significa che è necessario compilare in modo esplicito column01_length
la lunghezza corretta ogni volta che si popola column01
(su inserti e aggiornamenti). Ciò può essere complicato, perché è necessario assicurarsi che la lunghezza sia calcolata nello stesso modo della funzione T-SQL LEN()
. In particolare, gli spazi finali devono essere ignorati, il che non è necessariamente il modo in cui la lunghezza viene calcolata di default in vari linguaggi di programmazione in cui sono scritte le applicazioni client. La logica può essere facile da spiegare nel chiamante, ma è necessario essere consapevole della differenza in primo luogo.
Un'opzione sarebbe un INSERT/UPDATE
trigger 1 per fornire il valore corretto per la colonna, quindi appare calcolato per le applicazioni client.
1 Come spiegato in Trigger rispetto ai vincoli , per questo è necessario utilizzare un trigger INSTEAD OF. Un trigger AFTER non verrebbe mai eseguito, poiché la lunghezza assente non supererebbe il vincolo di controllo e ciò, a sua volta, impedirebbe l'esecuzione del trigger. I trigger INSTEAD OF, tuttavia, hanno le proprie restrizioni (consultare le Linee guida per la pianificazione dei trigger DML per una rapida panoramica).