这是我的表格,我希望我的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). :(
你可以运行这个。如果你找到任何可以帮助我的东西,请帮忙。任何帮助将不胜感激... 等待你的回应...
答案 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的格式化版本。
您使用预期方法运行的风险是:
答案 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)
这应该可以解决你的问题