我想使用前缀实现自动增量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
答案 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
我在源代码中添加了注释来解释简单的逻辑。希望这会有所帮助,并且是您正在寻找的 :-)