Простая хранимая процедура и простой вызов в SQL Server 2014:
CREATE TABLE [dbo].[SEQUENCES]
(
[SEQ_NAME] [nvarchar](50) NOT NULL,
[SEQ_NEXT_ID] [numeric](11, 0) NOT NULL,
[SEQ_INCREMENT] [numeric](2, 0) NOT NULL,
CONSTRAINT [SEQ_PK]
PRIMARY KEY CLUSTERED ([SEQ_NAME] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE PROCEDURE [dbo].[SomeStoredProcedure]
@SequenceName [NVARCHAR](MAX),
@Increment [INT]
AS
BEGIN
UPDATE [dbo].[SEQUENCES]
SET SEQ_NEXT_ID = SEQ_NEXT_ID + @Increment
OUTPUT deleted.SEQ_NEXT_ID
WHERE SEQ_NAME = @SequenceName
END
BEGIN
DECLARE @value NUMERIC(11,0);
EXEC @value = SomeStoredProcedure 'FOO', 1; -- 'FOO' already exists in SEQUENCES so we do get a value
-- weird results this always prints 0 if we uncomment the return
-- statement right below then and only then the correct value is printed
PRINT @value;
-- RETURN;
INSERT INTO SOME_TABLE (ID, NAME)
VALUES (@value, -- @value is always zero so we get a PK constraint violation ...
'Something');
END
Значение, которое получает @value
, всегда равно нулю, и из-за этого мы получаем нарушение ограничения PK в операторе обновления:
Сообщение 2627, Уровень 14, Состояние 1, Линия ...
Нарушение ограничения PRIMARY KEY 'PK'. Невозможно вставить повторяющийся ключ в объект 'dbo.SOME_TABLE'. Значение дубликата ключа (0).
Если мы раскомментируем оператор return в середине блока, то и только тогда оператор PRINT выводит правильное значение. Должно быть, упущено что-то действительно очевидное, но что?