xhon Ответов: 1

Хранимые процедуры: многосоставный идентификатор не может быть привязан


Я хочу создать хранимую процедуру для вставки или удаления фильма в/из таблицы фильмов.
Входные параметры-название и режиссер фильма.
Если фильм не существует, он будет создан, в противном случае я увеличу количество копий (фильм имеет атрибут INT 'numberOfCopies', чтобы сохранить его след).
Если я не могу удалить его, вся операция должна быть отменена.
Я написал следующий пакетный код, но когда я его запускаю, я получаю следующую ошибку для каждого столбца:

the multi-part identifier Movies.NameOfColumn could not be bound


А также Вот этот:

Invalid column name 'SCOPE:IDENTITY'


Что я уже пробовал:

CREATE PROCEDURE up_Movie_StoredProcedure 
@Title NVARCHAR(300),
@Director NVARCHAR(50)
@NumberOfCopies INT OUTPUT         -- parameters 
AS
-- Insert -->
IF  (
     Movie.Title != @Title
     AND Movie.Director != @Director
     	 )
    BEGIN  -- code block runs if condition is true
    INSERT INTO Movies(Title, Director)
	       VALUES (@Title, @Director );
		   SELECT SCOPE_IDENTITY;
    END 
ELSE
   BEGIN 
   UPDATE Movies
   SET Title = @Title,
       Director = @Director
       NumberOfCopies = NumberOfCopies + 1   -- output number of copies
   WHERE Title = @Title 
   OR   Director = @Director
   END
BEGIN
     SET @NumberOfCopies = (SELECT NumberOfCopies FROM Movies WHERE Title = @Title AND Dirctor = @Director);
   END

-- delete -->
BEGIN TRY
   BEGIN TRANSACTION
       DELETE 
	   FROM Movies
	   WHERE Title = @Title 
	     AND Director = @Director;
        DELETE r
		FROM Reservations r
		INNER JOIN Movies m ON m.IDMOvies = r.IDMovies
		WHERE m.Title = @Title
	      AND m.Director = @Director;
  COMMIT Transaction
END TRY
BEGIN CATCH
   ROLLBACK Transaction
END CATCH

Gerry Schmitz

Выберите count(*) для названия и директора. Если счетчик равен 0, вы "вставляете" (в зависимости от ваших спецификаций).

Richard Deeming

Пожалуйста, прекратите использовать этот анти-паттерн UPSERT - SQLPerformance.com[^]

Запустите программу UPDATE первый. Если ни одна строка не была затронута, запустите INSERT.

1 Ответов

Рейтинг:
12

Richard Deeming

В этой процедуре нет ничего, что указывало бы, Хотите ли вы вставить/обновить фильм или удалить его.

У вас должно быть две разные процедуры - одна для вставки или обновления:

CREATE PROCEDURE AddMovie
(
    @Title NVARCHAR(10), 
    @Director NVARCHAR(10)
)
As
BEGIN
    SET NOCOUNT ON;
    
    UPDATE
        Movies
    SET
        NumberOfCopies = NumberOfCopies + 1
    WHERE
        Title = @Title
    And
        Director = @Director
    ;
    
    If @@ROWCOUNT = 0
    BEGIN
        INSERT INTO Movies
        (
            Title,
            Director,
            NumberOfCopies
        )
        VALUES
        (
            @Title,
            @Director,
            1
        );
    END;
    
    SELECT
        NumberOfCopies
    FROM
        Movies
    WHERE
        Title = @Title
    And
        Director = @Director
    ;
END
и один для удаления:
CREATE PROCEDURE RemoveMovie
(
    @Title NVARCHAR(10), 
    @Director NVARCHAR(10)
)
As
BEGIN
    SET NOCOUNT ON;
    
    BEGIN TRY;
    BEGIN TRANSACTION;
        
        DELETE
        FROM R
        FROM Reservations As R
        INNER JOIN Movies As M ON M.IDMovie = R.IDMovie
        WHERE M.Title = @Title
        And M.Director = @Director;
        
        DELETE
        FROM Movies
        WHERE Title = @Title
        And Director = @Director;
        
        COMMIT;
    END TRY
    BEGIN CATCH;
        IF @@TRANCOUNT > 0 ROLLBACK;
        THROW;
    END CATCH;
END    


Richard Deeming

Затем сделайте это и проверьте параметр в хранимой процедуре.