Asp.net 自动递增varchar数据类型设置为主键
我已经创建了一个表,其中的Asp.net 自动递增varchar数据类型设置为主键,asp.net,sql,stored-procedures,database-design,type-conversion,Asp.net,Sql,Stored Procedures,Database Design,Type Conversion,我已经创建了一个表,其中的Id列为varchar(20) 我需要一个可以将id增加1的存储过程 我试过这个: ALTER PROCEDURE dbo.spInsertCatQuery (@Users_Id varchar(20), @Cat_Id varchar(20), @Query varchar(100), @Query_Title varchar(50) ) AS BEGIN Declare @Query_Id bigint SEL
Id
列为varchar(20)
我需要一个可以将id
增加1的存储过程
我试过这个:
ALTER PROCEDURE dbo.spInsertCatQuery
(@Users_Id varchar(20),
@Cat_Id varchar(20),
@Query varchar(100),
@Query_Title varchar(50)
)
AS
BEGIN
Declare @Query_Id bigint
SELECT @Query_Id = coalesce((select max(Query_Id) + 1 from tblCatQuery), 1);
INSERT INTO tblCatQuery
VALUES(@Query_Id, @Users_Id, @Cat_Id, @Query_Title, @Query)
END
但在第10条记录之后,它不起作用。将表中的
Query\u id
选项更改为下面的选项
SELECT @Query_Id=
coalesce((select max(cast(Query_Id as int)) + 1 from tblCatQuery), 1);
根据戈登的评论;我的理解是,由于ID是varcharmax(ID)
并没有获取正确的max值,但强制转换它会这样做
例如,试试这个
create table testtab (id varchar(10));
insert into testtab values(2),(200),(53)
如果你在下面说,它将返回53
select MAX(id) from testtab
但这只会返回200英里
select MAX(cast(id as int)) from testtab
在SQL SERVER 2008 R2中测试,听起来应用程序需要ID字段的字符串,但在数据库中,您希望它的ID表现为自动递增的整数字段 考虑在数据库中使用整数,当您检索该值并需要将其用作字符串时,请在查询或应用程序中将该值转换为字符串
这将解决您的问题。您必须认真审查您的设计。我建议这样做
CREATE TABLE tblCatQuery(QueryId int NOT NULL PRIMARY KEY IDENTITY(1, 1),
UserId int NOT NULL REFERENCES tblUsers(UserId),
CatId int NOT NULL REFERENCES tblCat(CatId),
Query varchar(100), Query_Title varchar(50))
CREATE TABLE tblUsers(UserId int NOT NULL PRIMARY KEY IDENTITY(1, 1), ....
CREATE TABLE tblCat(CatId int NOT NULL PRIMARY KEY IDENTITY(1, 1), ....
CREATEPROCEDURE dbo.spInsertCatQuery
(
@Users_Id int,
@Cat_Id int,
@Query varchar(100),
@Query_Title varchar(50)
)
AS
BEGIN
INSERT INTO tblCatQuery(Users_Id, Cat_Id, Query_Title, Query)
VALUES( Users_Id, Cat_Id, Query_Title, Query)
END
您知道存储过程有一个隐式的竞争条件,是吗 在计算新查询id和表insert得到提交之间,可以进入另一个会话,获取完全相同的查询id,插入它并得到提交。猜猜当插入尝试提交时会发生什么?赢得第一名;第二个获取重复的密钥错误。不要问我是怎么知道的:) 如果确实需要文本查询id,可以尝试使用计算字段,如下所示:
create table dbo.tblCatQuery
(
query_id int not null identity(1,1) primary key clustered ,
query_id_text as right('0000000000'+convert(varchar,id),10) ,
user_id varchar(20) not null ,
cat_id varchar(20) not null ,
query varchar(100) not null ,
query_title varchar(50) not null ,
)
create procedure dbo.spInsertCatQuery
@Users_Id varchar(20) ,
@Cat_Id varchar(20) ,
@Query varchar(100) ,
@Query_Title varchar(50) ,
@Query_ID varchar(10) output
AS
insert dbo.tblCatQuery ( user_id , cat_id , query_title , query )
VALUES ( @Users_Id , @Cat_Id , @Query_Title , @Query )
-- give the caller back the id of the row just inserted
set @Query_ID = @@SCOPE_IDENTITY
-- for redundancy, hand it back as the SP's return code, too
return @Query_ID
GO
然后,您的存储过程如下所示:
create table dbo.tblCatQuery
(
query_id int not null identity(1,1) primary key clustered ,
query_id_text as right('0000000000'+convert(varchar,id),10) ,
user_id varchar(20) not null ,
cat_id varchar(20) not null ,
query varchar(100) not null ,
query_title varchar(50) not null ,
)
create procedure dbo.spInsertCatQuery
@Users_Id varchar(20) ,
@Cat_Id varchar(20) ,
@Query varchar(100) ,
@Query_Title varchar(50) ,
@Query_ID varchar(10) output
AS
insert dbo.tblCatQuery ( user_id , cat_id , query_title , query )
VALUES ( @Users_Id , @Cat_Id , @Query_Title , @Query )
-- give the caller back the id of the row just inserted
set @Query_ID = @@SCOPE_IDENTITY
-- for redundancy, hand it back as the SP's return code, too
return @Query_ID
GO
第10次记录后不工作
。。。需要更多的澄清。所以您希望varchar的行为像一个数字,但您对它不符合要求感到失望。好吧,用一个数字键。。。用户Id varchar(20),Cat Id varchar(20),我的第二个猜测:query\u Id
声明为varchar
或char
,没有长度。默认值为1。请解释一下这会有什么不同?@GordonLinoff,我认为这是有意义的,但使用varchar
类型的代理键并以这种方式自动递增是非常丑陋的设计。@HamletHakobyan同意;不建议这样做,ID列应该是注释中已经指出的INT列。因此,如果有帮助的话,考虑做一个变通。