В SQL Server 2008 R2 есть ли способ создать настраиваемое поле идентификации с автоматическим увеличением без использования IDENTITY (1,1)? - PullRequest
0 голосов
/ 05 мая 2020

Я хотел бы иметь возможность извлекать значение настраиваемого ключа из таблицы, но также хотел бы, чтобы он работал как SQL столбец IDENTITY(1,1) сервера при вставках.

Пользовательский ключ предназначен для другого приложение и должно будет использоваться различными функциями, поэтому значение нужно будет извлечь из таблицы и сделать доступным для других областей.

Вот некоторые из моих попыток:

  1. Пробовал триггер в таблице хорошо работает при одиночных вставках, не работает при использовании 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;
Подумал о скалярной функции, но функции не могут выполнять c хранимые процедуры или операторы обновления, чтобы установить новое значение ключа в таблице поиска.

Спасибо

1 Ответ

0 голосов
/ 05 мая 2020

Вы можете использовать ROW_NUMBER() в зависимости от типа параллелизма, с которым вы имеете дело. Вот несколько примеров данных и демонстрация, которые вы можете запустить локально.

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

Каждый раз, когда я запускаю: EXEC dbo.InsertProc 1;, он возвращает еще 3 строки с правильным идентификатором col. Каждый раз, когда я его выполняю, он добавляет больше строк и при необходимости автоматически увеличивается.

SomeId   Col1
-------- ------
1        62
2        73
3        -17
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...