Esta parece ser otra de las muchas limitaciones de los índices filtrados. Intentar evitarlo con el LIKE
uso WHERE column01 LIKE '_____'
tampoco funciona, produciendo el mismo mensaje de error ( "Cláusula WHERE incorrecta ..." ).
Además de la VIEW
solución, otra forma sería convertir la columna calculada en una columna normal y agregar una CHECK
restricción para que siempre tenga datos válidos:
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 ;
Probado en rextester.com
Naturalmente, eso significa que debe llenar explícitamente column01_length
con la longitud correcta cada vez que complete column01
(en inserciones y actualizaciones). Eso puede ser complicado, porque debe asegurarse de que la longitud se calcule de la misma manera que lo hace la función T-SQL LEN()
. En particular, los espacios finales deben ignorarse, lo cual no es necesariamente cómo se calcula la longitud de forma predeterminada en varios lenguajes de programación en los que se escriben las aplicaciones cliente. La lógica puede ser fácil de explicar en la persona que llama, pero debe ser consciente de la diferencia en primer lugar.
Una opción sería un INSERT/UPDATE
desencadenador 1 para proporcionar el valor correcto para la columna, por lo que aparece como calculado para las aplicaciones del cliente.
1 Como se explica en Disparadores en comparación con las restricciones , necesitaría usar un disparador EN LUGAR DE PARA esto. Un disparador DESPUÉS simplemente nunca se ejecutaría, porque la longitud ausente fallaría la restricción de verificación y eso, a su vez, evitaría que el disparador se ejecute. Sin embargo, los desencadenadores INSTEAD OF tienen sus propias restricciones (consulte las Pautas de planificación de activación de DML para obtener una descripción general rápida).