Eu tenho uma situação em que preciso impor uma restrição exclusiva em um conjunto de colunas, mas apenas para um valor de coluna.
Então, por exemplo, eu tenho uma tabela como Tabela (ID, Nome, RecordStatus).
RecordStatus só pode ter um valor 1 ou 2 (ativo ou excluído), e quero criar uma restrição exclusiva em (ID, RecordStatus) apenas quando RecordStatus = 1, já que não me importo se houver vários registros excluídos com o mesmo EU IRIA.
Além de escrever gatilhos, posso fazer isso?
Estou usando o SQL Server 2005.
sql
sql-server
sql-server-2005
np-hard
fonte
fonte
Respostas:
Adicione uma restrição de verificação como esta. A diferença é que você retornará falso se Status = 1 e Contagem> 0.
http://msdn.microsoft.com/en-us/library/ms188258.aspx
fonte
Veja, o índice filtrado . Da documentação (grifo meu):
E aqui está um exemplo combinando um índice exclusivo com um predicado de filtro:
Isso essencialmente impõe exclusividade de
ID
quandoRecordStatus
é1
.Após a criação desse índice, uma violação de exclusividade levantará um erro:
Observação: o índice filtrado foi introduzido no SQL Server 2008. Para versões anteriores do SQL Server, consulte esta resposta .
fonte
ansi_padding
índices filtrados, portanto, certifique-se de que essa opção esteja ativada executandoSET ANSI_PADDING ON
antes de criar um índice filtrado.Você pode mover os registros excluídos para uma tabela que não tem a restrição e talvez usar uma visão com UNION das duas tabelas para preservar a aparência de uma única tabela.
fonte
Você pode fazer isso de uma maneira realmente hacky ...
Crie uma visão baseada em esquema em sua tabela.
CREATE VIEW Qualquer SELECT * FROM Table WHERE RecordStatus = 1
Agora crie uma restrição única na visão com os campos que você deseja.
Uma observação sobre as visualizações associadas ao esquema, porém, se você alterar as tabelas subjacentes, terá que recriar a visualização. Muitas pegadinhas por causa disso.
fonte
Porque, você vai permitir duplicatas, uma restrição única não funcionará. Você pode criar uma restrição de verificação para a coluna RecordStatus e um procedimento armazenado para INSERT que verifica os registros ativos existentes antes de inserir IDs duplicados.
fonte
Se você não pode usar NULL como um RecordStatus como Bill sugeriu, você poderia combinar sua ideia com um índice baseado em função. Crie uma função que retorne NULL se o RecordStatus não for um dos valores que você deseja considerar em sua restrição (e o RecordStatus caso contrário) e crie um índice sobre isso.
Isso terá a vantagem de não ser necessário examinar explicitamente outras linhas da tabela em sua restrição, o que pode causar problemas de desempenho.
Devo dizer que não conheço o servidor SQL, mas usei com sucesso essa abordagem no Oracle.
fonte