简体   繁体   English

在 SQL Server 2008 R2 中,有没有办法在不使用 IDENTITY(1,1) 的情况下创建自定义自动增量标识字段?

[英]In SQL Server 2008 R2, is there a way to create a custom auto increment identity field without using IDENTITY(1,1)?

I would like to be able to pull the custom key value from a table, but would also like it to perform like SQL Server's IDENTITY(1,1) column on inserts.我希望能够从表中提取自定义键值,但也希望它在插入时像 SQL 服务器的IDENTITY(1,1)列一样执行。

The custom key is for another application and will need to be used by different functions so the value will need to be pulled from a table and available for other areas.自定义键用于另一个应用程序,需要由不同的功能使用,因此需要从表中提取值并用于其他区域。

Here are some if my attempts:以下是我的一些尝试:

  1. Tried a trigger on the table works well on single inserts, failed on using SQL insert (forgetting the fact that a triggers are not per row but by batch)尝试在表上使用触发器在单次插入时效果很好,在使用 SQL 插入时失败(忘记触发器不是按行而是按批处理的事实)
ALTER TRIGGER [sales].[trg_NextInvoiceDocNo] 
ON [sales].[Invoice]
AFTER INSERT 
AS
BEGIN
    DECLARE @ResultVar VARCHAR(25)
    DECLARE @Key VARCHAR(25)

    EXEC [dbo].[usp_GetNextKeyCounterChar] 
               @tcForTbl = 'docNbr', @tcForGrp = 'docNbr', @NewKey =      @ResultVar OUTPUT

    UPDATE sales.InvoiceRET
    SET DocNbr = @ResultVar
    FROM sales.InvoiceRET
    JOIN inserted ON inserted.id = sales.InvoiceRET.id;
END;
  1. Thought about a scalar function, but functions cannot exec stored procedures or update statements in order to set the new key value in the lookup table.考虑过一个标量 function,但函数不能执行存储过程或更新语句以便在查找表中设置新的键值。

Thanks谢谢

You can use ROW_NUMBER() depending on the type of concurrency you are dealing with.您可以根据要处理的并发类型使用ROW_NUMBER() Here is some sample data and a demo you can run locally.这是一些示例数据和可以在本地运行的演示。

-- Sample table
USE tempdb
GO
IF OBJECT_ID('dbo.sometable','U') IS NOT NULL DROP TABLE dbo.sometable;
GO
CREATE TABLE dbo.sometable
(
  SomeId INT NULL,
  Col1   INT NOT NULL
);
GO

-- Stored Proc to insert data
CREATE PROC dbo.InsertProc @output BIT AS
BEGIN -- Your proc starts here
  INSERT dbo.sometable(Col1) 
  SELECT datasource.[value]
  FROM   (VALUES(CHECKSUM(NEWID())%100)) AS datasource([value]) -- simulating data from somewhere
  CROSS APPLY (VALUES(1),(1),(1)) AS x(x);

  WITH 
  id(MaxId) AS (SELECT ISNULL(MAX(t.SomeId),0) FROM dbo.sometable AS t),
  xx AS 
  (
    SELECT     s.SomeId, RN = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))+id.MaxId, s.Col1, id.MaxId
    FROM       id     AS id
    CROSS JOIN dbo.sometable AS s
    WHERE      s.SomeId IS NULL
  )
  UPDATE xx SET xx.SomeId = xx.RN;

  IF @output = 1
  SELECT t.* FROM dbo.sometable AS t;
END
GO 

Each time I run: EXEC dbo.InsertProc 1;每次我运行: EXEC dbo.InsertProc 1; it returns 3 more rows with the correct ID col.它返回 3 行具有正确 ID col 的更多行。 Each time I execute it, it adds more rows and auto-increments as needed.每次我执行它时,它都会根据需要添加更多行和自动增量。

SomeId   Col1
-------- ------
1        62
2        73
3        -17

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM