TSQL插入难题

时间:2009-05-07 13:19:45

标签: tsql sql-server-2000

我有一张桌子。该表需要存储一个关于某个位置的数字值,所以最初我只有两个没有递增列的列,给出以下内容:

RefID | TypeID
    1 | 1
    1 | 3
    1 | 6
    2 | 3
    3 | 5
    3 | 6

第一列是位置的参考,第二列是实际值。

问题是如何确定给第一列的值。我的想法是添加一个自动递增字段来生成这些值,所以我将改为使用以下数据:

ID | RefID | TypeID
1  | 1   | 1
2  | 1   | 3
3  | 1   | 6
4  | 4   | 3
5  | 5   | 5
6  | 5   | 6

因此,自动编号列(第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

ISNULL在CaseID上检查NULL,如果它为null则使用SCOPE_IDENTITY()值。在插入之前评估Howevert SCOPE_IDENTITY,从而返回生成的最后一个标识而不是新标识。

我不能使用相关表格中的唯一值,因为如果用户编辑了值,我需要完全跟踪。

所以我知道自己想做什么,但却没有足够的知识或经验。

所以封装:如何为集合的第一项生成一个唯一值并返回该值,以便我可以将其重用于该集合的其余部分?

如果有另一种更简单的方法,你也可以回答。请记住 - 我是SQL的新手,所以我需要了解为什么会发生什么事情,因为我可能需要在将来更改它。

更新:抓取咖啡后,我发现代码中出现错误 - 更改为三列的结果,因此[ID]在INSERT语句的第一部分变为RefID。这也使一些代码无效,从而部分地改变了我的问题的性质。很抱歉这可能导致混淆。

1 个答案:

答案 0 :(得分:5)

当插入带有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

除非您想明确控制号码,否则您不需要身份插入或类似内容。在这种情况下,您不会将其设置为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 

注意:如果没有重复项,您可能应该在RefID和TypeID上有唯一键约束。