#sql #sql-server #tsql #stored-procedures
Вопрос:
select @@Version
ВОЗВРАТ
Microsoft SQL Server 2019 (RTM-CU11) (KB5003249) - 15.0.4138.2 (X64)
May 27 2021 17:34:14
Copyright (C) 2019 Microsoft Corporation
Express Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
Я занимаюсь реинжинирингом приложения здесь, первоначальный разработчик умер (RIP).
Я просто пытаюсь добавить нового пользователя в базу данных. Из того, что я могу сказать, система выполняет хранимую процедуру RS_GetIDValue
, а затем использует ее для UserID
rsUser
таблицы вместо использования вставки идентификатора. Я могу ошибаться, но это то, что я вижу.
Хранимая процедура ожидает, что в нее будет передано имя таблицы, но я не совсем понимаю, какие значения она ожидает для других параметров. Например @entity_id
, откуда я могу получить это значение? То же самое для @NextID
или NextID
для вывода, который будет генерироваться хранимой процедурой? Если это так, то я бы использовал это значение для нового UserID
при вставке нового пользователя.
USE [obscure_database_name]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[RS_GetIDValue]
@table_nm varchar(75),
@entity_id int,
@NextID INT OUTPUT
AS
BEGIN
SET @NextID = NULL
IF @entity_id IS NOT NULL
BEGIN
SET @NextID = (SELECT id_num
FROM IDValue
WHERE table_nm = @table_nm
AND entity_id = @entity_id);
UPDATE IDValue
SET id_num = ISNULL(@NextID 1, 1)
WHERE table_nm = @table_nm
AND entity_id = @entity_id;
END
ELSE
BEGIN
SET @NextID = (SELECT id_num
FROM IDValue
WHERE table_nm = @table_nm
AND entity_id IS NULL);
UPDATE IDValue
SET id_num = ISNULL(@NextID 1, 1)
WHERE table_nm = @table_nm
AND entity_id IS NULL;
END
END
GO
Я считаю, что мне нужно выполнить
EXEC RS_GetIDValue @table_nm = 'dbo.rsUser', @entity_id = XXXX, @NextID = YYYY;
но я не знаю, чего ожидает хранимая процедура для XXXX и ГГГГ.
Какие-нибудь советы?
ОБНОВЛЕНИЕ В ответ на некоторые комментарии я не знал первоначального разработчика, и в идеальном мире были бы комментарии и/или документация. Я уверен, что первоначальный разработчик предполагал, что он займется созданием документации, и не думал, что умрет от COVID, но я отвлекся.
В настоящее время это очень старое настольное приложение, которое мы пытаемся определить, сможем ли мы воспроизвести его, сделав его веб — (облачным). Мы пытаемся убедиться, что полностью понимаем, что делает текущий код. Этот метод создания идентификаторов просто кажется мне странным, и это не то, что я видел раньше, но я снова отвлекся. Если мы продолжим рефакторинг этого, будет использоваться идентификатор вставки. Я ненавижу иметь дело с триггерами и искать такие таблицы, как эта. Я знаю, что они служат определенной цели, но для тех веб-приложений, которые я создаю, вставки идентификаторов подходят. /мыльница
ОКОНЧАТЕЛЬНОЕ ОБНОВЛЕНИЕ После еще более глубокого погружения, эта таблица пользователей RS не зависит от этого SP, мы определили случай, если/тогда в другом месте исходного кода, в котором добавление новых пользователей отличается, и этот SP действительно имеет смысл.
Спасибо всем вам за помощь. Мы все думали, что делаем здесь что-то безумное, но оказалось, что мы делали это намного сложнее, чем это было на самом деле.
За Девона, РИП. Очень жаль, что вы не приняли вакцинацию или не надели маску, потому что у меня есть другие вопросы о вашем дизайне. О, и твоя семья скучает по тебе. :/
Комментарии:
1. Разрывы строк и пробелы — это волшебная вещь. Определение вашей процедуры невозможно легко прочитать из-за отсутствия ни того, ни другого.
2. Что касается ожидаемых значений, то для этого и предназначена документация; мы не знаем вашу базу данных, поэтому понятия не имеем, какие значения имеют данные.
3. Спасибо за исправление форматирования. Я просто заметил, что он был выключен после публикации. Что касается комментария к документации, вы просто указываете, что это означает, что эти значения будут получены из базы данных или они предоставлены пользователем/запросом?
4. Теперь мы видим определение, в нем есть проблемы. Например, вы получаете значение следующего идентификатора, получая текущий максимум из таблицы и добавляя его. Поскольку вы не блокируете таблицу, вы можете легко столкнуться с условиями гонки и дублированием значений. Он также будет повторно использовать значения в случае неудачных вставок. Почему вы не используете a
SEQUENCE
или anIDENTITY
?5. Лично я бы удалил эту дурацкую процедуру и использовал
IDENTITY
колонку, как и положено. По крайней мере, используйте транзакцию, вы можете даже сделать это одним операторомUPDATE IDValue SET id_num = ISNULL(id_num 1, 1), @NextID = id_num WHERE table_nm = @table_nm
. Да@NextID
-это результат. Я отмечаю, что@table_nm
, вероятно, должно бытьsysname
илиnvarchar(128)