复合增量列

Composite increment column

我有一种情况需要将辅助列递增 1,假设另一个列的值相同。

Table 架构:

CREATE TABLE [APP].[World]
(
    [UID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [App_ID] [bigint] NOT NULL,
    [id] [bigint] NOT NULL,
    [name] [varchar](255) NOT NULL,
    [descript] [varchar](max) NULL,
    [default_tile] [uniqueidentifier] NOT NULL,
    [active] [bit] NOT NULL,
    [inactive_date] [datetime] NULL
)

首先,我有 UID,无论 App_ID 是什么,它都是独一无二的。

在我的情况下,我希望 idIncrement(1,1) 相似,只是为了相同的 App_ID

假设:

  1. 有3个App_Id: 1, 2, 3

场景:

理想结果:

App_ID  id
1       1
2       1
3       1
1       2
2       2
1       3
2       3
2       4
2       5

正在考虑将增量逻辑放在 Insert 存储过程中,但想看看是否有更简单或不同的方法在没有存储过程的情况下产生相同的结果。

图可用的选项是触发器或存储过程实现,但我想确保没有遗漏一些极端情况模式。

更新 #1

让我们重新考虑一下。

这是关于在 App_ID 上有一个 PK UID 和最终的分区列 id,关联 [=25] 的每个新条目都会增加 1 =].

这不可能实现您要求的方式。正如其他人在对您的原始 post 的评论中指出的那样,您的数据库设计最好拆分成多个表,这些表都有自己的身份并在必要时使用外键约束。

但是,如果您坚持使用这种方法,我会让 app_id 成为一个标识列,然后通过首先查询它来增加 id 列

MAX(identity)

然后将响应递增 1。这种逻辑适合在存储过程中实现,无论如何您都应该为插入实现它以防止直接 sql 注入等。此类过程的查询部分可能如下所示:

INSERT INTO
  [db].dbo.[yourtable]
SET
  (
    app_id
    , id
  ) 
VALUES
  (
   @app_id
   , (
        SELECT
          MAX(id)
        FROM
          [db].dbo.[table]
          WHERE
            App_id = @app_id
     )
   )

然而,这样做对性能的影响取决于您的评估。 此外,您还需要考虑如何在没有前一行的情况下正确处理 app_id.

最简单的解决方案如下:

    /* Adding Leading 0 to [App_ID] */
[SELECT RIGHT(CONCAT('0000', (([App_ID] - (([App_ID] - 1) % 3)) / 3) + 1), 4) AS [App_ID]

我在最近的代码中做了类似的事情,请找到下图。

希望下面的例子对您有所帮助。

解释部分 - 在下面的代码中,使用了 MAX(Primary_Key 标识列) 并在 ISNULL(NULL,1) 的帮助下处理了第一个条目的情况。在所有其他情况下,它将加起来 1 并给出唯一值。根据要求和需要,我们可以进行更改并使用以下示例代码。 WHILE循环只是为了展示demo(其实不需要)。

IF OBJECT_ID('dbo.Sample','U') IS NOT NULL 
  DROP TABLE dbo.Sample 

CREATE TABLE [dbo].[Sample](
    [Sample_key] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,    
    [Student_Key] [int] UNIQUE NOT NULL,
    [Notes] [varchar](100) NULL,
    [Inserted_dte] [datetime] NOT NULL
)

DECLARE @A INT,@N INT
SET @A=1
SET @N=10
WHILE(@A<=@N)
BEGIN
    INSERT INTO [dbo].[Sample]([Student_Key],[Notes],[Inserted_dte])
    SELECT ISNULL((MAX([Student_Key])+1),1),'NOTES',GETDATE() FROM  [dbo].[Sample]
    SET @A+=1
END

SELECT * FROM [dbo].[Sample]