#sql #sql-server
#sql #sql-сервер
Вопрос:
Я пытаюсь написать хранимую процедуру, которая создает новую строку данных в моей таблице, содержащую Identity
столбец. Я не могу понять, что я делаю не так, чтобы заставить его хранить мои данные в таблице.
Вот моя таблица
CREATE TABLE [Promotional].[Proposals]
(
[Proposal_Uid] [int] IDENTITY(1,1) NOT NULL,
[Prime_Contract] [nvarchar](30) NULL,
[Sub_Contract] [nvarchar](30) NULL,
[Po_Id] [nvarchar](30) NULL,
[Proposal_Title] [nvarchar](50) NULL,
[Client_Name] [nvarchar](40) NULL,
[Client_Code] [nvarchar](20) NULL,
[Total_Proposal_Amount] [decimal](18, 2) NULL,
[ODC_Amount] [decimal](18, 2) NULL,
[Manager_Name] [nvarchar](30) NULL,
[Admin] [nvarchar](30) NULL,
[Due_Date] [date] NULL,
[Start_Date] [date] NULL,
[End_Date] [date] NULL,
[Proposal_Number] [nvarchar](20) NULL,
[Contract_Type] [nvarchar](16) NULL,
CONSTRAINT [Proposal_Uid]
PRIMARY KEY CLUSTERED ([Proposal_Uid] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Вот моя хранимая процедура:
ALTER PROCEDURE [Promotional].[Proposals_Create]
(@Prime_Contract nvarchar(30),
@Sub_Contract nvarchar(30),
@Po_Id nvarchar(30),
@Proposal_Title nvarchar(50),
@Client_Name nvarchar(40),
@Client_Code nvarchar(20),
@Total_Proposal_Amount decimal(18,2),
@ODC_Amount decimal(18,2),
@Manager_Name nvarchar(30),
@Admin nvarchar(30),
@Due_Date date,
@Start_Date date,
@End_Date date,
@Proposal_Number nvarchar(20),
@Contract_Type nvarchar(16),
@NewId int output)
AS
BEGIN
IF @NewId IS NULL
BEGIN
INSERT INTO Promotional.Proposals (Prime_Contract, Sub_Contract, Po_Id, Proposal_Title, Client_Name, Client_Code,
Total_Proposal_Amount, ODC_Amount, Manager_Name, Admin, Due_Date, Start_Date, End_Date, Proposal_Number, Contract_Type)
VALUES (@Prime_Contract, @Sub_Contract, @Po_Id, @Proposal_Number, @Client_Name, @Client_Code,
@Total_Proposal_Amount, @ODC_Amount, @Manager_Name, @Admin, @Due_Date, @Start_Date, @End_Date,
@Proposal_Number, @Contract_Type)
SET @NewId = SCOPE_IDENTITY()
END
RETURN @NewId
END
GO
Я знаю, что это что-то маленькое, что я пропустил. Но мой РЕЗУЛЬТАТ заключается в том, что при запуске процедуры она вставляет значения в правильные столбцы, а первичный ключ обновляется автоматически без необходимости вставлять собственное значение в инструкцию. Мое выполнение инструкции будет следующим
EXEC Promotional.Proposals_Create 'hj','fd','fd','fd','fd','fd','0.23','1.24','fd','fd','2020/08/30','2020/08/30','2020/08/30','fd','fd';
И я получаю эту ошибку:
Сообщение 201, уровень 16, состояние 4, процедура рекламная.Proposals_Create, строка 0 [Строка запуска пакета 0]
Процедура или функция ‘Proposals_Create’ ожидает параметр ‘@NewId’, который не был указан.
Мне не нужно указывать этот параметр, потому что он должен автоматически обновляться с помощью моего PK, который есть Proposal_Uid
. Или я должен сделать свое Proposal_Uid
значение, возвращаемое из ScopeIdentity
?
Комментарии:
1. У вас есть вопрос?
2. привет @GordonLinoff да, я пытаюсь создать хранимую процедуру, которая создает новую строку данных в моей таблице, содержащую столбец идентификаторов. Я не могу понять, что я делаю не так, чтобы заставить его хранить мои данные в таблице. Он принимает сохраненную обработку, но не позволяет мне вставлять значения. Выдает ошибку.
3. Затем, пожалуйста, скопируйте и вставьте указанную ошибку в свой вопрос…
4. @Sander обновлен.
5. Итак… Ваша ошибка сообщает вам, что у вас не хватает одного входного параметра. Если бы вы использовали именованные входные параметры, подобные
EXEC Promotional.Proposals_Create @Prime_Contract='hj', @Sub_Contract='fd', ...
этому, было бы очень ясно.
Ответ №1:
@NewID
не должен быть параметром процедуры, поскольку это IDENTITY
столбец.
Комментарии:
1. Ваш пост привел меня к моему ответу. Я вынул @newId везде, где он упоминался, и просто оставил Insert В code и Values code. Это было так, и это сработало. Спасибо. Автоматическое увеличение и все такое.
Ответ №2:
Вы можете заставить хранимую процедуру возвращать сгенерированный идентификатор, предоставив выходную переменную для хранения ее содержимого. Это поведение также задокументировано здесь .
declare @test int;
EXEC Proposals_Create 'hj','fd','fd','fd','fd','fd','0.23','1.24','fd','fd',
'2020/08/30','2020/08/30','2020/08/30','fd','fd', @test OUTPUT;
select @test as 'new_identity';
set @test = null; -- because of the IF statement in your procedure...
EXEC Proposals_Create 'hj','fd','fd','fd','fd','fd','0.23','1.24','fd','fd',
'2020/08/30','2020/08/30','2020/08/30','fd','fd', @test OUTPUT;
select @test as 'new_identity';
Выбирает возврат 1
и 2
соответственно.
Скрипка (примечание: имя схемы удалено в коде выше и в скрипке).
Комментарии:
1. да, я видел. У меня было неправильное объяснение идентификатора области видимости и того, что он делал при вводе в процедуру. У меня сложилось впечатление, что
ScopeIdentity
он напрямую связан с моим ПК, который также является моей личностью, и должен быть включен в процедуру для автоматического увеличения и проверки. Мне была предоставлена неверная информация, и я не проверял факты, как следовало. Я просто удалил все, что с этим связано, и оставил вставку в и значения. Это сработало как шарм с моей строкой хранимой процедуры exec. Моя ошибка в том, что я опубликовал неверную мысль о ScopeIdentity.