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是varchar
max(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列。因此,如果有帮助的话,考虑做一个变通。