如何在不使用IDENTITY的情况下自动增加列?

时间:2011-02-21 18:08:20

标签: sql-server

我正在创建一个包含两列的表,我希望自动增加。一列是主键,因此我在其上使用IDENTITY关键字。另一列将用于跟踪表中用户定义的项目“排序顺序”。每当用户移动项目时,其“排序顺序”将交换值与另一个元素的值。但是,当项目插入表格时,应始终自动为插入的项目分配高于表格中任何其他值的排序顺序值。这是表创建脚本的简化版本:

CREATE TABLE [AnswerRow] (
    [AnswerRowId] [int] IDENTITY(1,1) NOT NULL,
    [SortOrder] [int] NOT NULL,
    [IsDeleted] [bit] NOT NULL CONSTRAINT [DF_AnswerRow_IsDeleted] DEFAULT 0,
    CONSTRAINT [PK_AnswerRow] PRIMARY KEY CLUSTERED ([AnswerRowId] asc)
)

使SortOrder列自动增量的最佳方式是AnswerRowId列的相同方式(但之后仍然可以修改排序顺序值)?

4 个答案:

答案 0 :(得分:10)

我不确定这是否是@Stephen Wrighton的想法,但我认为你可以使用插入触发器来利用为AnswerRowId生成的IDENTITY值:

CREATE TRIGGER [dbo].[AnswerRowInsertTrigger]
   ON  [dbo].[AnswerRow]
   AFTER INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    UPDATE a SET a.SortOrder = a.AnswerRowId
    FROM AnswerRow a JOIN inserted i ON a.AnswerRowId = i.AnswerRowId

END

答案 1 :(得分:5)

立即想到两种方式,第一种是触发器,这不是我个人所做的。

第二个,就是让我的SQL在这些方面做点什么:

INSERT INTO AnswerRow(SortOrder, IsDeleted, Answer)
SELECT MAX(SortOrder) + 1, 0, 'My New Answer'
FROM AnswerRow

答案 2 :(得分:3)

对于它的价值,我发现在我的排序位置使用浮点列比使用整数值要容易得多。对于新记录,您仍然需要一个触发器,将该值设置为等于最大现有值加上一些常量(比如100)。但是,要更新项目的排序位置,您只需找到之前条目的排序位置和您要移动的条目之后的条目。平均这两个值,您就有了新的排序位置。

答案 3 :(得分:0)

DECLARE @NextItem int

SET @NextItem =    (SELECT 
       COUNT(*) + 1 AS NewSortOrder
    FROM 
       MyTable 
    WHERE 
       AnswerRowID=@AnswerRowID 
    ORDER BY 
       SortOrder ASC)


   --now you can use @NextItem
   INSERT INTO AnswerRow(SortOrder, IsDeleted) VALUES(@NextItem, 0)

或者您只需使用当前订单:

 SELECT TOP 1 (ISNULL(SortOrder, 0) + 1) as NewSortOrder FROM AnswerRow WHERE AnswerRowID=@AnswerRowID ORDER BY SortOrder DESC

如果没有记录,您可能需要检查是否返回NULL,请在BOL中检查IsNULL

无论哪种方式,您要获取当前数字,添加一个,然后使用该值进行插入。