Loop through all records in my SQL Server database - sql-server-2008

I have the following SQL script. As you can see I manually set the #listingid value to 30653.
But this script should be executed for all records in the [listings] table where #listingid is assigned the value of the [listings].id column.
DECLARE #profname nvarchar(150)
DECLARE #furl nvarchar(250)
DECLARE #city nvarchar(250)
DECLARE #listingid int
set #listingid=30653
--select the top 1 professionname
SELECT TOP 1 #profname=REPLACE(LOWER(pn.title),' ','-'),#furl=l.friendlyurl,#city=REPLACE(REPLACE(LOWER(l.city),'''',''),' ','-') FROM healthprof_professionnames hpn
INNER JOIN professionname pn ON pn.id=hpn.professionnameid
INNER JOIN listings l on l.id=hpn.healthprofid
WHERE l.id=#listingid ORDER BY pn.title
--check if current friendlyurl already contains profession
IF NOT CHARINDEX(#profname,#furl)>0
SET #furl = #furl + '-' + #profname
IF NOT CHARINDEX(#city,#furl)>0
SET #furl = #furl + '-' + #city
SET #furl = #furl + '-3'
UPDATE listings set friendlyurl=#furl WHERE id=#listingid

You can use a cursor to loop over every row in a result set:
declare cur cursor for
select distinct id from listings
declare #listingid int
open cur
fetch next from cur into #listingid
while ##FETCH_STATUS = 0
BEGIN
-- your code from above goes here
fetch next from cur into #listingid
END
That being said, I agree with Tim's comment above. Rewrite it to work in one set-based operation if at all possible. I think this will work, but I haven't tested it:
;WITH vars AS (
SELECT id, profname, furl, city
FROM (
SELECT l.id,
REPLACE(LOWER(pn.title),' ','-') as profname,
l.friendlyurl as furl,
REPLACE(REPLACE(LOWER(l.city),'''',''),' ','-') as city,
ROW_NUMBER() OVER (PARTITION BY l.id ORDER BY pn.title) as rnk
FROM healthprof_professionnames hpn
INNER JOIN professionname pn ON pn.id=hpn.professionnameid
INNER JOIN listings l on l.id=hpn.healthprofid
) A
WHERE A.rnk = 1
),
vars2 AS (
SELECT id,
CASE WHEN NOT CHARINDEX(profname, furl) > 0
THEN furl + '-' + profname ELSE furl END as furl,
city
FROM vars
),
vars3 as (
SELECT id,
CASE WHEN NOT CHARINDEX(city, furl) > 0
THEN furl + '-' + city ELSE furl END as furl
FROM vars2
)
UPDATE listings SET friendlyurl = vars3.furl + '-3'
FROM listings INNER JOIN vars3 on vars3.id = listings.id

Related

How can I get the max column value from every table in multiple schemas?

Is it possible to get the max value of a single column which exists in the majority of tables within several different schemas?
If this were one or two tables, I could easily use:
SELECT 'schema1.table1' as rowsource, category, max(date_used) max_date_used from schema1.table1 group by category
UNION ALL
SELECT 'schema1.table2' as rowsource, category, max(date_used) max_date_used from schema1.table2 group by category
UNION ALL
SELECT 'schema2.table3' as rowsource, category, max(date_used) max_date_used from schema2.table3 group by category
UNION ALL
SELECT 'schema3.table4' as rowsource, category, max(date_used) max_date_used from schema3.table4 group by category
However, I am looking at having to query nearly 300 tables across 3 different schemas.
TIA for any advice/insight!
You could try to store all your required table from informationSchema into a temp table, then use Dynamic SQL to go through each one of it. For example
DROP TABLE IF EXISTS #Temp
CREATE TABLE #temp ---identity column will be used to iterate
(
id INT IDENTITY,
TableName VARCHAR(50),
SchemaName VARCHAR(20)
)
INSERT INTO #temp
SELECT TABLE_NAME,TABLE_SCHEMA
FROM INFORMATION_SCHEMA.TABLES
-- choose your own results with where conditions
DECLARE #SQL VARCHAR(MAX) = ''
DECLARE #Count INT = 1
DECLARE #SchemaName VARCHAR(20)
DECLARE #Table VARCHAR(20)
WHILE #COUNT <= (SELECT COUNT(*) FROM #temp)
BEGIN
SELECT #SchemaName = SchemaName FROM #temp WHERE id = #Count
SELECT #table = TABLENAME FROM #temp WHERE id = #Count
SELECT #sql = #sql + 'SELECT category, max(date_used) max_date_used from ' + #SchemaName + '.' + #Table + ' group by category
UNION ALL '
SET #Count = #Count + 1
END
PRINT LEFT((#SQL),LEN(#SQL) - LEN('UNION ALL '))
After you check the printed result, change it to EXEC if you think that is correct for you.

Store values in different variables in SQL, separated by (Comma) ","

I need to separate values and store them in different variables in SQL,
for example
a='3100,3101,3102,....'
And the output should be
x=3100
y=3101
z=3102
.
.
.
create function [dbo].[udf_splitstring] (#tokens varchar(max),
#delimiter varchar(5))
returns #split table (
token varchar(200) not null )
as
begin
declare #list xml
select #list = cast('<a>'
+ replace(#tokens, #delimiter, '</a><a>')
+ '</a>' as xml)
insert into #split
(token)
select ltrim(t.value('.', 'varchar(200)')) as data
from #list.nodes('/a') as x(t)
return
end
GO
declare #cad varchar(100)='3100,3101,3102'
select *,ROW_NUMBER() over (order by token ) as rn from udf_splitstring(#cad,',')
token rn
3100 1
3101 2
3102 3
The results of the Parse TVF can easily be incorporated into a JOIN, or an IN
Declare #a varchar(max)='3100,3101,3102'
Select * from [dbo].[udf-Str-Parse](#a,',')
Returns
RetSeq RetVal
1 3100
2 3101
3 3102
The UDF if needed (much faster than recursive, loops, and xml)
CREATE FUNCTION [dbo].[udf-Str-Parse] (#String varchar(max),#Delimiter varchar(25))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(#String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 a,cte1 b,cte1 c,cte1 d) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(#Delimiter) From cte2 t Where Substring(#String,t.N,DataLength(#Delimiter)) = #Delimiter),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(#Delimiter,#String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By A.N)
,RetVal = LTrim(RTrim(Substring(#String, A.N, A.L)))
From cte4 A
);
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/
--Much faster than str-Parse, but limited to 8K
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||')
I suggest you to use following query, it's much faster than other functions like cross apply and udf.
SELECT
Variables
,S_DATA
FROM (
SELECT
Variables
,CASE WHEN LEN(LIST2)>0 THEN LTRIM(RTRIM(SUBSTRING(LIST2, NUMBER+1, CHARINDEX(',', LIST2, NUMBER+1)-NUMBER - 1)))
ELSE NULL
END AS S_DATA
,NUMBER
FROM(
SELECT Variables
,','+COMMA_SEPARETED_COLUMN+',' LIST2
FROM Tb1
)DT
LEFT OUTER JOIN TB N ON (N.NUMBER < LEN(DT.LIST2)) OR (N.NUMBER=1 AND DT.LIST2 IS NULL)
WHERE SUBSTRING(LIST2, NUMBER, 1) = ',' OR LIST2 IS NULL
) DT2
WHERE S_DATA<>''
and also you should create a table 'NUMBER' before running the above query.
CREATE TABLE TB (Number INT)
DECLARE #I INT=0
WHILE #I<1000
BEGIN
INSERT INTO TB VALUES (#I)
SET #I=#I+1
END

Apex ORA-01008: not all variables bound on host variables

I am working with an apex environment where I need a dynamic sql query. Apex provides this api with the help of "Classic Report (based on function)". I would like you to draw your attention to line 8. My appoligies the spacing gets messed up when I paste it into stackoverflow. Now the problem is that I am getting the error 'ORA-01008: not all variables bound' Which is funny because when I change the :TEAM_SELECTOR in line 8 to something along the lines of 'MYSQL' (which is a team name) then this code works without error. Notice that :TEAM_SELECTOR is also used in the returned query without problem. Also I am using APEX 5.
DECLARE
v_time INT;
v_start_time int;
v_end_time int;
v_rownum int := 1;
v_max_shifts int;
v_location INT;
v_P4_team_selector varchar2(30) := :TEAM_SELECTOR;
BEGIN
select extract(hour from CAST(sysdate AS TIMESTAMP)) into v_time from dual;
select count(*) into v_max_shifts from oncall_shift
where team = v_P4_team_selector;
FOR i IN 0..v_max_shifts
LOOP
select start_time into v_start_time from (select * from oncall_shift where team =v_P4_team_selector)
where rownum = v_rownum;
select end_time into v_end_time from (select * from oncall_shift where team =v_P4_team_selector)
where rownum = v_rownum;
v_rownum := v_rownum + 1;
if v_time >= v_start_time and v_time <= v_end_time
then
select location into v_location from oncall_shift
where team = v_P4_team_selector
and start_time = v_start_time
and end_time = v_end_time;
return '
SELECT E.FNAME "First Name",E.LNAME "Last Name",E.OFFICE_NUM "Office Number", E.MOBILE_NUM "Mobile Number",L.NAME Location, o.position "Primary/Secondary"
FROM EMPLOYEE E, LOCATION L, ON_CALL O
WHERE E.ID = O.EMP_ID
AND L.ID = O.LOC_ID
AND O.ONCALL_DATE=TRUNC(SYSDATE)
AND O.TEAM=:TEAM_SELECTOR
AND L.ID = ' || v_location ||
' ORDER BY l.name asc
';
EXIT;
END IF;
END LOOP;
END;
Okay so I believe the issue was that the classic report based on a function executes before the host variables (TEAM_SELECTOR) is able to be bound therefore throwing the error. My solution to this was to change it to a normal classic report based on a sql query which runs after host variables are bound, because I needed one separate variable I created a P1_LOCATION item on that page using the same the query expect changing "v_location" to P1_LOCATION. Now in the P1_LOCATION page item I put the procedure to get the location.
P1_LOCATION code:
DECLARE
v_time INT;
v_start_time int;
v_end_time int;
v_rownum int := 1;
v_max_shifts int;
v_location INT;
v_P4_team_selector varchar2(30) := :TEAM_SELECTOR;
BEGIN
select extract(hour from CAST(sysdate AS TIMESTAMP)) into v_time from dual;
select count(*) into v_max_shifts from oncall_shift
where team = v_P4_team_selector;
FOR i IN 0..v_max_shifts
LOOP
select start_time into v_start_time from (select * from oncall_shift where team =v_P4_team_selector)
where rownum = v_rownum;
select end_time into v_end_time from (select * from oncall_shift where team =v_P4_team_selector)
where rownum = v_rownum;
v_rownum := v_rownum + 1;
if v_time >= v_start_time and v_time <= v_end_time
then
select location into v_location from oncall_shift
where team = v_P4_team_selector
and start_time = v_start_time
and end_time = v_end_time;
APEX_UTIL.set_session_state('P1_LOCATION',v_location);
EXIT;
END IF;
END LOOP;
END;
Classic Report (sql query):
SELECT E.FNAME "First Name",E.LNAME "Last Name",E.OFFICE_NUM "Office Number", E.MOBILE_NUM "Mobile Number",L.NAME Location, o.position "Primary/Secondary"
FROM EMPLOYEE E, LOCATION L, ON_CALL O
WHERE E.ID = O.EMP_ID
AND L.ID = O.LOC_ID
AND O.ONCALL_DATE=TRUNC(SYSDATE)
AND O.TEAM=:TEAM_SELECTOR
AND L.ID = :P1_LOCATION
ORDER BY l.name asc

case statement in where clause - SQL Server 2008

SELECT
PDADate, T.Merchandizer_ID, T.Merchandizer, Merchandizer_LoginName,
STORE_ID, STORE_CODE, STORE_NAME,
ACCOUNT_ID, ACCOUNT_NAME, Account_Store_Format_Id, Account_Store_Format,
StoreType_Id, StoreType, T.Listid, T.Listname,
T.TimeIn, T.TimeOut, T.PlannedDate, T.Reason, TaskCode, TotalTime
FROM
[dbo].Report_RD_Coverage T
INNER JOIN
#TempLocationH TL ON TL.LocationId=T.Location_Id
WHERE
CONVERT(Date, PDADate) Between (#Start_Date) AND Isnull(#End_Date, #CurrentDate)
AND T.Account_Id IN
(SELECT
CASE WHEN #Account_Id IS NULL THEN T.Account_Id
ELSE (SELECT * FROM UDF_SplitString(#Account_Id,','))
END
)
AND T.StoreType_Id IN
(SELECT
CASE WHEN #StoreType_Id IS NULL THEN T.StoreType_Id
ELSE (SELECT * FROM UDF_SplitString(#StoreType_Id,','))
END
)
AND T.Store_Id IN
(SELECT
CASE WHEN #Store_Id IS NULL THEN T.Store_Id
ELSE (SELECT * FROM UDF_SplitString(#Store_Id,','))
END
)
If #Account_Id, #StoreType_Id and #Store_Id are null the it should select all the ACCOUNT_ID, STORETYPE_ID and STORE_ID otherwise based on parameter value it should filter.
UDF_SplitString is the function to split up comma-separated strings, and its return value is a table like:
- 1
- 2
- 3
I'm getting this error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
CASE must return a scalar value, so try this variation instead:
select PDADate, T.Merchandizer_ID, T.Merchandizer, Merchandizer_LoginName, STORE_ID, STORE_CODE,
STORE_NAME, ACCOUNT_ID, ACCOUNT_NAME, Account_Store_Format_Id, Account_Store_Format,
StoreType_Id, StoreType, T.Listid, T.Listname, T.TimeIn, T.TimeOut, T.PlannedDate,
T.Reason, TaskCode, TotalTime
from [dbo].Report_RD_Coverage T
inner join #TempLocationH TL on TL.LocationId = T.Location_Id
where CONVERT(date, PDADate) between (#Start_Date)
and Isnull(#End_Date, #CurrentDate)
and (
#Account_Id is null
or T.Account_Id in (
select *
from UDF_SplitString(#Account_Id, ',')
)
)
and (
#StoreType_Id is null
or T.StoreType_Id in (
select *
from UDF_SplitString(#StoreType_Id, ',')
)
)
and (
#Store_Id is null
or T.Store_Id in (
select *
from UDF_SplitString(#Store_Id, ',')
) end
)
I tried this and reached very closer but you have to do something from what I found a link.
This is my try. the only thing you need to build is the #udf data.
declare #Store_Id INT;
declare #Account_Id INT;
DECLARE #UDF[9] OF VARCHAR(30);
set #Store_Id = 99 --NULL
set #Account_Id = 15
SET #UDF = '11,12,13,14,15,16'
SELECT #Account_Id AS ACID
WHERE CAST(#Account_Id AS VARCHAR(6)) IN (
CASE WHEN #Store_Id IS NULL THEN CAST(#Account_Id AS VARCHAR(6))
ELSE #UDF END
The link is at
http://www.codeproject.com/Questions/473174/CreateplusArrayplusinplusSqlplusServer
DECLARE #INSTR as VARCHAR(MAX)
SET #INSTR = '2,3,177,'
DECLARE #SEPERATOR as VARCHAR(1)
DECLARE #SP INT
DECLARE #VALUE VARCHAR(1000)
SET #SEPERATOR = ','
CREATE TABLE #tempTab (id int not null)
WHILE PATINDEX('%' + #SEPERATOR + '%', #INSTR ) <> 0
BEGIN
SELECT #SP = PATINDEX('%' + #SEPERATOR + '%',#INSTR)
SELECT #VALUE = LEFT(#INSTR , #SP - 1)
SELECT #INSTR = STUFF(#INSTR, 1, #SP, '')
INSERT INTO #tempTab (id) VALUES (#VALUE)
END
SELECT * FROM myTable WHERE id IN **(SELECT id FROM #tempTab)**
DROP TABLE #tempTab
you can extract for the sql in bold and the logic how to create temp table and its data and I hope you will get what you want.
> This is the my right solultion........now its working correctly
CREATE TABLE #Store_Id (StoreID varchar(20))
IF #Store_Id != '0'
BEGIN
INSERT INTO #Store_Id
SELECT data FROM UDF_SplitString(#Store_Id,',')
END
ELSE
BEGIN
INSERT INTO #Store_Id
SELECT '0'
END
CREATE TABLE #StoreType_Id (StoreTypeID varchar(20))
IF #StoreType_Id != '0'
BEGIN
INSERT INTO #StoreType_Id
SELECT data FROM UDF_SplitString(#StoreType_Id,',')
END
ELSE
BEGIN
INSERT INTO #StoreType_Id
SELECT '0'
END
CREATE TABLE #Account_Id (AccountID varchar(20))
IF #Account_Id != '0'
BEGIN
INSERT INTO #Account_Id
SELECT data FROM UDF_SplitString(#Account_Id,',')
END
ELSE
BEGIN
INSERT INTO #Account_Id
SELECT '0'
END
INSERT INTO #FinalTable(VisitDate,Merchandizer_Id,Merchandizer,MerchandizerLogin,StoreId,StoreCode,StoreName,AccountId,AccountName,
Account_Store_Format_Id,Account_Store_Format,StoreTypeId ,StoreType ,ListId ,ListName,TimeIn ,TimeOut,PlannedDate ,Reason ,TaskCode,TotalTime)
SELECT Visit_Date,T.Merchandizer_ID,T.Merchandizer,Merchandizer_LoginName,STORE_ID,STORE_CODE,STORE_NAME,ACCOUNT_ID,ACCOUNT_NAME,
Account_Store_Format_Id,Account_Store_Format,StoreType_Id,
StoreType,T.Listid,T.Listname,T.TimeIn,T.TimeOut,T.PlannedDate,T.Reason,TaskCode,TotalTime
FROM [dbo].Report_RD_Coverage T
INNER JOIN #TempLocationH TL ON TL.LocationId=T.Location_Id
INNER JOIN #Store_Id on CONVERT(VARCHAR,t.Store_Id) = CASE WHEN #Store_Id = '0' THEN convert(VARCHAR,t.Store_Id) ELSE StoreID END
INNER JOIN #StoreType_Id on CONVERT(VARCHAR,t.StoreType_Id) = CASE WHEN #StoreType_Id = '0' THEN convert(VARCHAR,t.StoreType_Id) ELSE StoreTypeID END
INNER JOIN #Account_Id on CONVERT(VARCHAR,t.Account_Id) = CASE WHEN #Account_Id = '0' THEN convert(VARCHAR,t.Account_Id) ELSE AccountID END
WHERE CONVERT(Date,PDADate) Between #Start_Date AND #End_Date

SQL Stored Procedure fails to update data while the script in it works manually

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
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....