SQL 存储过程无法更新数据,而其中的脚本手动运行

发布于 2024-09-02 06:31:00 字数 7761 浏览 3 评论 0原文

我有一个在作业中执行的 SQL 脚本,用于定期转换表。为了加快速度,我将该脚本放入存储过程中并通过作业执行它。它工作得更快。

当存储过程即使执行但仍无法工作时,有时会出现此问题。我手动使用该脚本并运行它,一切正常。

整个脚本位于一个事务内,我已经这样做了,这样如果出现一些错误,它就会被正确记录。但是该脚本没有给出任何错误。


BEGIN TRANSACTION
BEGIN TRY

-- Rounding off Campaign stats
update Campaigns
set ImpressionsBurned = ImpressionTarget
where ImpressionsBurned > ImpressionTarget and CampaignTypeID = 1

update Campaigns
set ClicksConsumed = ClickTarget
where ClicksConsumed = ClickTarget and CampaignTypeID = 2

-- Updating Campaigns & Banners
update banners
set banners.impressionsburned = 
    (select  sum(impressionsqueue.impressionsburned) from impressionsqueue where impressionsqueue.bannerid = banners.bannerid)
where exists (select impressionsqueue.bannerid from impressionsqueue where impressionsqueue.bannerid = banners.bannerid)

update Campaigns
set ImpressionsBurned = 
    (select isnull(SUM(ImpressionsQueue.ImpressionsBurned),0) from ImpressionsQueue 
    inner join Banners on Banners.BannerID = ImpressionsQueue.BannerID and CampaignID = Campaigns.CampaignID
    )
where 
    exists (
        (select ImpressionsQueue.BannerID from ImpressionsQueue 
        inner join Banners on Banners.BannerID = ImpressionsQueue.BannerID and CampaignID = Campaigns.CampaignID
        )
    )
    and 
    (
    ( Campaigns.ImpressionsBurned < Campaigns.ImpressionTarget and Campaigns.CampaignTypeID = 1)
    or ( Campaigns.ClicksConsumed < Campaigns.ClickTarget and Campaigns.CampaignTypeID = 2) 
    or Campaigns.CampaignTypeID = 3
    )
    and Campaigns.IsPaused = 0
    and Campaigns.StartsOn <= GetDate() and Campaigns.EndsOn >= GetDate()

-- Updating Paused Banners in the Queue
update ImpressionsQueue
set IsPaused = (
    select IsPaused from Banners where Banners.BannerID = ImpressionsQueue.BannerID
)
-- Updating the Navigation URLs
update ImpressionsQueue
set NavigateURL = (
    select NavigateURL from Banners where Banners.BannerID = ImpressionsQueue.BannerID
)

-- Removing any rows if the Weight of a banner is updated, 
-- the banner will be reinserted later with updated impressions
delete from ImpressionsQueue 
where BannerID in 
( 
    select ImpressionsQueue.BannerID from ImpressionsQueue 
    inner join Banners on Banners.BannerID = ImpressionsQueue.BannerID
    group by ImpressionsQueue.BannerID, Banners.Weight
    having Banners.Weight <> COUNT(ImpressionsQueue.BannerID)
)

-- Removing entries whose impressions count has reached its target 
delete from impressionsqueue where
BannerID in (
    select Banners.BannerID from impressionsqueue
    inner join Banners on banners.bannerid = impressionsqueue.bannerid
    inner join campaigns on campaigns.campaignid = banners.campaignid
    where Campaigns.CampaignTypeID = 1 
    -- excluding flat fee based campaign
    group by Campaigns.ImpressionTarget, Banners.BannerID
    having not (Campaigns.ImpressionTarget > sum(ImpressionsQueue.impressionsburned))
    -- inverse logic for campaign count
)
-- Removing entries whose campaign click count has reached
delete from impressionsqueue where
BannerID in (
    select Banners.BannerID from impressionsqueue
    inner join Banners on banners.bannerid = impressionsqueue.bannerid
    inner join campaigns on campaigns.campaignid = banners.campaignid and Campaigns.CampaignTypeID = 2 
        and Not (Campaigns.ClickTarget > Campaigns.ClicksConsumed)
    -- inverse logic for campaign count
)
-- Removing entries whose campaign has expired
delete from impressionsqueue where
BannerID in (
    select impressionqueueid from impressionsqueue
    inner join Banners on banners.bannerid = impressionsqueue.bannerid
    inner join campaigns on campaigns.campaignid = banners.campaignid
        and not (Campaigns.StartsOn <= GETDATE() and Campaigns.EndsOn >= GETDATE())
    -- inverse logic for date
)

----------------------------------------------------------------------------------------
-- Begin updating Impressions Queue
----------------------------------------------------------------------------------------


Declare @TempBanners Table(BcID [int] IDENTITY(1,1),ZoneID [int], BannerID [int], Weight [int], FileID [uniqueidentifier], IsPaused [bit], Impressions [int], URL [nvarchar](2048))

/*
Insert into the temp table all the banners that:
      1) Belong to an active campaign => c.StartsOn <= GetDate() and c.EndsOn >= GetDate()
      2) and Belong to a campaign that is not paused
      3) and The banner itself is not paused
      4) and Flat Fee campaign banner
*/
Insert Into @TempBanners (ZoneID, BannerID, Weight, FileID, IsPaused, Impressions, URL)
Select 
      bz.ZoneID, 
      b.BannerID, 
      b.Weight,
      b.FileID,
      b.IsPaused,
      b.ImpressionsBurned,
      b.NavigateURL
From Banners b
Join Bannerzones bz on b.BannerID = bz.BannerID
Join Campaigns c on b.CampaignID = c.CampaignID
And c.StartsOn <= GetDate() and c.EndsOn >= GetDate()
And c.IsPaused = 0
And b.IsPaused = 0
And (
            (c.CampaignTypeID = 1 And c.ImpressionsBurned < c.ImpressionTarget)
            Or (c.CampaignTypeID = 2 And c.clicksconsumed < c.clicktarget)
            Or (c.campaigntypeid = 3)
      );

-- Declaration of Vairables      
Declare @index As int,@maxRow As int, @weight Int, @bcid int
Set @index = 1 --Because we will start from First row
Select @maxRow = Count(0)  From @TempBanners Where Weight > 1  
-- How many rows we have that has weight more then 1
While(@index <= @maxRow)
Begin
      Select 
            @weight = V.Weight,
            @bcid = V.BcID
      From (
                  Select 
                        BCid,
                        Weight,
                        ROW_NUMBER() Over (Order By Bcid Asc) Row 
                  From @TempBanners 
                  Where Weight > 1 
            )V
      Where V.Row = @index

      Set @index = @index + 1 

      While(@weight <> 1)
      Begin
            Insert Into @TempBanners (ZoneID, BannerID, Weight, FileID, URL)
            Select ZoneID, BannerID, Weight, FileID, URL From @TempBanners Where BcID = @bcid 
            set @weight = @weight - 1
      End
End

-- INSERT INTO THE IMPRESSION QUEUE ALL THE BANNERS THAT ARE NOT YET IN THE QUEUE
Insert Into ImpressionsQueue (BannerID, ZoneID, FileID, ImpressionsBurned,  RowUpdated, IsPaused, NavigateURL )
Select V.BannerID, V.ZoneID, V.FileID, V.Impressions, GETDATE(), V.IsPaused, V.URL
From 
(
      Select m.BannerID, m.ZoneID, m.FileID, 
      isnull(m.IsPaused,0) as IsPaused, 
      isnull(m.Impressions,0) as Impressions,
      ISNULL(m.URL,'') as URL
      From @TempBanners m
      where Weight > 
            (select COUNT(t.bannerid) 
            from ImpressionsQueue as t
            where t.BannerID = m.BannerID
                and t.FileID = m.FileID
                and t.ZoneID = m.ZoneID
                )      
)As V;

-- Update the banner file id in case it is modified after the banner was created
Update ImpressionsQueue
Set FileID = CTE.FileID, ImpressionsQueue.IsPaused = isnull(CTE.IsPaused,0), ImpressionsQueue.NavigateURL = CTE.URL
From ImpressionsQueue I
Inner Join @TempBanners As CTE On CTE.BannerID = I.BannerID And CTE.ZoneID = I.ZoneID --And CTE.FileID <> I.FileID

----------------------------------------------------------------------------------------
-- End updating Impressions Queue
----------------------------------------------------------------------------------------


END TRY
BEGIN CATCH
    declare @error varchar(3000) = 'Message: ' + ERROR_MESSAGE() + ' ' + ERROR_LINE()
    exec master.sys.xp_logevent 50001, @error , 'Warning' 
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION
END CATCH
IF @@TRANCOUNT > 0
    COMMIT TRANSACTION

I have a SQL Script that I execute in a job to transform tables periodically. To speed it up I put that script in a stored procedure and executed it with a job. It worked faster.

The problem occurs at times when the stored procedure even though it executes it doesn't work. I use the script manually and run it and everything works fine.

The whole script is inside a transaction and I have made it so that if some error comes up it gets logged properly. However the script doesn't give any errors.


BEGIN TRANSACTION
BEGIN TRY

-- Rounding off Campaign stats
update Campaigns
set ImpressionsBurned = ImpressionTarget
where ImpressionsBurned > ImpressionTarget and CampaignTypeID = 1

update Campaigns
set ClicksConsumed = ClickTarget
where ClicksConsumed = ClickTarget and CampaignTypeID = 2

-- Updating Campaigns & Banners
update banners
set banners.impressionsburned = 
    (select  sum(impressionsqueue.impressionsburned) from impressionsqueue where impressionsqueue.bannerid = banners.bannerid)
where exists (select impressionsqueue.bannerid from impressionsqueue where impressionsqueue.bannerid = banners.bannerid)

update Campaigns
set ImpressionsBurned = 
    (select isnull(SUM(ImpressionsQueue.ImpressionsBurned),0) from ImpressionsQueue 
    inner join Banners on Banners.BannerID = ImpressionsQueue.BannerID and CampaignID = Campaigns.CampaignID
    )
where 
    exists (
        (select ImpressionsQueue.BannerID from ImpressionsQueue 
        inner join Banners on Banners.BannerID = ImpressionsQueue.BannerID and CampaignID = Campaigns.CampaignID
        )
    )
    and 
    (
    ( Campaigns.ImpressionsBurned < Campaigns.ImpressionTarget and Campaigns.CampaignTypeID = 1)
    or ( Campaigns.ClicksConsumed < Campaigns.ClickTarget and Campaigns.CampaignTypeID = 2) 
    or Campaigns.CampaignTypeID = 3
    )
    and Campaigns.IsPaused = 0
    and Campaigns.StartsOn <= GetDate() and Campaigns.EndsOn >= GetDate()

-- Updating Paused Banners in the Queue
update ImpressionsQueue
set IsPaused = (
    select IsPaused from Banners where Banners.BannerID = ImpressionsQueue.BannerID
)
-- Updating the Navigation URLs
update ImpressionsQueue
set NavigateURL = (
    select NavigateURL from Banners where Banners.BannerID = ImpressionsQueue.BannerID
)

-- Removing any rows if the Weight of a banner is updated, 
-- the banner will be reinserted later with updated impressions
delete from ImpressionsQueue 
where BannerID in 
( 
    select ImpressionsQueue.BannerID from ImpressionsQueue 
    inner join Banners on Banners.BannerID = ImpressionsQueue.BannerID
    group by ImpressionsQueue.BannerID, Banners.Weight
    having Banners.Weight <> COUNT(ImpressionsQueue.BannerID)
)

-- Removing entries whose impressions count has reached its target 
delete from impressionsqueue where
BannerID in (
    select Banners.BannerID from impressionsqueue
    inner join Banners on banners.bannerid = impressionsqueue.bannerid
    inner join campaigns on campaigns.campaignid = banners.campaignid
    where Campaigns.CampaignTypeID = 1 
    -- excluding flat fee based campaign
    group by Campaigns.ImpressionTarget, Banners.BannerID
    having not (Campaigns.ImpressionTarget > sum(ImpressionsQueue.impressionsburned))
    -- inverse logic for campaign count
)
-- Removing entries whose campaign click count has reached
delete from impressionsqueue where
BannerID in (
    select Banners.BannerID from impressionsqueue
    inner join Banners on banners.bannerid = impressionsqueue.bannerid
    inner join campaigns on campaigns.campaignid = banners.campaignid and Campaigns.CampaignTypeID = 2 
        and Not (Campaigns.ClickTarget > Campaigns.ClicksConsumed)
    -- inverse logic for campaign count
)
-- Removing entries whose campaign has expired
delete from impressionsqueue where
BannerID in (
    select impressionqueueid from impressionsqueue
    inner join Banners on banners.bannerid = impressionsqueue.bannerid
    inner join campaigns on campaigns.campaignid = banners.campaignid
        and not (Campaigns.StartsOn <= GETDATE() and Campaigns.EndsOn >= GETDATE())
    -- inverse logic for date
)

----------------------------------------------------------------------------------------
-- Begin updating Impressions Queue
----------------------------------------------------------------------------------------


Declare @TempBanners Table(BcID [int] IDENTITY(1,1),ZoneID [int], BannerID [int], Weight [int], FileID [uniqueidentifier], IsPaused [bit], Impressions [int], URL [nvarchar](2048))

/*
Insert into the temp table all the banners that:
      1) Belong to an active campaign => c.StartsOn <= GetDate() and c.EndsOn >= GetDate()
      2) and Belong to a campaign that is not paused
      3) and The banner itself is not paused
      4) and Flat Fee campaign banner
*/
Insert Into @TempBanners (ZoneID, BannerID, Weight, FileID, IsPaused, Impressions, URL)
Select 
      bz.ZoneID, 
      b.BannerID, 
      b.Weight,
      b.FileID,
      b.IsPaused,
      b.ImpressionsBurned,
      b.NavigateURL
From Banners b
Join Bannerzones bz on b.BannerID = bz.BannerID
Join Campaigns c on b.CampaignID = c.CampaignID
And c.StartsOn <= GetDate() and c.EndsOn >= GetDate()
And c.IsPaused = 0
And b.IsPaused = 0
And (
            (c.CampaignTypeID = 1 And c.ImpressionsBurned < c.ImpressionTarget)
            Or (c.CampaignTypeID = 2 And c.clicksconsumed < c.clicktarget)
            Or (c.campaigntypeid = 3)
      );

-- Declaration of Vairables      
Declare @index As int,@maxRow As int, @weight Int, @bcid int
Set @index = 1 --Because we will start from First row
Select @maxRow = Count(0)  From @TempBanners Where Weight > 1  
-- How many rows we have that has weight more then 1
While(@index <= @maxRow)
Begin
      Select 
            @weight = V.Weight,
            @bcid = V.BcID
      From (
                  Select 
                        BCid,
                        Weight,
                        ROW_NUMBER() Over (Order By Bcid Asc) Row 
                  From @TempBanners 
                  Where Weight > 1 
            )V
      Where V.Row = @index

      Set @index = @index + 1 

      While(@weight <> 1)
      Begin
            Insert Into @TempBanners (ZoneID, BannerID, Weight, FileID, URL)
            Select ZoneID, BannerID, Weight, FileID, URL From @TempBanners Where BcID = @bcid 
            set @weight = @weight - 1
      End
End

-- INSERT INTO THE IMPRESSION QUEUE ALL THE BANNERS THAT ARE NOT YET IN THE QUEUE
Insert Into ImpressionsQueue (BannerID, ZoneID, FileID, ImpressionsBurned,  RowUpdated, IsPaused, NavigateURL )
Select V.BannerID, V.ZoneID, V.FileID, V.Impressions, GETDATE(), V.IsPaused, V.URL
From 
(
      Select m.BannerID, m.ZoneID, m.FileID, 
      isnull(m.IsPaused,0) as IsPaused, 
      isnull(m.Impressions,0) as Impressions,
      ISNULL(m.URL,'') as URL
      From @TempBanners m
      where Weight > 
            (select COUNT(t.bannerid) 
            from ImpressionsQueue as t
            where t.BannerID = m.BannerID
                and t.FileID = m.FileID
                and t.ZoneID = m.ZoneID
                )      
)As V;

-- Update the banner file id in case it is modified after the banner was created
Update ImpressionsQueue
Set FileID = CTE.FileID, ImpressionsQueue.IsPaused = isnull(CTE.IsPaused,0), ImpressionsQueue.NavigateURL = CTE.URL
From ImpressionsQueue I
Inner Join @TempBanners As CTE On CTE.BannerID = I.BannerID And CTE.ZoneID = I.ZoneID --And CTE.FileID <> I.FileID

----------------------------------------------------------------------------------------
-- End updating Impressions Queue
----------------------------------------------------------------------------------------


END TRY
BEGIN CATCH
    declare @error varchar(3000) = 'Message: ' + ERROR_MESSAGE() + ' ' + ERROR_LINE()
    exec master.sys.xp_logevent 50001, @error , 'Warning' 
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION
END CATCH
IF @@TRANCOUNT > 0
    COMMIT TRANSACTION

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

带刺的爱情 2024-09-09 06:31:00

不确定这是否是所有问题的原因 - 但如果我是你,我会将 COMMIT TRANSACTION 放入 TRY..... 块中:

   -------------------------------------------------------------------------------
   -- End updating Impressions Queue
   -------------------------------------------------------------------------------
   IF @@TRANCOUNT > 0
       COMMIT TRANSACTION
END TRY
BEGIN CATCH
    declare @error varchar(3000) = 'Message: ' + ERROR_MESSAGE() + ' ' + ERROR_LINE()
    exec master.sys.xp_logevent 50001, @error , 'Warning' 
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION
END CATCH

如果一切顺利,你将执行 < code>COMMIT TRANSACTION 作为 TRY... 块的最后一条语句 - 如果出现问题,无论如何您都会陷入 CATCH 块。在 CATCH 块之外调用 COMMIT TRANSACTION 可能很危险......

Not sure if that's the cause of all problem - but if I were you, I'd put the COMMIT TRANSACTION inside the TRY..... block:

   -------------------------------------------------------------------------------
   -- End updating Impressions Queue
   -------------------------------------------------------------------------------
   IF @@TRANCOUNT > 0
       COMMIT TRANSACTION
END TRY
BEGIN CATCH
    declare @error varchar(3000) = 'Message: ' + ERROR_MESSAGE() + ' ' + ERROR_LINE()
    exec master.sys.xp_logevent 50001, @error , 'Warning' 
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION
END CATCH

If everything goes okay, you'll execute COMMIT TRANSACTION as the last statement of your TRY... block - and if something blows up, you'll fall into the CATCH block anyway. Might be dangerous to call COMMIT TRANSACTION outside your CATCH block after it....

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文