Eu tenho um banco de dados que não está em produção, portanto, a tabela principal é CustodyDetails, esta tabela possui uma ID int IDENTITY(1,1) PRIMARY KEY
coluna e estou procurando uma maneira de adicionar outro identificador exclusivo que não seja referenciado em nenhuma outra tabela. conta, o conteúdo da coluna não seria exatamente uma chave de identidade.
Essa nova coluna de identidade possui alguns detalhes específicos e é aqui que o meu problema começa. O formato é o seguinte: XX/YY
onde XX é um valor incremental automático que redefine / reinicia a cada novo ano e YY são os últimos 2 dígitos do ano atual SELECT RIGHT(YEAR(GETDATE()), 2)
.
Assim, por exemplo, vamos fingir que um registro é adicionado por dia a partir de 28/12/2015, terminando em 01/01/2016 , a coluna teria a seguinte aparência:
ID ID2 DATE_ADDED
1 1/15 2015-12-28
2 2/15 2015-12-29
3 3/15 2015-12-30
4 4/15 2015-12-31
5 1/16 2016-01-01
6 2/16 2016-01-02
7 3/16 2016-01-03
Pensei em usar o front-end para analisar o ID composto (ID2 no exemplo), obter os dois últimos dígitos e comparar com os últimos dois dígitos do ano atual e depois decidir se devo ou não iniciar um novo correlativo. É claro que seria ótimo poder fazer tudo isso no lado do banco de dados.
EDIT 1: btw, eu também vi pessoas usando tabelas separadas apenas para armazenar chaves de identidade paralelas, então uma tabela Chave de identidade se torna uma segunda chave secundária da tabela, isso soa um pouco desonesto, mas talvez seja esse o caso dessa implementação?
EDIT 2: Esse ID extra é uma referência de documento legado que rotula todos os arquivos / registros. Eu acho que alguém poderia pensar nisso como um alias especial para o ID principal.
O número de registros que este banco de dados manipula anualmente não foi dos 100 nos últimos 20 anos e é altamente (realmente, extremamente altamente) improvável que seria, é claro, se ultrapassar os 99, o campo será capaz de continue com o dígito extra e o frontend / procedimento poderá ultrapassar 99, por isso não é como se isso mudasse as coisas.
É claro que alguns desses detalhes que eu não mencionei no início, porque apenas restringiriam as possibilidades de solução para atender às minhas necessidades específicas, tentaram manter o alcance do problema mais amplo.
ID
= 5, 6 e 7, o DATE_ADDED deve ser2016-01-01
e assim por diante?Respostas:
Você pode usar uma tabela de chaves para armazenar a parte de incremento da sua segunda coluna de ID. Esta solução não depende de nenhum código do lado do cliente e tem reconhecimento automático de vários anos; quando o
@DateAdded
parâmetro passa em um ano não utilizado anteriormente, ele começará automaticamente a usar um novo conjunto de valores para aID2
coluna, com base nesse ano. Se o proc for usado consequentemente para inserir linhas de anos anteriores, essas linhas serão inseridas com valores "corretos" para o incremento. OGetNextID()
proc é voltado para lidar com possíveis bloqueios graciosamente, transmitindo apenas um erro ao chamador se ocorrerem 5 bloqueios sequenciais ao tentar atualizar atblIDs
tabela.Crie uma tabela para armazenar uma linha por ano contendo o valor de ID usado atualmente, juntamente com um procedimento armazenado para retornar o novo valor a ser usado:
Sua tabela, juntamente com um proc para inserir linhas nela:
Insira alguns dados de amostra:
Mostrar as duas tabelas:
Resultados:
A tabela de chaves e o procedimento armazenado vêm dessa pergunta.
fonte
(IDName, LastID)
linha, isso resultaria em um impasse ou em uma das transações violando o PK? Nesse último caso, talvez faça sentido dar outra chance a essa transação (para que, eventualmente, obtenha o ID 2).@NewID
explicitamente como nulo no início do loop: se a transação que tenta inserir uma linha se tornar uma vítima de impasse, ela não tentará inserir uma linha na próxima iteração, porque@NewID
já terá foi definido como 1 (que não é NULL e, portanto, a ramificação INSERT será omitida).tblIDs
tabela, pois essa tabela é atualizada por uma única operação atômica; a atualização "peculiar".@NewID = NULL
no início do loop.