É possível limitar quais valores são permitidos em uma coluna com base em outros valores na linha?
Por exemplo, minha tabela:
ID Test_mode Active
-- --------- ------
1 1 Null
2 0 1
3 1 0
Existe uma maneira de alterar o valor de Test_mode
para 0
se um 1
for inserido emActive
OU
Se Test_mode
for 1 não permite inserção/atualização deActive
OU
Lança algum tipo de erro se Test_mode
for 1 e uma inserção/atualização Active
for tentada.
Active
só pode ser NULL, 1, 0, E apenas 1 com Test_mode
0.
Espero que isso faça sentido, se não, me avise e atualizarei a pergunta.
Em primeiro lugar, bem-vindo ao dba.stackexchange.com e obrigado por sua postagem !!
É possível limitar quais valores são permitidos em uma coluna com base em outros valores na linha.
Sim, usando CHECK CONSTRAINTS conforme descrito aqui
Exemplo :
Se
Test_mode
for 1 não permite inserção/atualização de Active --OU-- Lança algum tipo de erro se Test_mode for 1 e uma inserção/atualização de Active é tentada.Use TRY/CATCH conforme descrito aqui
A primeira linha de defesa para evitar que dados inválidos entrem em suas tabelas são os tipos de dados das colunas.
Se um processo tentar inserir ou atualizar uma coluna para um valor que esteja fora do intervalo do tipo de dados (ou
NULL
se a coluna não permitirNULL
s), a operação falhará imediatamente sem que você precise fazer nenhum trabalho extra.A seleção do tipo de dados é um dos aspectos mais importantes do design da tabela.
Então, como você não postou um esquema, vou construir um com base nas informações que você forneceu:
Com base neste design, as combinações disponíveis já se limitam ao seguinte:
Qualquer coisa diferente disso fará com que um erro seja gerado. (O que é uma boa coisa.)
Você deu 4 maneiras diferentes de chegar à combinação permitida de valores (bem, mais ou menos). Estas são estratégias muito diferentes , com comportamentos de implementação muito diferentes.
Prefiro usar o que chamamos de restrições declarativas . Em outras palavras, o esquema da tabela e seus objetos associados limitam os valores permitidos declarando explicitamente o que é permitido (ou às vezes, o que não é permitido). Na verdade, os próprios tipos de dados da coluna são um tipo de restrição declarativa. Quanto mais próximos dos dados da tabela os valores puderem ser restritos, mais fácil e confiável eles poderão ser restritos. (Em contraste, uma restrição não declarativa ou ativa seria implementada escrevendo uma parte do T-SQL, geralmente um gatilho de tabela ou parte de um procedimento armazenado.)
As 3 primeiras opções só podem ser implementadas por meios não declarativos. O último, no entanto, é declarativo, então vamos nos concentrar nisso:
Isso define o que você realmente deseja, que são as combinações de valores permitidas na tabela. Observe que as combinações válidas dependem apenas dos valores das colunas dentro da mesma linha . Isso é importante porque determina qual(is) mecanismo(s) pode(m) ser usado(s) para implementar a restrição.
Nesse caso, podemos usar uma
CHECK
restrição , que é um teste verdadeiro/falso que determina se uma linha é válida ou inválida com base nos valores 1 da coluna de uma linha . Se o teste falhar, a operação que tentou alterar a linha falhará com um erro.Você notará que construí o predicado de forma que ele continue a funcionar mesmo se
Test_mode
for realmente um tipo inteiro (não anulável). AIS NOT NULL
parte é necessária porque asCHECK
restrições permitem linhas em que o predicado é avaliado comoundefined
.1 Eles podem ser usados para verificar fora da linha atual, mas essa é uma prática ruim e não vou entrar nisso aqui. Em vez disso, use um gatilho.