Хранимая процедура SQL Server ожидает параметр, который не был указан - PullRequest
1 голос
/ 21 сентября 2019
CREATE TABLE [dbo].[review]
(
    [id] [int] IDENTITY(1,1) NOT NULL,
    [uID] [varchar](6) NOT NULL,
    [pID] [int] NOT NULL,
    [email] [nvarchar](255) NOT NULL,
    [review] [nvarchar](3000) NULL,
    [refURL] [nvarchar](2083) NOT NULL,
    [refID] [nvarchar](100) NOT NULL,
    [cDate] [datetime] NOT NULL,

    CONSTRAINT [PK_review] 
        PRIMARY KEY CLUSTERED ([id] 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 TABLE [dbo].[review] 
    ADD CONSTRAINT [DF_review_uID] DEFAULT (LEFT(NEWID(), (6))) FOR [uID]
GO

ALTER TABLE [dbo].[review] 
    ADD CONSTRAINT [DF_review_cDate] DEFAULT (GETDATE()) FOR [cDate]
GO

Я написал эту хранимую процедуру:

ALTER PROCEDURE [dbo].[spReview] 
    @id INT = 0,
    @uID VARCHAR(6),
    @pID INT = 0,
    @email NVARCHAR(255),
    @review NVARCHAR(3000),
    @refURL NVARCHAR(2083),
    @refID NVARCHAR(100),
    @cDate DATETME = NULL,
    @OPERATION NVARCHAR(50) = ''
AS
    IF @OPERATION = 'Insert'
    BEGIN
        DECLARE @inserted TABLE ([uID] VARCHAR(6));

        INSERT INTO review ([pID], [email], [review], [refURL], [refID])
        OUTPUT INSERTED.[uID] INTO @inserted
        VALUES (@pID, @email, @review, @refURL, @refID)

        SELECT *
        FROM @inserted
    END
    ELSE IF @OPERATION = 'Delete'
    BEGIN
        DELETE FROM review
        WHERE id = @id
    END
    ELSE IF @OPERATION = 'Update'
    BEGIN
        UPDATE review
        SET pID = @pID,
            email = @email,
            review = @review,
            refURL = @refURL,
            refID = @refID
        WHERE id = @id
  END

uID: left (newid (), (6)) и cDate: getdate () установить значение по умолчанию

DECLARE @return_value int

EXEC    @return_value = [dbo].[spReview]
        @id = N'29',
        @OPERATION = N'Delete'

SELECT  'Return Value' = @return_value

GO

Я получаю эту ошибку при выполнении запроса на удаление:

Процедура или функция 'spReview' ожидает параметр '@uID', который не был предоставлен

Я попытался отладитьЯ не могу понять, где я допустил ошибку.Где я допустил ошибку?


ELSE IF @OPERATION = 'Delete'
    BEGIN
        DELETE FROM review
        WHERE id = @id
END

Просто ожидание параметра '@id', для него не нужно '@ uID'

Ответы [ 5 ]

2 голосов
/ 21 сентября 2019

Как уже упоминалось, несколько раз, это должно быть 3 отдельных SP, поэтому вам нужны только параметры, необходимые для этой операции:

CREATE PROC dbo.Review_Delete @id int AS
BEGIN 

    DELETE FROM dbo.review
    WHERE id = @id;
END;
GO

CREATE PROC dbo.Review_Insert @pID int, @email nvarchar(255), @review nvarchar(3000), @RefURL nvarchar(2083), @RefID nvarchar(100) AS
BEGIN

    INSERT INTO dbo.review(pID, email, review, refURL, refID)
    OUTPUT inserted.uID --This seems like an OUTPUT parameter might be better, as you insert a single row
    VALUES(@pID, @Email, @review, @RefURL, @RefID);
END;
GO

CREATE PROC dbo.Review_Update @id int, @pID int, @email nvarchar(255), @review nvarchar(3000), @RefURL nvarchar(2083), @RefID nvarchar(100) AS
BEGIN

    UPDATE dbo.review
    SET pID = @pID,
        email = @email,
        review = @review,
        refURL = @refURL,
        refID = @refID
    WHERE ID = @ID;
END;
GO

Обратите внимание, что я никогда не объявляю параметр @cDate, так как выне используйте его один раз в своем SP.

Если по какой-то действительно странной причине вам действительно нужен один SP, то создайте другие и вызывайте их динамически;только передавая параметры, которые вы передали в «мастер» ИП «детям».Я, однако, не рекомендую этот, и вы должны просто назвать их правильными в первую очередь:

CREATE PROC Review_Operation @Operation char(6), --No need for this to be an nvarchar, or 50 characters, delete, insert and update are all 6 characters in length and contain no unicode characters
                             @ID int = NULL, @pID int = NULL, @email nvarchar(255) = NULL, @review nvarchar(3000) = NULL, @RefURL nvarchar(2083) = NULL, @RefID nvarchar(100) = NULL AS
BEGIN

    --Because they are all NULL we're going to use Dynamic SQKL to only pass parameters will a value to force the error
    DECLARE @SQL nvarchar(MAX),
            @Params nvarchar(MAX);

    IF @Operation = 'Delete' BEGIN

        SET @SQL = N'EXEC Review_Delete ' + CASE WHEN @ID IS NOT NULL THEN N'@id' ELSE N'' END + N';';
        SET @Params = N'@ID int';
        EXEC sp_executesql @SQL, @Params, @ID;

    END ELSE IF @Operation = 'Insert' BEGIN

        SET @SQL = N'EXEC Review_Insert ' + STUFF(CASE WHEN @pID IS NOT NULL THEN N',@pID = @pID' ELSE N'' END +
                                                  CASE WHEN @email IS NOT NULL THEN N',@email = @email' ELSE N'' END +
                                                  CASE WHEN @review IS NOT NULL THEN N',@review = @review' ELSE N'' END +
                                                  CASE WHEN @RefURL IS NOT NULL THEN N',@RefURL = @RefURL' ELSE N'' END +
                                                  CASE WHEN @RefID IS NOT NULL THEN N',@RefID = @RefID' ELSE N'' END,1,1,N'') + N';';
        SET @Params = N'@pID int, @email nvarchar(255), @review nvarchar(3000), @RefURL nvarchar(2083), @RefID nvarchar(100)';
        EXEC sp_executesql @SQL, @Params, @pID, @email, @review, @RefURL, @RefID;

    END ELSE IF @Operation = 'Update' BEGIN

        SET @SQL = N'EXEC Review_Update ' + STUFF(CASE WHEN @ID IS NOT NULL THEN N',@ID = @ID' ELSE N'' END +
                                                  CASE WHEN @pID IS NOT NULL THEN N',@pID = @pID' ELSE N'' END +
                                                  CASE WHEN @email IS NOT NULL THEN N',@email = @email' ELSE N'' END +
                                                  CASE WHEN @review IS NOT NULL THEN N',@review = @review' ELSE N'' END +
                                                  CASE WHEN @RefURL IS NOT NULL THEN N',@RefURL = @RefURL' ELSE N'' END +
                                                  CASE WHEN @RefID IS NOT NULL THEN N',@RefID = @RefID' ELSE N'' END,1,1,N'') + N';';
        SET @Params = N'@id int,@pID int, @email nvarchar(255), @review nvarchar(3000), @RefURL nvarchar(2083), @RefID nvarchar(100)';
        EXEC sp_executesql @SQL, @Params, @ID, @pID, @email, @review, @RefURL, @RefID;

    END;        

END;
GO
2 голосов
/ 21 сентября 2019

Это ваш код:

ALTER PROCEDURE [dbo].[spReview] 
    @id INT = 0,
    @uID VARCHAR(6),
    @pID INT = 0,
    @email NVARCHAR(255),
    @review NVARCHAR(3000),
    @refURL NVARCHAR(2083),
    @refID NVARCHAR(100),
    @cDate DATETME = NULL,
    @OPERATION NVARCHAR(50) = '' 

Для каждого параметра без знака "=" необходимо указать значение. В вашем случае это означает, что вам нужноукажите, по крайней мере, следующие параметры:

    @uID VARCHAR(6),
    @email NVARCHAR(255),
    @review NVARCHAR(3000),
    @refURL NVARCHAR(2083),
    @refID NVARCHAR(100),

Таким образом, либо вы предоставляете эти параметры при вызове процедуры, либо переписываете свою процедуру так, что вам не нужны эти параметры.

2 голосов
/ 21 сентября 2019

Процедура или функция «spReview» ожидает параметр «@uID», который не был предоставлен

Это означает, что вы не передаете значение @uID при вызове хранимой процедуры,Вам нужно передать действительный параметр во время выполнения SP.

1 голос
/ 21 сентября 2019

У вас есть несколько проблем с созданием и вызовом вашей процедуры.

Создание: Вы объявили параметр @uID VARCHAR (6), который не использовался в процедуре. Вы можете удалить строку @uID VARCHAR (6) из раздела определения параметров процедуры.

Вызов: определенный вами параметр - @email, @review, @refURL, @refID в процедуре, но не предоставляет значения для них при вызове процедуры.Вы должны вызвать процедуру, как показано ниже -

DECLARE @return_value int

EXEC    @return_value = [dbo].[spReview]
        @id = N'29',
        @email = N'abc@yahoo.com',
        @OPERATION = N'Delete',
        @email = 'test@yahoo.com', 
        @review = 'abc', 
        @refURL = 'xyz', 
        @refID = '1' -- ID should be a INT but declared as NVARCHAR

SELECT  'Return Value' = @return_value

GO
0 голосов
/ 21 сентября 2019

Хотя это и не рекомендуется, как указано выше, вы можете предоставить значения по умолчанию, и на самом деле у вас установлены значения по умолчанию для @id, @pID и @ OPERATION.

Конечно, если вы используете @uID по умолчаниючтобы обнулить, вы ДОЛЖНЫ учесть это в реальной процедуре, чтобы нулевой @uID не вызывал другие ошибки.

create proc [dbo].[spReview] 
    @id INT = 0,
    @uID VARCHAR(6) = null,
    @pID INT = 0,
    @email NVARCHAR(255),
    @review NVARCHAR(3000),
    @refURL NVARCHAR(2083),
    @refID NVARCHAR(100),
    @cDate DATETME = NULL,
    @OPERATION NVARCHAR(50) = ''
AS
if @uID is null
   begin
     -- do something here when @uID is null.
   end
...