Tengo una situación en la que necesito aplicar una restricción única en un conjunto de columnas, pero solo para un valor de una columna.
Entonces, por ejemplo, tengo una tabla como Table (ID, Name, RecordStatus).
RecordStatus solo puede tener un valor 1 o 2 (activo o eliminado), y quiero crear una restricción única en (ID, RecordStatus) solo cuando RecordStatus = 1, ya que no me importa si hay varios registros eliminados con el mismo CARNÉ DE IDENTIDAD.
Aparte de escribir desencadenantes, ¿puedo hacer eso?
Estoy usando SQL Server 2005.
sql
sql-server
sql-server-2005
np-hard
fuente
fuente
Respuestas:
Agregue una restricción de verificación como esta. La diferencia es que devolverá falso si Estado = 1 y Recuento> 0.
http://msdn.microsoft.com/en-us/library/ms188258.aspx
fuente
He aquí el índice filtrado . De la documentación (el énfasis es mío):
Y aquí hay un ejemplo que combina un índice único con un predicado de filtro:
Esto esencialmente refuerza la singularidad de
ID
cuándoRecordStatus
es1
.Tras la creación de ese índice, una infracción de unicidad generará un error:
Nota: el índice filtrado se introdujo en SQL Server 2008. Para versiones anteriores de SQL Server, consulte esta respuesta .
fuente
ansi_padding
índices filtrados, así que asegúrese de que esta opción esté activada ejecutándolaSET ANSI_PADDING ON
antes de crear un índice filtrado.Puede mover los registros eliminados a una tabla que carece de la restricción, y quizás usar una vista con UNION de las dos tablas para preservar la apariencia de una sola tabla.
fuente
Puedes hacer esto de una manera realmente hacky ...
Cree una vista enlazada al esquema en su mesa.
CREAR VISTA Lo que sea SELECT * FROM Table WHERE RecordStatus = 1
Ahora cree una restricción única en la vista con los campos que desee.
Sin embargo, una nota sobre las vistas vinculadas a esquemas, si cambia las tablas subyacentes, tendrá que volver a crear la vista. Un montón de trampas por eso.
fuente
Debido a que va a permitir duplicados, una restricción única no funcionará. Puede crear una restricción de verificación para la columna RecordStatus y un procedimiento almacenado para INSERT que verifica los registros activos existentes antes de insertar ID duplicados.
fuente
Si no puede usar NULL como RecordStatus como sugirió Bill, podría combinar su idea con un índice basado en funciones. Cree una función que devuelva NULL si RecordStatus no es uno de los valores que desea considerar en su restricción (y RecordStatus en caso contrario) y cree un índice sobre eso.
Eso tendrá la ventaja de que no tiene que examinar explícitamente otras filas de la tabla en su restricción, lo que podría causarle problemas de rendimiento.
Debo decir que no conozco el servidor SQL en absoluto, pero he utilizado con éxito este enfoque en Oracle.
fuente