我有一种情况,我需要将辅助列加1,假设另一列的值相同。
表架构:
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
是什么。
在我的情况下,我希望id
与Increment(1,1)
相似,仅适用于App_ID
。
假设:
App_Id
:1,2,3 情景:
App_ID
1有3个世界App_ID
2有5个世界App_ID
3有1个世界理想的结果:
App_ID id
1 1
2 1
3 1
1 2
2 2
1 3
2 3
2 4
2 5
考虑将增量逻辑放在Insert
存储过程中,但想知道在没有存储过程的情况下是否会有更简单或不同的方法产生相同的结果。
图可用的选项是触发器或存储过程实现,但是想确保没有一些我遗漏的边缘案例模式。
让我们重新考虑一下。
这是关于存在一个PK UID
,最终是一个分区列id
,超过App_ID
,对于关联的App_id
每个新条目都会增加1 。
Row_Number()
的方式类似,但每次插入新条目时都没有重新计算值的所有开销。App_ID
和id
都有BIGINT
的空间和潜力;因此,可能组合的组合数量为:BIGINT x BIGINT 答案 0 :(得分:0)
这不可能实现您的要求。正如其他人在您对原始帖子的评论中指出的那样,您的数据库设计在多个表中分离会更好,这些表都有自己的身份,并在必要时使用外键约束。
但是,如果您在继续这种方法时已经死定,我会将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的前一行时正确处理。
答案 1 :(得分:0)
最简单的解决方案如下:
/* Adding Leading 0 to [App_ID] */
[SELECT RIGHT(CONCAT('0000', (([App_ID] - (([App_ID] - 1) % 3)) / 3) + 1), 4) AS [App_ID]
我在最近的代码中做了类似的事情,请找到下面的图片。
答案 2 :(得分:0)
希望以下示例对您有所帮助。
说明部分-在下面的代码中,使用MAX(Primary_Key Identity列),并借助ISNULL(NULL,1)处理第一个输入项。在所有其他情况下,它将加1并给出唯一值。根据要求和需求,我们可以进行更改并使用以下示例代码。只是添加了WHILE循环以显示演示(实际上不需要)。
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]