CREATE TABLE Parent ( ParentID int NOT NULL PRIMARY KEY,
ParentName varchar(50) NULL )
CREATE TABLE Child ( ChildID int NOT NULL PRIMARY KEY,
ParentID int NOT NULL REFERENCES Parent (ParentID),
ChildName varchar(50) NULL,
IsFavorite BIT NOT NULL )
O primeiro desejo é que eu gostaria de evitar a situação de pais sem filhos. Obviamente, quando o par é criado pela primeira vez, o Pai não terá filho, e eu não quero impedir a inserção em si; mas quero proibir totalmente a exclusão do último filho. (Por motivos comerciais, os Pais nunca serão excluídos.)
Como segundo desejo, preciso evitar mais de um Child com IsFavorite=1, o que sei que posso fazer com um índice exclusivo filtrado. Eu também gostaria de desencorajar não ter filhos com IsFavorite=1 -- ou seja, não permitir a configuração IsFavorite=0 se este for o único filho de seu pai. (Do lado do aplicativo, as inserções normalmente devem ser feitas corretamente com IsFavorite=1 para o primeiro filho; mas não quero que o banco de dados interfira nisso.)
Tenho certeza de que não sou o primeiro com esses desejos, mas não consegui encontrar uma pergunta correspondente no dba ou no stackoverflow. Se isso é um engano, por favor marque-o como um idiota e me aponte onde eu preciso estar.
Você pode fazer (ParentId,FavoriteChildId) um FK em Parent e obter a maior parte disso. No entanto, no SQL Server, não há uma maneira prática de tornar o relacionamento necessário, portanto, você deve permitir que um pai não tenha filho favorito, ou então não poderá inserir um novo pai sem desabilitar o FK.
Você pode adicionar um gatilho para evitar definir FavoriteChildId como nulo, mas deve permitir isso pelo menos no caso de um pai ter um único filho, caso contrário não haveria como excluir esse filho. Então não tenho certeza se vale a pena se preocupar com o Trigger. POR EXEMPLO:
Talvez seja mais fácil implementar esses requisitos (um tanto incomuns) com um índice exclusivo filtrado e alguns
AFTER
gatilhos:Tabelas e índices
Excluir gatilho
Atualizar acionador
Como de costume, o gatilho de atualização só lidará com todas as atualizações de várias linhas corretamente se a chave primária for imutável. A maneira mais fácil de conseguir isso seria criar
ChildID
uma coluna de identidade.