在单个存储过程中插入和更新不起作用

时间:2014-08-31 11:29:04

标签: sql sql-server sql-update sql-insert

当用户更新他的个人资料图片时,我想将其插入表格并仅更新另一个表格中的两列。它只适用于一个条目并停止更新第二个表..不知道错误是什么

ALTER PROCEDURE [dbo].[UploadProfilePic]
     (@UserName Nvarchar(50),
      @ImageName Nvarchar(max),
      @OrgImageName Nvarchar(max),
      @CommentImage Nvarchar(max))
AS 
BEGIN
    IF NOT EXISTS (SELECT Username FROM ProfilePic WHERE UserName = @UserName)
    Begin
          insert into ProfilePic ([UserName], [ImageName], [OrgImageName], [IsActive], [CommentImage])
          values(@UserName, @ImageName, @OrgImageName, 'Y', @CommentImage)

          Update UserProfile 
          set ProfileImg = @ImageName,
              PostImage = @CommentImage
          where UserName = @UserName
    END
    ELSE
    BEGIN
       UPDATE ProfilePic 
       SET IsActive = 'N' 
       WHERE UserName = @UserName

       INSERT INTO ProfilePic ([UserName], [ImageName], [OrgImageName], [IsActive],[CommentImage])
       VALUES(@UserName, @ImageName, @OrgImageName, 'Y', @CommentImage)
   END
END

2 个答案:

答案 0 :(得分:0)

<强>更新

我创造了一个小提琴,请检查一下:

http://sqlfiddle.com/#!3/73aff0/6

我认为问题在于您错过了在其他情况下添加更新语句,因此对于新用户而言,它一直在工作 - 但不适用于已存在的用户。

    BEGIN
      IF NOT EXISTS (SELECT Username FROM ProfilePic WHERE UserName = @UserName)
        BEGIN
          INSERT INTO ProfilePic ([UserName], [ImageName], [OrgImageName], [IsActive],     [CommentImage])
          VALUES (@UserName, @ImageName, @OrgImageName, 'Y', @CommentImage)

          UPDATE UserProfile 
          SET ProfileImg = @ImageName,
              PostImage = @CommentImage
          WHERE UserName = @UserName
        END
    ELSE
        BEGIN
           UPDATE ProfilePic 
           SET IsActive = 'N' 
           WHERE UserName = @UserName

           INSERT INTO ProfilePic ([UserName], [ImageName], [OrgImageName], [IsActive],    [CommentImage])
           VALUES(@UserName, @ImageName, @OrgImageName, 'Y', @CommentImage)

           UPDATE UserProfile 
           SET ProfileImg = @ImageName,
               PostImage = @CommentImage
           WHERE UserName = @UserName
       END
    END

答案 1 :(得分:0)

你的问题实际上提出了一个非常有趣和非常普遍的情况。以下是使用merge来解决此方案的一种技术。由于我已经修改了模式并且移动了一些内容,这并不是完全准确的要求,但它是如何解决这种情况的一个很好的例子。

--
-------------------------------------------------
if schema_id(N'profile') is null
  execute (N'create schema profile');
go
if object_id(N'[profile].[picture]', N'U') is not null
  drop table [profile].[picture];
go
if object_id(N'[profile].[user]', N'U') is not null
  drop table [profile].[user];
go
create table [profile].[user]
  (
     [id]          [int] not null identity(1, 1) constraint [profile.user.id.clustered_primary_key] primary key clustered
     , [user_name] [sysname]
  );
go
create table [profile].[picture]
  (
     [id]              [int] not null identity(1, 1) constraint [profile.picture.id.clustered_primary_key] primary key clustered
     , [image_name]    [sysname]
     , [image_comment] [nvarchar](max)
     , [is_active]     [bit]
     , [user]          [int] constraint [profile.picture.user] references [profile].[user] ([id])
  );
go
--
if object_id(N'[profile].[set_picture]', N'P') is not null
  drop procedure [profile].[set_picture];
go
create procedure [profile].[set_picture]
  @user_id         [int]
  , @image_name    [nvarchar](max)
  , @image_comment [nvarchar](max)
as
  begin
      declare @output table
        (
           [action] [sysname]
           , [id]   [int]
        );
      --
      merge into [profile].[picture] as target
      using (values(@user_id
            , @image_name
            , @image_comment)) as source ([user], [image_name], [image_comment])
      on source.[user] = target.[user]
         and source.[image_name] = target.[image_name]
      when matched then
        update set target.[is_active] = 1
                   , target.[image_name] = source.[image_name]
                   , target.[image_comment] = source.[image_comment]
      when not matched by target then
        insert ([user]
                , [image_name]
                , [image_comment]
                , [is_active])
        values ([user]
                , [image_name]
                , [image_comment]
                , 0)
      output $action
             , coalesce(inserted.[id], deleted.[id])
      into @output([action], [id]);
  end;
go
--
-- note that you cannot insert a picture for a user that doesn't exist
-------------------------------------------------
insert into [profile].[user]
            ([user_name])
     values (N'sally'),
            (N'kevin');
go
select *
  from [profile].[user];
--
-- and the first insert gets an [is_active] value of 0
-- so you set it a second time to activate it
-------------------------------------------------
execute [profile].[set_picture]
  @user_id         =1
  , @image_name    =N'at the park'
  , @image_comment =N'she looks good in that dress';
go
execute [profile].[set_picture]
  @user_id         =1
  , @image_name    =N'at church'
  , @image_comment =N'but I like the blue dress better';
go
--
-------------------------------------------------
execute [profile].[set_picture]
  @user_id         =2
  , @image_name    =N'at work'
  , @image_comment =N'nice smile';
go
execute [profile].[set_picture]
  @user_id         =2
  , @image_name    =N'at work'
  , @image_comment =N'nice smile';
go
--
-------------------------------------------------
select *
  from [profile].[picture];
go
--