Tengo que agregar un disparador que debería actualizar una columna usando las siguientes cadenas de formato: <current_date>_<per_day_incremental_id>
por ejemplo 2015-10-01_36
. Los identificadores deben ser incrementales y se permiten huecos.
Mi enfoque es bastante ingenuo: hacer una tabla con la fecha actual y el valor de secuencia actual y mantener un registro único en ella:
create table DailySequence
(
date date,
sequence int
)
insert into DailySequence values (getdate(), 1);
CREATE TRIGGER MakeHumanReadableId ON dbo.AuditMeasures
FOR INSERT
AS
DECLARE @ret int;
DECLARE @tempDate date;
DECLARE @nowDate date;
SET @nowDate = getdate();
SELECT @ret = t.sequence, @tempDate = t.date from DailySequence as t;
IF @nowDate = @tempDate
BEGIN
SET @ret = @ret + 1;
UPDATE DailySequence
SET sequence = @ret;
END
ELSE
BEGIN
SET @ret = 0;
UPDATE DailySequence
SET sequence = @ret, date = @nowDate;
END
UPDATE AuditMeasures
SET [HumanReadableId] = CAST(@nowdate AS VARCHAR(10)) + '_' + CAST(@ret AS VARCHAR(10));
FROM inserted
INNER JOIN AuditMeasures On inserted.id = AuditMeasures.id
GO
Preguntas:
- ¿Hay alguna dificultad para mi solución? por ejemplo, el código dentro del activador no se ejecutará dentro de una transacción, por lo que dará valores incorrectos.
- ¿Me estoy perdiendo una solución mejor?
sql-server
sql-server-2008-r2
t-sql
sequence
Pavel Murygin
fuente
fuente
IDENTITY
que no se restablece todos los días y agregarlo a la fecha actual. Cada nuevo día se verá como si tuviera una "brecha" cada vez mayor, pero la brecha está permitida, ¿no es así? Es una broma, por supuesto, pero resalta que debes haber omitido algunos requisitos.Respuestas:
Un método potencial para hacer esto sería (ver el mejor método, al final):
Los resultados:
Habiendo dicho todo eso, me preguntaría por qué no simplemente mantener dos columnas separadas que podrían concatenarse en la capa de presentación:
Los resultados:
El método anterior es mucho más capaz de escalar bien y ofrece flexibilidad en la presentación del número de secuencia legible por humanos.
fuente
Podría simplificar la parte que actualiza la
DailySequence
tabla. En lugar de esto:podrías usar esto:
La
@ret
variable se inicializaría en la instrucción UPDATE con el valor almacenado ensequence
.Alternativamente, también puede deshacerse de la
set @nowDate = getdate();
declaración reescribiendo la ACTUALIZACIÓN de esta manera:o, tal vez, incluso así:
De esta forma, la instrucción UPDATE inicializaría ambos
@nowDate
y@ret
. La@tempDate
variable no sería necesaria con ninguna de las opciones.fuente