如何生成id为每个插入时递增的列

时间:2012-03-09 13:03:21

标签: asp.net sql-server sql-server-2008 sql-server-2005 ado.net

这是我的表格,我希望我的PNRNo为第一个条目生成'PNRRES001',连续条目为'PNRRES002','PNRRES002'等等。 因此,在创建表时,我只调用该列来生成PNR否,用户只需从前端输入CustomerNo,然后输入PNR&客户编号将更新为PNRDetails表。

CREATE TABLE PNRDetails(PNRNo AS (DBO.FuncIncPNR()) ,customerNo INT

--FUNCTION TO GENERATE THE PNR NUMBER
ALTER FUNCTION dbo.FuncIncPNR()
RETURNS VARCHAR(20)
AS 
BEGIN
DECLARE @RR VARCHAR(20) SET @RR='PNRRESA001'
--here i have checked if no value is there then return the first value as 'PNRRESA001'
    IF((SELECT COUNT(*)FROM PNRDetails)=0)
    BEGIN
    RETURN @RR
    END
    ELSE
-- if any value is there then take the last value and add 1 to it and update to the table
    BEGIN
    DECLARE @pnr VARCHAR(20),@S1 VARCHAR(20),@S2 INT
    DECLARE PNRCursor CURSOR Static
    FOR SELECT PNRNo FROM PNRDetails
    OPEN PNRCursor
    FETCH LAST FROM PNRNo INTO @pnr
    SET @S1=SUBSTRING(@pnr,1,7)
    SET @S2=RIGHT(@PNR,3)
    SET @S2=@S2+1;
    SET @pnr=@S1+@S2;

    END
    RETURN @pnr
END

--Here am inserting only customerNo as 5 and the PNR should be generated by my function
INSERT INTO PNRDetails VALUES(5)
--it shows 1 row updated  :)
SELECT * FROM PNRDetails
-- but when i run select command it shows
--Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).  :(

你可以运行这个。如果你找到任何可以帮助我的东西,请帮忙。任何帮助将不胜感激... 等待你的回应...

5 个答案:

答案 0 :(得分:6)

您可以尝试使用计算列和标识列。

create table PNRDetails
(
  ID int identity,
  PNRNo as 'PNRRES'+right(1000+ID, 3),
  customerNo int
)

答案 1 :(得分:5)

我建议只使用IDENTITY作为你的id,让SQL Server处理每个id号的分配及其所有内置的并发保护,并将格式保留到UI ... 。或者,如果您确实需要在数据库中使用它,请创建一个computed column来定义ID的格式化版本。

您使用预期方法运行的风险是:

  • 表现不佳
  • 并发问题 - 如果在同一时间生成大量的ID

答案 2 :(得分:1)

如果您乐意更改表格结构。以下将完成这项工作。

CREATE TABLE [dbo].[PNRDetails](
[autoId] [int] IDENTITY(1,1) NOT NULL,
[prnNo]  AS ('PNRRES'+right('000'+CONVERT([varchar](3),[dbo].[GetRowCount]([autoId]),(0)),(3))),
[customerNo] [int] NOT NULL,
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED 
(
[autoId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,     ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

编辑:以解决您的要求的身份问题请创建以下函数并在计算列中传递[autoId] in(编辑)。

CREATE FUNCTION dbo.GetRowCount
(
@autoId INT
)
RETURNS INT
AS
BEGIN
DECLARE @RESULTS AS INT
SELECT @RESULTS = COUNT(autoId) FROM PNRDetails WHERE PNRDetails.autoId<@autoId
    RETURN @RESULTS + 1
END
GO

- INSERT

INSERT INTO PNRDetails (customerNo) VALUES(5)

答案 3 :(得分:0)

1)您可以在数据库中使用标识列(INTEGER)

  

PROS:生成的ID之间容易/无间隙

     

缺点:你必须选择插入的id&amp;通过程序/查询返回   如果你要向最终用户展示

2)定义数据库序列

  

PROS:易于实施/可以在表单之前存储/显示给用户   甚至保存了

     

缺点:如果某个id曾经生成过,则介于两者之间。没用过

3)。从列+ 1

中选择max(id)
  

PROS:仅在单个用户插入表格

时有用      

缺点:如果您处于多个用户的环境中,那将是灾难性的   插入相同的tablle(不匹配的max ids)

4)使用数据库触发器自动增加列

  

优点:自动

     

缺点:很难调试(你必须确保它不会破坏一些   插入失败的原因)

答案 4 :(得分:0)

更改触发器的工作方式。像这样的东西

CREATE FUNCTION dbo.fn_FuncIncPNR(@ID int)
RETURNS varchar(20)
BEGIN
Declare @Retval varchar(20),
        @No varchar(4)
Select @No = convert(varchar(4), @ID)
while Len(@No) < 4
    Select @No = '0' + @No      

Select @Retval = 'PNRRESA' + @No
RETURN @Retval
END

您会注意到有一个参数字段

将您的表格创建更改为此

CREATE TABLE PNRDetails(PNRNo AS (dbo.fn_ShowPNRNo(wID)), wID int IDENTITY(1,1) NOT NULL, customerNo INT)

这应该可以解决你的问题