У меня есть MS-SQL Server, который отслеживает количество клиентов. Если день рождения известен, он сохраняется как атрибут datetime, называемый dayOfBirth
. Теперь я хотел бы иметь еще один атрибут age, который отслеживает текущий возраст клиента. Поскольку возраст может измениться в любой день, я подумал, что сценарий может быть лучшей идеей.
Первое, что я сделал, было создание хранимой процедуры, которая вычисляет возраст с учетом дня рождения как datetime. Вот что я придумал:
USE [MyDB]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE CalculateAge
@dayOfBirth datetime,
@age INT OUTPUT
AS
DECLARE @today datetime, @thisYearBirthDay datetime
DECLARE @years int
SET @today = GETDATE()
SET @thisYearOfBirth = DATEADD(year, @dayOfBirth, @today), @dayOfBirth)
SET @years = DATEDIFF(year, @dayOfBirth, @today) - (CASE WHEN @thisYearBirthDay > @today THEN 1 ELSE 0 END)
SET @age = @years
Впоследствии я создал еще один скрипт, который запускает все записи с ненулевым атрибутом dayOfBirth и обновляет возраст, заполненный соответствующим образом.
USE [MyDB]
GO
DECLARE @age int;
DECLARE @birth datetime;
DECLARE @id intl
DECLARE cursorQuery CURSOR FOR SELECT clientId FROM Clients WHERE dayOfBirth IS NOT NULL;
OPEN cursorQuery
FETCH NEXT FROM cursorQuery INTO @id
WHILE @@FETCH_STATUS = 0
BEGIN
SET @birth = (SELECT dayOfBirth from Kunden where clientId=@id);
EXEC dbo.CalculateAge @birth, @age OUTPUT;
UPDATE Clients SET Age = @age WHERE clientId = @id;
FETCH NEXT FROM cursorQuery INTO @id
END
CLOSE cursorQuery
DEALLOCATE cursorQuery
Я бы запустил приведенный выше скрипт один раз в день, чтобы заполнить атрибут age. Это то, что я имею до сих пор, но я чувствую, что есть много возможностей для улучшения.
** Спасибо Сунг Мейстер **
У меня получилось что-то вроде этого:
CREATE TABLE Client (
ID int identity(1,1) primary key,
DOB datetime null,
AGE as (case
when DOB is null then null
else DATEDIFF(YY,DOB,GETDATE()) - CASE WHEN (MONTH(GETDATE()) = MONTH(DOB) AND DAY(DOB) > DAY(GETDATE()) OR MONTH(GETDATE()) > MONTH(DOB)) THEN 1 ELSE 0 END
end
)
)