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

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