После удаления вставить значение в SQL Server

#sql-server #sql-server-2005

#sql-сервер #sql-server-2005

Вопрос:

sp:

 CREATE PROC [dbo].[Usp_MenuMgrAddUpdMenupermission] 
@MenuID       INT,
@PermissionID INT,
@PortalID     INT,
@Username nvarchar(256)
AS
  BEGIN
      IF EXISTS(DELETE [dbo].[PagePermission]
                    WHERE [PortalID] = @PortalID AND
                          [MenuID] = @MenuID)

     INSERT INTO [dbo].[MenuPermission]
                    (MenuID,
                     PermissionID,
                     AddedOn,
                     Username)

        VALUES     (@MenuID,
                    @PermissionID,
                    Getdate(),
                    @UserName)
  END 
  

Но я получил синтаксическую ошибку. Пожалуйста, предложите правильный способ сделать это.

Ответ №1:

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

 DELETE [dbo].[PagePermission]
    OUTPUT @MenuID,@PermissionID,Getdate(),@UserName
        INTO [dbo].[MenuPermission]
    WHERE [PortalID] = @PortalID AND [MenuID] = @MenuID
  

рабочий пример:

 DECLARE @PagePermission TABLE (PortalID int, MenuID int)
INSERT INTO @PagePermission VALUES (1,1)
INSERT INTO @PagePermission VALUES (2,1)
INSERT INTO @PagePermission VALUES (3,2)
INSERT INTO @PagePermission VALUES (4,2)

DECLARE @MenuPermission TABLE (MenuID int, PermissionID int,YourDate datetime, UserName varchar(10))

DECLARE @MenuID        int
       ,@PermissionID  int
       ,@UserName      varchar(10)
      ,@PortalID       int

SELECT @MenuID        =1
      ,@PermissionID  =100
      ,@UserName      ='xyz'
      ,@PortalID      =2

DELETE @PagePermission
    OUTPUT @MenuID,@PermissionID,Getdate(),@UserName
        INTO @MenuPermission
    WHERE PortalID = @PortalID AND MenuID = @MenuID

select * from @PagePermission

select * from @MenuPermission
  

ВЫВОД:

 PortalID    MenuID
----------- -----------
1           1
3           2
4           2

(3 row(s) affected)

MenuID      PermissionID YourDate                UserName
----------- ------------ ----------------------- ----------
1           100          2011-11-09 09:18:52.693 xyz

(1 row(s) affected)
  

Ответ №2:

Вот как я бы это сделал (отредактировано с учетом новых требований):

  IF EXISTS(SELECT TOP 1 1 FROM [dbo].[PagePermission]
           WHERE [PortalID] = @PortalID AND [MenuID] = @MenuID)
 BEGIN

   BEGIN TRANSACTION

   DELETE [dbo].[PagePermission]
   WHERE [PortalID] = @PortalID AND [MenuID] = @MenuID

   INSERT INTO [dbo].[MenuPermission]
           (MenuID, PermissionID, AddedOn, Username)
    VALUES (@MenuID, @PermissionID, Getdate(), @UserName)

   COMMIT TRANSACTION

END
ELSE
BEGIN
   INSERT INTO [dbo].[MenuPermission]
           (MenuID, PermissionID, AddedOn, Username)
    VALUES (@MenuID, @PermissionID, Getdate(), @UserName)
END
  

Комментарии:

1. @Hagon если одновременно не существует запроса на удаление, тоже срабатывает?

2. @ShreeKhanal Нет, удаление выполняется в инструкции if и после начала транзакции.

3. это не работает. Его единственное удаление n обновляет существующий идентификатор меню, который я передаю. Я хочу, чтобы, если указан новый идентификатор меню, тогда вместо запроса на удаление вставьте запрос fire. В любом случае, спасибо.

4. ваше приветствие, спасибо в любом случае, у вас нет в исходном вопросе позже

Ответ №3:

Используйте @@ROWCOUNT переменную:

 DELETE [dbo].[PagePermission] WHERE [PortalID] = @PortalID AND [MenuID] = @MenuID

IF @@ROWCOUNT > 0
    INSERT INTO [dbo].[MenuPermission] ...
  

Комментарии:

1. я не понимаю.пожалуйста, объясните. Я не должен хотеть, чтобы запрос на удаление запускался, когда условие не соответствует.

2. Что делает этот код: 1. удалите строки 2. если какая-либо строка была удалена, затем выполните вставку. Если вы хотите что-то еще, пожалуйста, отредактируйте свой вопрос и добавьте больше деталей.

3. Удалите строку, если она существует. Если нет, то почему должен выполняться запрос на удаление? выполняется только запрос insert. Я путаю.

4. @ShreeKhanal: Вам нужно было бы сначала проверить, есть ли строки для удаления (выполнить их поиск), затем, если такие строки были, выполнить команду DELETE, которая, в свою очередь, должна была бы сначала выполнить поиск строк для удаления, как указано в ее WHERE предложении, затем выполнить фактическое удаление. Так зачем искать дважды? Просто выполните УДАЛЕНИЕ, как предлагает здесь Xavier, и если УДАЛЕНИЕ действительно приведет к удалению каких-либо строк, @@ROWCOUNT глобальной переменной будет присвоено ненулевое значение. На основе этого вы выдадите ВСТАВКУ. Таким образом, это дешевле, если я чего-то не упускаю в ваших требованиях.

5. @ShreeKhanal: … (кстати, вы не указали должным образом в своем вопросе ).