gra*_*eds 0 t-sql sql-server-2000
我有一张桌子.该表需要存储一个关于某个位置的数字值,所以最初我只有两个没有递增列的列,给出以下内容:
RefID | TypeID
1 | 1
1 | 3
1 | 6
2 | 3
3 | 5
3 | 6
Run Code Online (Sandbox Code Playgroud)
第一列是位置的参考,第二列是实际值.
问题是如何确定给第一列的值.我的想法是添加一个自动递增字段来生成这些值,所以我将改为以下数据:
ID | RefID | TypeID
1 | 1 | 1
2 | 1 | 3
3 | 1 | 6
4 | 4 | 3
5 | 5 | 5
6 | 5 | 6
Run Code Online (Sandbox Code Playgroud)
因此,自动编号列(第1列)充当参考列的种子.
所以我有两个问题 - 将标识列值复制到引用列,并将引用值返回给应用程序,以便在该位置有多个值时可以使用它.
我想出了这个存储过程:
CREATE PROCEDURE [dbo].[AddCaseType]
(
@TypeID INTEGER,
@CaseID INTEGER = NULL OUT
)
AS
BEGIN
INSERT INTO
dbo.CaseTypeList(RefID, TypeID)
VALUES
( ISNULL(@CaseID,SCOPE_IDENTITY()), @TypeID)
Set @CaseID = SCOPE_IDENTITY()
END
GO
Run Code Online (Sandbox Code Playgroud)
ISNULL在CaseID上检查NULL,如果为null则使用该SCOPE_IDENTITY()
值.SCOPE_IDENTITY
在插入之前评估Howevert ,从而返回生成的最后一个标识而不是新标识.
我不能使用相关表中的唯一值,因为如果用户编辑值,我需要完全跟踪.
所以我知道自己想做什么,但却没有足够的知识或经验.
所以封装:如何为集合的第一项生成一个唯一值并返回该值,以便我可以将其重用于该集合的其余部分?
如果有另一种更简单的方法,你也可以回答.请记住 - 我是SQL的新手,所以我需要理解为什么会发生一些事情因为我将来可能需要改变它.
更新:抓到咖啡后我注意到我的代码中出现了错误 - 更改为三列的结果,因此[ID]在INSERT语句的第一部分变为RefID.这也使一些代码无效,从而部分地改变了我的问题的性质.很抱歉这可能造成混乱.
插入带有identity
列的表时,不要为identity
列指定任何内容:
DECLARE @ERR INT
INSERT INTO CaseTypeList (TypeID, CaseID) --Column1 is auto-number, skip it
VALUES (@TypeID, @CaseID)
-- capture error var and last inserted identity value
SELECT @ERR = @@ERROR, @ID = SCOPE_IDENTITY()
-- IF @ERR <> 0 handle error, otherwise return
Run Code Online (Sandbox Code Playgroud)
除非您想明确控制数字,否则您不需要身份插入或类似的东西.在这种情况下,您不会将其设置为identity
.
另外,我猜你的专栏.
编辑:好的,所以看起来你根本不需要身份栏.相反,如果未提供下一个数字,则需要生成序列中的下一个数字.在这种情况下,您可以将标识列留在那里 - 它不会伤害任何内容,但如果您想要一个唯一的密钥,可能会有所帮助:
CREATE PROCEDURE [dbo].[AddCaseType]
(
@RefID INTEGER = NULL OUT,
@TypeID INTEGER
)
AS
BEGIN TRANSACTION
IF @RefID IS NULL BEGIN
SELECT @RefID = MAX(RefID)+1 FROM CaseTypeList
END
IF @@ERROR <> 0 BEGIN ROLLBACK; RAISERROR('Could not get ID', 16, 1) END
INSERT INTO
CaseTypeList(RefID, TypeID)
VALUES
(@RefID, @TypeID)
IF @@ERROR <> 0 BEGIN ROLLBACK; RAISERROR('Could not insert', 16, 1) END
COMMIT TRANSACTION
Run Code Online (Sandbox Code Playgroud)
注意:如果没有重复项,您可能应该在RefID和TypeID上具有唯一键约束.