2014-08-31 23 views
0

當用戶更新他的個人資料圖片時,我想將其插入到表中並更新另一個表中的兩列。它工作正常,只是一個入口和停止更新第二個表..不知道什麼是我創建了一個小提琴錯誤在單個存儲過程中插入和更新不起作用

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 
+0

接着說:SQL-server'標籤和'爲nvarchar(最大)'數據類型 – 2014-08-31 11:33:26

回答

0

UPDATE

,檢查此請:

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

我認爲問題在於你錯過了在else情況下添加update語句,所以對於新用戶它一直在工作 - 但不是已經存在的那些用戶。

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 
+0

這是一個貧窮的方法,你都包裹在一個單獨的事務的其他部分,這整個語句'IF..ELSE'應該在一個事務中。此外,OP的方法很好,我認爲問題在於數據在某個地方。 – 2014-08-31 11:52:58

+0

@ M.Ali - 謝謝,請您用幾句話告訴我爲什麼這是一種糟糕的做法?它是否緩慢,重負荷? – 2014-08-31 11:56:03

+0

EXECUTE後的事務計數表示BEGIN和COMMIT語句的數量不匹配。以前的計數= 0,當前計數= 1 .....我在改變後得到這個錯誤 – kumar 2014-08-31 12:08:43

0

你的問題實際上帶來了一個非常有趣和非常常見的情況。這是一種使用合併來解決這種情況的技術。這並不完全正是我所要求的,因爲我已經修改了模式並移除了一些內容,但這是如何解決這種情況的一個很好的例子。因爲`@`變量的

-- 
------------------------------------------------- 
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 
-- 
相關問題