带有前缀的MSSQL自动递增ID

时间:2016-06-20 10:14:00

标签: sql sql-server sql-server-2012

我想使用前缀实现自动增量ID,但如果它具有不同的前缀,则重置该数字。

我想要的输出如下:

ID  PREFIX  PROJECTID
1   PID_    PID_1
2   PID_    PID_2
3   RID_    RID_1
4   RID_    RID_2

但我用我的脚本得到的结果是:

ID  PREFIX  PROJECTID
1   PID_    PID_1
2   PID_    PID_2
3   RID_    RID_3
4   RID_    RID_4

这是我创建表格的脚本

CREATE TABLE PROJECTS
(ID INT IDENTITY(1,1) NOT NULL,
PREFIX NVARCHAR(10) NOT NULL,
PROJECTID AS ISNULL(PREFIX + CAST(ID AS NVARCHAR(10)), '') PERSISTED)

INSERT INTO PROJECTS(PREFIX) VALUES('PID_'),('PID_'),('RID_'),('RID_')

我正在使用 MS SQL 2012

4 个答案:

答案 0 :(得分:0)

你想要这样

CREATE TABLE #PROJECTS
(
  ID INT IDENTITY(1, 1)
         NOT NULL ,
  PREFIX NVARCHAR(10) NOT NULL ,
  PROJECTID NVARCHAR(11)
)


INSERT  INTO #PROJECTS
    ( PREFIX )
VALUES  ( 'PID_' ),
        ( 'PID_' ),
        ( 'RID_' ),
        ( 'RID_' )

假设您的表格中有以上数据

现在如果你想用DECLARE执行插入@PREFIX NVARCHAR(10)='RID _'

INSERT  INTO #PROJECTS
    ( PREFIX ,
      PROJECTID
    )
    SELECT  @PREFIX  ,
            @PREFIX  + CAST(( COUNT(TT.rn) + 1 ) AS NVARCHAR(1))
    FROM    ( SELECT    ROW_NUMBER() OVER ( PARTITION BY P.PREFIX ORDER BY ( SELECT
                                                          NULL
                                                          ) ) AS rn
              FROM      #PROJECTS AS P
              WHERE     P.PREFIX = @PREFIX
            ) AS tt

见上面的查询可能对您有所帮助。

答案 1 :(得分:0)

嘿,请使用此查询..

                CREATE FUNCTION DBO.GET_NEX_P_ID(@PREF VARCHAR(4))
        RETURNS NVARCHAR(24)
        AS
        BEGIN
        RETURN  (SELECT @PREF+CAST(COUNT(1)+1 AS VARCHAR) FROM PROJECTS WHERE PREFIX=@PREF) 
        END
        GO

        CREATE TABLE PROJECTS
        (
        PREFIX VARCHAR(8),
        PROJECTID NVARCHAR(24)
        )

        GO
        INSERT INTO PROJECTS
        VALUES('PRJ_',DBO.GET_NEX_P_ID('PRJ_'))
        GO
        INSERT INTO PROJECTS
        VALUES('PRQ_',DBO.GET_NEX_P_ID('PRQ_'))
        GO

由于

答案 2 :(得分:0)

嗨,我在 Ms Sql 服务器上工作了几个小时后找到了 ansowr

USE [StocksDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[tb1_triger]
ON  [dbo].[Table1]
instead of INSERT
AS 
declare @name  nchar(12)
select top 1 @name=name from inserted
declare @maxid char(12)
select @maxid = MAX(id1) from Table1

BEGIN
 SET NOCOUNT ON;
  if (@maxid is null)
  begin
   set @maxid=0
  end
   set @maxid= substring(@maxid,  5 , LEN(@maxid))+1

  INSERT INTO table1 
  (id1,name) SELECT CONCAT_WS((REPLICATE('0',12-4-LEN(@maxid))),'tblo',@maxid),i.name
  from inserted i
  END

答案 3 :(得分:0)

您可以使用表上的 INSTEAD OF 触发器而不是使用 PERSISTED 列来执行此操作。我已经编写了触发器,以便它可以正确处理批量插入,因为这是很多人所忽视的。此外,对于我的解决方案,如果您不想要IDENTITY 列,则无需在表上添加该列。

因此该表已被定义为包含该列。此外,您可以去掉我上面提到的 IDENTITY 列:

CREATE TABLE dbo.PROJECTS
(
    ID INT IDENTITY(1, 1) NOT NULL,
    PREFIX NVARCHAR(10) NOT NULL,
    PROJECTID NVARCHAR(20) NOT NULL
);

注意 - 由于 PREFIX 列是 NVARCHAR(10) 并且我不知道数字会有多大,因此增加了 PROEJCTID 列的大小以防止溢出。根据您的数据需要调整大小。

这是触发器:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER dbo.InsertProjects
   ON  dbo.PROJECTS
   INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;
    DECLARE @rowsAffected INT = (SELECT COUNT(*) FROM Inserted);
    -- if there are no rows affected, no need to do anything
    IF @rowsAffected = 0 RETURN;

    DECLARE @ExistingCounts TABLE (
        Prefix NVARCHAR(10) NOT NULL, 
        ExistingCount INT NOT NULL
    );

    -- get the count for each existing prefix
    INSERT INTO @ExistingCounts(Prefix, ExistingCount)
    SELECT PREFIX, COUNT(*) FROM dbo.PROJECTS GROUP BY PREFIX;

    -- since this is an INSTEAD OF trigger, we must do the insert ourself.
    -- a prefix might not exist, so use ISNULL() to get a zero in that case.

    INSERT INTO dbo.PROJECTS
    (
        PREFIX, PROJECTID
    )
    SELECT sub.PREFIX, 
        -- the number after the prefix is the existing count for the prefix plus 
        -- the position of the prefix in the Inserted table
        sub.PREFIX + CAST((sub.ExistingCount + sub.Number) AS NVARCHAR(10))
    FROM 
    (SELECT i.PREFIX,
            -- get the position (1, 2, 3...) of the prefix in the Inserted table
           ROW_NUMBER() OVER(PARTITION BY i.PREFIX ORDER BY i.PREFIX) AS [Number], 
           -- get the existing count of the prefix
           ISNULL(c.ExistingCount, 0) AS [ExistingCount]
    FROM Inserted AS i 
    LEFT OUTER JOIN @ExistingCounts AS c ON c.Prefix = i.PREFIX) AS sub;
END
GO

我在源代码中添加了注释来解释简单的逻辑。希望这会有所帮助,并且是您正在寻找的 :-)