自定义ID列,基于年份和月份

时间:2015-05-26 06:15:02

标签: sql sql-server tsql

我有以下创建表代码:

CTranID int identity(1,1) constraint pk_CTrainID Primary Key,
CustomerID AS 'PB' + 
               cast(datepart(yy,getdate()) as varchar(25)) + 
               cast(datepart(mm,getdate()) as varchar(25)) + 
               RIGHT('000000000' + CAST(CTranID AS VARCHAR(10)), 9),

正在发生的事情是,当记录插入时,它按当前年份和月份进行 但作为测试,我更改了系统月份,当我在T-SQL中查询时,我看到之前插入的记录与更改的月份相同。
如果它应该在更改系统月之前的那个月。

2 个答案:

答案 0 :(得分:3)

您正在使用计算列。每次查询该表时,将立即计算每行的列值。这就是您在更改系统时钟时看到更改值的原因。

而是将创建日期存储在一列中,并将计算出的列基于该列:

CREATE TABLE peter (
CTranID int identity(1,1) constraint pk_CTrainID Primary Key,
CreatedOn DateTime2 DEFAULT (SYSDATETIME()) NOT NULL, -- New Column
CustomerID AS 'PB' + cast(datepart(yy,CreatedOn) as varchar(25)) + cast(datepart(mm,CreatedOn) as varchar(25)) + RIGHT('000000000' + CAST(CTranID AS VARCHAR(10)), 9)
)

INSERT INTO peter
DEFAULT values      

SELECT * FROM peter
CTranID   CreatedOn   CustomerID 
1         2015-05-26  PB20155000000001

答案 1 :(得分:1)

计算列的重点是每次访问时都会计算它 - 如果计算的基础组件发生变化,那么列值也会变化。

您需要将CustomerId列更改为正常的持久列,并找到自动填充它的另一种方法。

CREATE TABLE...
  CustomerID VARCHAR(50), -- i.e. not computed

理想情况下,这将由插入行的应用程序完成,但我可以猜测也会使用触发器,例如。

CREATE TRIGGER T_Customer ON CUSTOMER AFTER INSERT
AS
BEGIN
    UPDATE c
    SET c.CustomerID = 'PB' + cast(datepart(yy,getdate()) as varchar(25)) + 
        cast(datepart(mm,getdate()) as varchar(25)) + 
        RIGHT('000000000' + CAST(ins.CTranID AS VARCHAR(10)), 9)
    FROM Customer c 
    INNER JOIN Inserted ins on c.CTranID = ins.CTranID;
END;
GO

SqlFiddle here