Sql server 如何自动递增varchar

Sql server 如何自动递增varchar,sql-server,database-design,Sql Server,Database Design,我可以在一个表中为供应商“s0001、s0002”和“c0001、c0002”生成主键吗?否。如果您确实需要此主键,则必须手动生成ID 数据库设计的思想是使每个数据元素保持独立。每个元素都有自己的数据类型、约束和规则。c0002不是一个字段,而是两个字段。与XXXnnn或任何内容相同。这是不正确的,它将严重限制您使用数据以及使用数据库功能和设施的能力 将其分解为两个离散的数据项: column_1 CHAR(1) 列2整数 然后在列2上设置自动增量 是的,您的主键可以是(第1列,第2列),因此您

我可以在一个表中为供应商“s0001、s0002”和“c0001、c0002”生成主键吗?

否。如果您确实需要此主键,则必须手动生成ID

  • 数据库设计的思想是使每个数据元素保持独立。每个元素都有自己的数据类型、约束和规则。
    c0002
    不是一个字段,而是两个字段。与
    XXXnnn
    或任何内容相同。这是不正确的,它将严重限制您使用数据以及使用数据库功能和设施的能力

    将其分解为两个离散的数据项:
    column_1 CHAR(1)
    列2整数

    然后在
    列2上设置自动增量

    是的,您的主键可以是
    (第1列,第2列)
    ,因此您不会失去
    c0002
    对您的意义

  • 切勿将供应商和客户(无论“c”和“s”是什么意思)放在同一张表中。如果这样做,就不会有数据库表,而是有一个平面文件。以及由此产生的各种问题和限制

    这意味着,数据正常化。您最终将得到:

    • 一个用于
      人员
      组织
      的表格,包含公共数据(
      姓名、地址
      …)
    • 一个包含客户特定数据的客户表(
      CreditLimit
    • 一个包含供应商特定数据的供应商表(
      PaymentTerms
    • 没有不明确或可选的列,因此没有空值
    • 对使用或SQL函数没有限制
      .
    当需要添加列时,只在需要的地方添加,而不会影响平面文件的所有其他问题。影响范围仅限于变更范围


  • 不在一个表中为客户执行“c0001,c0002”,为供应商执行“s0001,s0002”,而是按以下方式执行:

    • 创建一个数据类型为“
      int(10)unsigned
      ”的自动递增字段“
      id
    • 创建数据类型“
      enum('c','s')
      ”(其中c=客户,s=供应商)的另一个字段“
      type

    正如“@PerformanceDBA”所指出的,然后您可以为两个字段“
    id
    ”和“
    type
    ”创建主键索引,以便使用正确的方法满足您的需求

    我更喜欢人工主键。您的需求也可以实现为计算列上的唯一索引:

    CREATE TABLE [dbo].[AutoInc](
      [ID] [int] IDENTITY(1,1) NOT NULL,
      [Range] [varchar](50) NOT NULL,
      [Descriptor]  AS ([range]+CONVERT([varchar],[id],(0))) PERSISTED,
      CONSTRAINT [PK_AutoInc] PRIMARY KEY ([ID] ASC)
    )
    
    GO
    
    CREATE UNIQUE INDEX [UK_AutoInc] ON [dbo].[AutoInc] 
    (
        [Descriptor] ASC
    )
    
    GO
    

    为主键指定域含义是一种实践,可以追溯到Cobol程序员和恐龙一起在地球上行走的时代。这种做法一直延续到今天,最常见的是遗留库存系统。它主要是一种消除一列或多列数据并将消除列中的数据嵌入PK值的方法

    如果您想将customer和supplier存储在同一个表中,只需这样做,并使用一个自动递增的整数PK,然后添加一个名为ContactType的列或类似的列,该列可以包含值“S”和“C”或其他值。您不需要复合主键

    如果要消除列以节省空间(即在打印或显示的页面上),则始终可以在报告上连接这些列(PK和ContactType),例如C12345、S20000(将整数转换为字符串),组织中的每个人都理解这样一种约定,即实体id的第一个字符代表ContactType代码

    这种方法将利用数据库引擎内置的自动递增功能,简化数据层中的PK和相关代码,并使程序和数据库更加健壮

    我的方法是:

    • 创建一个
      idintidentity
      列,并将其用作主键(它是唯一的、狭窄的、静态的、完美的)

    • 如果您确实需要一个带有字母或其他内容的ID,请根据该
      ID INT IDENTITY

    试着这样做:

    CREATE TABLE dbo.Demo(ID INT IDENTITY PRIMARY KEY,
                          IDwithChar AS 'C' + RIGHT('000000' + CAST(ID AS VARCHAR(10)), 6) PERSISTED
                         )
    
    此表将包含
    1、2、3、4中的
    ID
    值。
    IDwithChar
    类似于
    C000001、C000002、…、C000042等

    有了这一点,您就可以两全其美:

    • 表上的一个适当的、非常适合的主键(和集群键),非常适合从其他表引用

    • 您的基于字符的ID,正确定义,计算,始终是最新的


    首先,让我们声明,您不能直接这样做。如果你尝试

    create table dbo.t1 (
    id varchar(10) identity,
    );
    
    错误消息告诉您直接支持哪些数据类型

    Msg 2749,16级,状态2,第1行 死亡“id”-身份证 Datentyp'int'、'bigint'、'smallint', “tinyint”或“decimal”bzw。 “数字”mit 0 Dezimalstellen sein 还有keine空的Werte zulassen

    顺便说一句:我试图在BOL或MSDN中查找此信息,但失败了


    现在知道你不能用直接的方法来做,使用计算列来遵循@marc_的建议是一个不错的选择

    是的,实际上这是两个不同的问题, 1.我们可以使用varchar列作为具有唯一值(如类中的卷号)的自动增量列吗

    答:是的,您可以使用下面的代码,而不指定ID和p_ID的值

    CREATE TABLE dbo.TestDemo
      (ID INT IDENTITY(786,1) NOT NULL PRIMARY KEY CLUSTERED,
       P_ID AS 'LFQ' + RIGHT('00000' + CAST(ID AS VARCHAR(5)), 5) PERSISTED,
       Name varchar(50),
       PhoneNumber varchar(50)
      )
    
  • 同一列中有两个不同的增量
  • 答:不,你不能在一张桌子上用这个

    INSERT INTO Yourtable (yourvarcharID) 
      values('yourvarcharPrefix'+(
          SELECT CAST((SELECT CAST((
          SELECT Substring((
          SELECT MAX(yourvarcharID) FROM [Yourtable ]),3,6)) AS int)+1) 
            AS VARCHAR(20))))
    

    这里,
    varchar
    列的前缀是'RX',然后是
    001
    ,因此我在它的前缀之后选择了
    substring
    ,并单独增加了该数字。

    我们可以添加带有表定义的
    默认约束函数来实现这一点

    首先创建表格-

    create table temp_so (prikey varchar(100) primary key, name varchar(100))
    go
    
    create function dbo.fn_AutoIncrementPriKey_so ()
    returns varchar(100)
    as
    begin
        declare @prikey varchar(100)
        set @prikey = (select top (1) left(prikey,2) + cast(cast(stuff(prikey,1,2,'') as int)+1 as varchar(100)) from temp_so order by prikey desc)
        return isnull(@prikey, 'SB3000')
    end
    go
    
    alter table temp_so
    add constraint df_temp_prikey
    default dbo.[fn_AutoIncrementPriKey_so]() for prikey
    go
    
    insert into temp_so (name) values ('Rohit')
    go 4
    
    select * from temp_so
    
    prikey  name
    SB3000  Rohit
    SB3001  Rohit
    SB3002  Rohit
    SB3003  Rohit
    
    第二次创建新的
    用户定义函数
    -
    <
    SET @variable1 = SUBSTR((SELECT id FROM user WHERE id = (SELECT MAX(id) FROM user)), 5, 7)+1;
    SET @variable2 = CONCAT("LHPL", @variable1);
    INSERT INTO `user`(`id`, `name`) VALUES (@variable2,"Jeet");