如何创建唯一的用户密钥

时间:2010-05-12 21:50:03

标签: sql-server database

场景:我有一个相当通用的表(Data),它有一个标识列。此表中的数据已分组(按城市说)。

用户需要一个标识符才能在纸质表格上打印等。 用户只能访问他们的引用数据,因此如果他们为此目的使用标识列,他们将看到奇数(例如'纽约'用户可能会看到1,37,2028 ...作为列出的密钥。

理想情况下,他们会看到1,2,3 ...(或类似的东西)

问题当然是并发性,这是一个Web应用程序,你不能只有这样的东西:    UserId =从Data = City ='New York'

的数据中选择Count(*)+ 1

有没有人想出任何狡猾的解决这个问题的方法?

更新 - 从下面的评论中我想我想要类似下面的SP。不完全确定递归应该如何在CATCH块中起作用。

ALTER PROCEDURE [dbo].[DataContainer_Insert] 
@SomeData varchar(max),
@DataContainerId int out    
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    BEGIN TRY
        SELECT @UserId = MAX(UserId) From DataContainer
        INSERT INTO DataContainer (UserId, SomeData)
        VALUES (@UserId, SomeData)

        SELECT @DataContainerId = scope_identity()
    END TRY
    BEGIN CATCH
        --try again
        exec DataContainer_Insert @DataContainerId, @SomeData
    END CATCH       

END

3 个答案:

答案 0 :(得分:1)

在关闭情况下,如果我从GROUP BY T语句中使用SELEC生成的服务器数据发送回来,并且每行需要id,我使用ROW_NUMBER() (见http://msdn.microsoft.com/en-us/library/ms186734.aspx)。这在数据分页的情况下也很好(参见http://weblogs.asp.net/Firoz/archive/2005/06/12/411949.aspx中的一个简单示例)。这是因为这需要SQL Server 2005或更高版本。您没有编写您使用的SQL Server。

答案 1 :(得分:1)

好吧,如果你在city和UserId上添加跨越唯一性约束(为了保证只有1个特定Id和City的实例),你可以使用UserId = Select Count(*)+1 from Data Where City='New York'想法。然后你只需要能够处理约束违规(通过重新提交)。

答案 2 :(得分:1)

作为一般性评论:您可以执行类似

的操作
newUserId = Select MAX(UserId)+1 from Data Where City='New York'
INSERT INTO data (...) VALUES (newUserId, ...)

即使在并发访问方案(例如Web应用程序)中,只要您采用适当的并发控制,即(a)锁定或(b)事务,适当的隔离级别。

有关如何使用SQL Server执行此类操作的深入分析,请参阅question 1994771