开发者

How can I auto-increment a column without using IDENTITY?

开发者 https://www.devze.com 2023-02-13 00:28 出处:网络
I\'m creating开发者_如何转开发 a table with two columns that I want to auto-increment. One column is a primary key, so I\'m using the IDENTITY keyword on it. The other column will be used to track the

I'm creating开发者_如何转开发 a table with two columns that I want to auto-increment. One column is a primary key, so I'm using the IDENTITY keyword on it. The other column will be used to track the user-defined "sort order" of items in the table. Any time the user moves an item, its "sort order" will swap values with that of another element. However, when an item is inserted into the table, the inserted item should always be auto-assigned a sort-order value higher than any other value in the table. Here's a simplified version of the table creation script:

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)
)

What's the best way to make the SortOrder column auto-increment the same way the AnswerRowId column will (but still be able to modify sort-order values afterward)?


I'm not sure if this is what @Stephen Wrighton had in mind, but I think you could have an insert trigger make use of the IDENTITY value being generated for AnswerRowId:

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


Two ways come to mind right off, the first is a trigger, which is not what I'd do personally.

The second, would be to have my sql do something along these lines:

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


For what it's worth, I've found it much easier to use a floating-point column for my sort position than to use an integer value. For new records, you would still need a trigger that sets the value equal to the largest existing value plus some constant (say 100). For updating the sort position of an item, though, you can simply find the sort position of the entry before and the entry after the entry you are moving. Average those two values and you have your new sort position.


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)

Or you can simply use the current order:

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

You might want to check if this returns a NULL in case no records exist, check IsNULL in BOL.

Either way the point is you want to get the current number, add one to it, and then use that value to do your insert.

0

精彩评论

暂无评论...
验证码 换一张
取 消