Удалить запрос, не работающий в хранимой процедуре

avatar
negin motalebi
9 августа 2021 в 07:15
242
2
0

У меня есть хранимая процедура на сервере sql, которая на первом этапе вставляет некоторые данные из одной таблицы в другую, а затем удаляет данные, вставленные во вторую таблицу, из первой таблицы; Возможно, это сложное описание, поэтому давайте посмотрим код:

ALTER PROCEDURE [dbo].[SP_Insert_NotificationUserBulk]
AS
BEGIN
  SET NOCOUNT ON;
  INSERT INTO [dbo].[NotificationUserBulk]
       ([NotificationId]
       ,[UserId]
       ,[IsNotify]
       ,[IsShow]
       ,[NotifyMethod]
       ,[NotifyDateTime]
       ,[ShowDateTime]
       ,[IsDeleted]
       ,[CreatedDate]
       ,[ModifiedDate])
 
 (SELECT 
UserId,
NotificationId,
IsNotify,
IsShow,
NotifyMethod,
NotifyDateTime,
ShowDateTime,
IsDeleted,
CreatedDate,ModifiedDate
FROM NotificationUsers WHERE IsShow=1 OR IsDeleted=1)

DELETE FROM dbo.NotificationUsers WHERE IsShow=1 OR IsDeleted=1
   RETURN
END

Операция вставки выполняется успешно, проблем нет, но инструкция удаления не работает и ничего не происходит. Так в чем проблема и как ее исправить?

Источник
negin motalebi
9 августа 2021 в 07:20
0

Это моя вина, и я исправляю это. Спасибо, но это не связано с этим, и оно успешно выполняется вне хранимой процедуры.

Stu
9 августа 2021 в 07:42
1

Не принимая во внимание, почему ваше удаление не работает - они должны быть согласованы с транзакциями и должны находиться в пределах begin/end transaction. Вы также можете сделать это в одном выражении, используя output. Кроме того, будьте последовательны в своем префиксе схемы - либо используйте последовательно dbo, либо нет, иначе вы рискуете двусмысленностью.

AlwaysLearning
9 августа 2021 в 08:01
1

Существует также вариант одного оператора, поскольку SQL Server поддерживает delete TableA output ... into TableB.

negin motalebi
9 августа 2021 в 12:56
0

@AlwaysLearning Спасибо, сработало!

Ответы (2)

avatar
SteveC
9 августа 2021 в 11:32
1

Если это одноразовый или специальный запрос, вы можете попробовать что-то вроде этого. Если это oltp, вы можете добавить TRY/CATCH и вернуть переменную успеха/неудачи.

В явной транзакции с XACT_ABORT ON запрос вставляет в таблицу NotificationUsers, выводит (вставленный) NotificationId во временную таблицу и удаляет из NotificationUsers на основе INNER JOIN с временной таблицей.

ALTER PROCEDURE [dbo].[SP_Insert_NotificationUserBulk]
AS
SET NOCOUNT ON;
SET xact_abort on;

begin transaction 
    declare @NotificationId             table(NotificationId        int primary key);

    INSERT INTO [dbo].[NotificationUserBulk]
           ([NotificationId]
           ,[UserId]
           ,[IsNotify]
           ,[IsShow]
           ,[NotifyMethod]
           ,[NotifyDateTime]
           ,[ShowDateTime]
           ,[IsDeleted]
           ,[CreatedDate]
           ,[ModifiedDate])
    output inserted.NotificationId into @NotificationId 
    SELECT UserId, NotificationId, IsNotify, IsShow, NotifyMethod,
           NotifyDateTime, ShowDateTime, IsDeleted, CreatedDate, 
           ModifiedDate
    FROM NotificationUsers
    WHERE IsShow=1 
          OR IsDeleted=1;

    DELETE nu
    from dbo.NotificationUsers nu
         join @NotificationId n on nu.NotificationId=n.NotificationId;
commit
go
negin motalebi
9 августа 2021 в 12:58
1

Я сделал что-то подобное, и теперь sp успешно выполняется.

avatar
Vijay Raval
9 августа 2021 в 11:17
0

пожалуйста, не используйте RETURN после запроса DELETE, попробуйте простой запрос

DELETE FROM dbo.NotificationUsers WHERE IsShow=1 OR IsDeleted=1
negin motalebi
9 августа 2021 в 12:56
0

Спасибо за отзыв, но это не решение