如何在 Sql Server 2005 中创建自定义字母数字主键
我写了这个算法 a 并且它是正确的: 表是:
create table PrimKeyTest (primarykeycolumn varchar(8), nextcolumn int)
GO
insert into PrimKeyTest values ('P09-0001', 1)
GO
我的功能是:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[GetSpecialPrimaryKey](@yearvalue int)
returns nvarchar(8)
as
begin
declare @maxkey varchar(4)
declare @maxLength int, @maxkeylength int
set @maxLength = 4
select @maxkey = ISNULL(cast(max(cast(substring(primaryKeycolumn, 5, 4) as integer)+1) as varchar),'1')
from PrimKeyTest
where substring(primaryKeycolumn, 2, 2) = substring(convert(varchar, @yearvalue), 3, 2)
set @maxkeylength = len(@maxkey)
while @maxkeylength < @maxLength
begin
set @maxkey = '0' + @maxkey
set @maxkeylength = len(@maxkey)
end
return 'P' + substring(convert(varchar, @yearvalue), 3, 2) + '-' + @maxkey
end
现在当我删除该表的最后一行时,新的最后一条记录给出正确的数字,例如。 P09-0001 P09-0002 P09-0003 P09-0004 P09-0005 但是当我删除该表的第二行时,主列的顺序不正确 例如。 P09-0001 P09-0003 P09-0004 P09-0005 你能帮助我吗? 我想要这个:P09-0001 P09-0002 P09-0003 P09-0004
i write this alghorithm a and it's correct:
Tables were :
create table PrimKeyTest (primarykeycolumn varchar(8), nextcolumn int)
GO
insert into PrimKeyTest values ('P09-0001', 1)
GO
and My function is :
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[GetSpecialPrimaryKey](@yearvalue int)
returns nvarchar(8)
as
begin
declare @maxkey varchar(4)
declare @maxLength int, @maxkeylength int
set @maxLength = 4
select @maxkey = ISNULL(cast(max(cast(substring(primaryKeycolumn, 5, 4) as integer)+1) as varchar),'1')
from PrimKeyTest
where substring(primaryKeycolumn, 2, 2) = substring(convert(varchar, @yearvalue), 3, 2)
set @maxkeylength = len(@maxkey)
while @maxkeylength < @maxLength
begin
set @maxkey = '0' + @maxkey
set @maxkeylength = len(@maxkey)
end
return 'P' + substring(convert(varchar, @yearvalue), 3, 2) + '-' + @maxkey
end
Now when i delete last row of this table ,new last record give correct number eg.
P09-0001 P09-0002 P09-0003 P09-0004 P09-0005
but when i delete 2nd row of this table order of primary column has incorrect
eg. P09-0001 P09-0003 P09-0004 P09-0005
can you help me?
i want this: P09-0001 P09-0002 P09-0003 P09-0004
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这实际上不是处理主键的好方法。这样做意味着每当删除一个密钥时(除非是最后一个密钥),就要“重新调整”所有密钥。这样做可能是一个复杂、成本高昂且容易出错的过程。例如,您在此表中有一个 pkey,可能会通过其他表的外键引用它。如果您更改第一个表中的 pkey 值,那么您还必须在引用它的所有其他表中更改它。这意味着在更改等期间放弃任何限制。
看起来您正在尝试创建一个很可能呈现给最终用户的标识符。您可以继续使用您的函数来执行此操作,但不要将其设为主键。使用自动递增列作为主键,使用“P09-N”值作为单独的字段。然后,如果您想修改这些值,您可以这样做,而不会影响表设计的其余部分。
现在,要在删除表时更新表的标识符值,您可能需要在存储过程中使用游标。这是一个很好的游标概述。您还可以使用 CTE(通用表表达式)来执行
这是一个光标示例,其中 Col1 是您的 pkey,Col2 是您要更改的标识符:
我没有执行前导零逻辑,但您可以很容易地在 Google 上搜索到这一点。
This is actually not a great approach to dealing with primary keys. Doing this means "realigning" all of your pkeys whenever one is deleted (except when it's the last.) Doing this could be a complex, costly and error-prone process. For example, you have a pkey in this table which will probably be referenced via a foreign key from other tables. If you change the value of the pkey in the first table then you also have to change it in all the other tables that reference it. This means dropping any constraints for the duration of the change etc.
It looks like you're trying to create an identifier that will most likely be presented to the end user. You can go ahead and use your function to do that, BUT do not make it a primary key. Use an auto-incrementing column as the primary key and the 'P09-N' value as a separate field. Then, if you want to modify the values you can do so without affecting the rest of your table design.
Now to update the identifier values for the table whenever one is deleted you'll probably need to use a cursor in a stored procedure. Here's a good overview on cursors. You could also use CTEs (Common Table Expressions) to do the updating.
Here is a cursor example where Col1 is your pkey and Col2 is the identifier you want to change:
I didn't do the leading zero logic but you can Google for that pretty easily.