July 8, 2005 at 8:33 am
I don't unserstand how you relate the column name to to tables.. can you be more specific?
July 8, 2005 at 9:00 am
I look up the column name in the Carriers table to get the CarrierID (CarID).
I realized that I was processing EVERY cell (row,column), not just the ones with a '1'. Plus I realized I could shorten it by looking at the columns, not the rows, so I came up with a new Dynamic SQL set-based approach to get all the ProspectID's that have a 1 in the current column. Basically I only iterate the rows in each column that have a 1, as opposed to iterating every column in each row looking for a 1.
This just finished and took 6:40 as opposed to almost 2 hours yesterday:
--------------------------------------------------------------------------
DECLARE @maxcol int
DECLARE @maxid int
DECLARE @curid int
DECLARE @oldid int
DECLARE @ColID int
DECLARE @colname nvarchar(100)
DECLARE @carid int
DECLARE @count float
DECLARE @sql nvarchar(2000)
DECLARE @Parm nvarchar(1000)
DECLARE @cols table(cid int identity, colname nvarchar(100), carid int)
SET NOCOUNT ON
TRUNCATE TABLE APPOINTMENTS
SELECT @maxcol=max(ordinal_position)-2 FROM information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments'
While @ColID <=@maxcol BEGIN
insert into @cols
Select column_name, carid FROM information_schema.columns left outer
WHERE table_name=N'2004 UIL Prospects Appointments'
set @ColID=@ColID + 1
END
create table #temp (ProspectID int)
Set @ColID=1
While @ColID<@maxcol BEGIN
print 'Col: ' + cast(@colid as varchar(4))
Select @colname = colname, @carid=carid from @cols where cid=@ColID
SET @sql = N'Insert into #temp'
SET @sql = @sql + N' Select ProspectID from [2004 UIL Prospects
print 'sql: '+@SQL
EXEC dbo.SP_EXECUTESQL @sql
-- #temp contains all entries=1 for that carrier
Print 'Appts: ' + cast(@maxid as varchar(8))
SELECT @maxid=max(ProspectID) FROM #temp
SELECT @curid=min(ProspectID) FROM #temp
SET @oldid=@curid
SET @count = 1
While @curid<=@maxid BEGIN
INSERT INTO Appointments (ID, CarID) VALUES(@curid, @CarID)
SELECT @curid=min(ProspectID) FROM #temp WHERE ProspectID>@oldid
SET @oldid=@curid
END
truncate table #temp
set @ColID=@ColID+1 -- Next Column
END
drop table #temp
July 8, 2005 at 9:17 am
-- Populate Carriers
insert into Carriers( CarrierName, ID)
select Column_Name, (Ordinal_Position - 10) as ID
FROM information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments'
and ORdinal_Position between 11 and 102
-- Populate Appointments
insert into Appointments( ID, CarrierID)
select PK_apointment, CarrierID and
YourTable
crossjoin
Carriers
where
1= (case when ID = 1 and [1st Auto] = 1 then 1
when ID = 2 and [Accident Fund] = 1 then 1
when ID = 3 and [ACUITY] = 1 then 1
when ID = 4 and [Allied] = 1 then 1
when ID = 5 and [Amerisure] = 1 then 1
when ID = 6 and [ASI] = 1 then 1
when ID = 7 and [Atlantic Mutual] = 1 then 1
when ID = 8 and [Austin Mutual] = 1 then 1
when ID = 9 and [Badger] = 1 then 1
when ID = 10 and [Barnstable] = 1 then 1
when ID = 11 and [Beacon] = 1 then 1
when ID = 12 and [Bituminous] = 1 then 1
when ID = 13 and [Blue Ridge] = 1 then 1
when ID = 14 and [Brethren Mutual] = 1 then 1
when ID = 15 and [Briarcreek] = 1 then 1
when ID = 16 and [Buckeye] = 1 then 1
when ID = 17 and [Bunker Hill] = 1 then 1
when ID = 18 and [Calif Insurance Group] = 1 then 1
when ID = 19 and [Cameron] = 1 then 1
when ID = 20 and [Casco] = 1 then 1
when ID = 21 and [Central Mutual] = 1 then 1
when ID = 22 and [Chubb] = 1 then 1
when ID = 23 and [Cincinnati Financial] = 1 then 1
when ID = 24 and [C N A] = 1 then 1
when ID = 25 and [Colorado Casualty] = 1 then 1
when ID = 26 and [Columbia] = 1 then 1
when ID = 27 and [Commerce] = 1 then 1
when ID = 28 and [Continental Western] = 1 then 1
when ID = 29 and [crop insurer] = 1 then 1
when ID = 30 and [Cumberland] = 1 then 1
when ID = 31 and [Donegal] = 1 then 1
when ID = 32 and [Encompass] = 1 then 1
when ID = 33 and [Erie] = 1 then 1
when ID = 34 and [Erie and Niagara] = 1 then 1
when ID = 35 and [Everett Cash Mutual] = 1 then 1
when ID = 36 and [FAMI] = 1 then 1
when ID = 37 and [Farmers and Merchanics] = 1 then 1
when ID = 38 and [Farmers Mutual of Nebraska] = 1 then 1
when ID = 39 and [Financial Pacific] = 1 then 1
when ID = 40 and [Finger Lakes] = 1 then 1
when ID = 41 and [Firemans Fund] = 1 then 1
when ID = 42 and [Foremost] = 1 then 1
when ID = 43 and [Fremont Insurance] = 1 then 1
when ID = 44 and [General Casualty] = 1 then 1
when ID = 45 and [GMAC] = 1 then 1
when ID = 46 and [GuideOne] = 1 then 1
when ID = 47 and [Hanover] = 1 then 1
when ID = 48 and [Harleysville] = 1 then 1
when ID = 49 and [Hartford] = 1 then 1
when ID = 50 and [Hastings Mutual] = 1 then 1
when ID = 51 and [Hawaii Employers] = 1 then 1
when ID = 52 and [IIABA] = 1 then 1
when ID = 53 and [Iowa Mutual] = 1 then 1
when ID = 54 and [Kansas Mutual] = 1 then 1
when ID = 55 and [Lebananon] = 1 then 1
when ID = 56 and [Liberty Northwest] = 1 then 1
when ID = 57 and [Madison Mutual] = 1 then 1
when ID = 58 and [Marysville Mutual] = 1 then 1
when ID = 59 and [MD Injured Works fund] = 1 then 1
when ID = 60 and [Merchants] = 1 then 1
when ID = 61 and [Mercury] = 1 then 1
when ID = 62 and [Miami Mutual] = 1 then 1
when ID = 63 and [MICOA] = 1 then 1
when ID = 64 and [Midwest Family Mutual] = 1 then 1
when ID = 65 and [Montgomery Insurance] = 1 then 1
when ID = 66 and [MSA] = 1 then 1
when ID = 67 and [Mutual Fire] = 1 then 1
when ID = 68 and [NLC] = 1 then 1
when ID = 69 and [Northern Neck] = 1 then 1
when ID = 70 and [Ohio Casualty] = 1 then 1
when ID = 71 and [OneBeacon] = 1 then 1
when ID = 72 and [Oregon Mutual] = 1 then 1
when ID = 73 and [Peninsula] = 1 then 1
when ID = 74 and [Penn National] = 1 then 1
when ID = 75 and [Pioneer State] = 1 then 1
when ID = 76 and [PRAC] = 1 then 1
when ID = 77 and [Preferred Mutual] = 1 then 1
when ID = 78 and [PROG] = 1 then 1
when ID = 79 and [Rockford Mutual] = 1 then 1
when ID = 80 and [Rockwood Casualty] = 1 then 1
when ID = 81 and [Safeco] = 1 then 1
when ID = 82 and [Safety] = 1 then 1
when ID = 83 and [SAIF] = 1 then 1
when ID = 84 and [Secura] = 1 then 1
when ID = 85 and [Selective] = 1 then 1
when ID = 86 and [Southern Family] = 1 then 1
when ID = 87 and [Southern Mutual] = 1 then 1
when ID = 88 and [St Paul] = 1 then 1
when ID = 89 and [State Auto] = 1 then 1
when ID = 90 and [Superior] = 1 then 1
when ID = 91 and [The Columbus OH Grange] = 1 then 1
when ID = 92 and [Travelers] = 1 then 1
when ID = 93 and [Tuscarora-Wayne] = 1 then 1
when ID = 94 and [Unigard] = 1 then 1
when ID = 95 and [Unitrin] = 1 then 1
when ID = 96 and [West Bend] = 1 then 1
when ID = 97 and [Western Reserve] = 1 then 1
when ID = 98 and [Westfield] = 1 then 1
when ID = 99 and [Wilson Mutual] = 1 then 1
when ID = 100 and [Windsor] = 1 then 1
when ID = 101 and [Wisconsin Mutual] = 1 then 1
when ID = 102 and [Wolverine] = 1 then 1
else 0 end)
* Noel
July 8, 2005 at 10:14 am
Noeld -
Carriers is already populated. It's a fixed table. The only time it's updated is when a new Carrier is introduced in the "UIL Prospects Appointments" table (The "2004" in the name is unfortunate. The original developer was obviously a moron since the table is updated a couple of times each year, he even built in code to do that. It was imported from an Excel spreadsheet and I think he just took the default name. I'd have called it "Prospects").
The updates to the Prospects table that results in new carriers would require recoding of your gigundo Select statement. Since the customer has the capability to import a new spreadsheet into the table (and thereby change the schema -- double ewwww!) this becomes problematic. We've dealt with that in terms of ensuring the Carriers table gets updated based on the columns in Prospects, but rebuilding the Appointments table has always been a pain.
The whole thing runs as a DTS Job so now that I have it down to 6 minutes from 2 hours and I still have the flexibility of not being hard-coded to the schema I think I'll leave well enough alone.
It is a good example of a Set-Based answer to the problem, though.
July 8, 2005 at 10:20 am
If the schema changes you can generate the SQL dynamically.
BTW: you are HARD CODING COLUMN POSITIONS too ( set @ColID=11 )
I bet my query BLASTS the heck out of the while loops!
* Noel
July 8, 2005 at 10:21 am
Not even worth trying to compare.. gonna be too depressing .
July 8, 2005 at 10:24 am
"If the schema changes you can generate the SQL dynamically." Oy... I suppose I could, I'll have to think on that one. That's a lot of dynamic sql.
"BTW: you are HARD CODING COLUMN POSITIONS too ( set @ColID=11 )" Yes, BUT the schema changes are only after column 10. The first ten columns are fixed info (agency name, contact, address, etc). Cols 11 through nCols-2 are the variable part of the schema.
"I bet my query BLASTS the heck out of the while loops!" Could be. If I have some time maybe I'll code up a test and try it.
July 8, 2005 at 10:44 am
>>Oy... I suppose I could, I'll have to think on that one. That's a lot of dynamic sql. <<
You mean this ?
declare @STR varchar(8000)
@STR = 'insert into Appointments( ID, CarrierID)
select PK_apointment, CarrierID and
YourTable
crossjoin
Carriers
where
1= (case '
select @STR = @STR + 'When ID = ' cast(columnID - 10 as varchar(4)) + ' and [' + column_name + '] = 1 then 1 ' + chr(13) + chr(10)
from
information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments'
and ORdinal_Position between 11 and (select max(columnID)
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments') -2
set @STR = @STR + ' else 0 end)'
exec (@str)
* Noel
July 8, 2005 at 10:45 am
Hmmm... 6:36 v 00:26. There's a difference in the results between the two of about 1,000 entries in the Appointments table. I'll have to see if I can figure out where that's coming from. Fast doesn't help if it's not right. Maybe I'll tackle generating the Where clause and using ExecuteSQL so I know I'm getting the right Carrier ID AND Column name...
You were right, I was wrong...
July 8, 2005 at 10:47 am
You mean this ?
declare @STR varchar(8000)
@STR = 'insert into Appointments( ID, CarrierID)
select PK_apointment, CarrierID and
YourTable
crossjoin
Carriers
where
1= (case '
select @STR = @STR + 'When ID = ' cast(columnID - 10 as varchar(4)) + ' and [' + column_name + '] = 1 then 1 ' + chr(13) + chr(10)
from
information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments'
and ORdinal_Position between 11 and (select max(columnID)
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments') -2
set @STR = @STR + ' else 0 end)'
exec (@str)
Uhh... Yeah. That. Thanks.
July 8, 2005 at 10:52 am
Just watch out for the limit of 8000 characters which at the pace you are going you may get there in no time Not that it is impossible because you can always use two variables and run the exec like : exec (@str1 + @str2) but it needs a bit of recoding
Good luck!
* Noel
July 8, 2005 at 11:03 am
OK. The code stops at Carrier #88:
insert into Appts( ID, CarID) select P.ProspectID, C.CarID FROM [2004 UIL Prospects Appointments] P cross join Carriers C where 1= (case
When ID = 1 and [1st Auto] = 1 then 1
When ID = 2 and [Accident Fund] = 1 then 1
When ID = 3 and [ACUITY] = 1 then 1
When ID = 4 and [Allied] = 1 then 1
When ID = 5 and [Amerisure] = 1 then 1
When ID = 6 and [ASI] = 1 then 1
When ID = 7 and [Atlantic Mutual] = 1 then 1
When ID = 8 and [Austin Mutual] = 1 then 1
When ID = 9 and [Badger] = 1 then 1
When ID = 10 and [Barnstable] = 1 then 1
When ID = 11 and [Beacon] = 1 then 1
When ID = 12 and [Bituminous] = 1 then 1
When ID = 13 and [Blue Ridge] = 1 then 1
When ID = 14 and [Brethren Mutual] = 1 then 1
When ID = 15 and [Briarcreek] = 1 then 1
When ID = 16 and [Buckeye] = 1 then 1
When ID = 17 and [Bunker Hill] = 1 then 1
When ID = 18 and [Calif Insurance Group] = 1 then 1
When ID = 19 and [Cameron] = 1 then 1
When ID = 20 and [Casco] = 1 then 1
When ID = 21 and [Central Mutual] = 1 then 1
When ID = 22 and [Chubb] = 1 then 1
When ID = 23 and [Cincinnati Financial] = 1 then 1
When ID = 24 and [C N A] = 1 then 1
When ID = 25 and [Colorado Casualty] = 1 then 1
When ID = 26 and [Columbia] = 1 then 1
When ID = 27 and [Commerce] = 1 then 1
When ID = 28 and [Continental Western] = 1 then 1
When ID = 29 and [crop insurer] = 1 then 1
When ID = 30 and [Cumberland] = 1 then 1
When ID = 31 and [Donegal] = 1 then 1
When ID = 32 and [Encompass] = 1 then 1
When ID = 33 and [Erie] = 1 then 1
When ID = 34 and [Erie and Niagara] = 1 then 1
When ID = 35 and [Everett Cash Mutual] = 1 then 1
When ID = 36 and [FAMI] = 1 then 1
When ID = 37 and [Farmers and Merchanics] = 1 then 1
When ID = 38 and [Farmers Mutual of Nebraska] = 1 then 1
When ID = 39 and [Financial Pacific] = 1 then 1
When ID = 40 and [Finger Lakes] = 1 then 1
When ID = 41 and [Firemans Fund] = 1 then 1
When ID = 42 and [Foremost] = 1 then 1
When ID = 43 and [Fremont Insurance] = 1 then 1
When ID = 44 and [General Casualty] = 1 then 1
When ID = 45 and [GMAC] = 1 then 1
When ID = 46 and [GuideOne] = 1 then 1
When ID = 47 and [Hanover] = 1 then 1
When ID = 48 and [Harleysville] = 1 then 1
When ID = 49 and [Hartford] = 1 then 1
When ID = 50 and [Hastings Mutual] = 1 then 1
When ID = 51 and [Hawaii Employers] = 1 then 1
When ID = 52 and [IIABA] = 1 then 1
When ID = 53 and [Iowa Mutual] = 1 then 1
When ID = 54 and [Kansas Mutual] = 1 then 1
When ID = 55 and [Lebananon] = 1 then 1
When ID = 56 and [Liberty Northwest] = 1 then 1
When ID = 57 and [Madison Mutual] = 1 then 1
When ID = 58 and [Marysville Mutual] = 1 then 1
When ID = 59 and [MD Injured Works fund] = 1 then 1
When ID = 60 and [Merchants] = 1 then 1
When ID = 61 and [Mercury] = 1 then 1
When ID = 62 and [Miami Mutual] = 1 then 1
When ID = 63 and [MICOA] = 1 then 1
When ID = 64 and [Midwest Family Mutual] = 1 then 1
When ID = 65 and [Montgomery Insurance] = 1 then 1
When ID = 66 and [MSA] = 1 then 1
When ID = 67 and [Mutual Fire] = 1 then 1
When ID = 68 and [NLC] = 1 then 1
When ID = 69 and [Northern Neck] = 1 then 1
When ID = 70 and [Ohio Casualty] = 1 then 1
When ID = 71 and [OneBeacon] = 1 then 1
When ID = 72 and [Oregon Mutual] = 1 then 1
When ID = 73 and [Peninsula] = 1 then 1
When ID = 74 and [Penn National] = 1 then 1
When ID = 75 and [Pioneer State] = 1 then 1
When ID = 76 and [PRAC] = 1 then 1
When ID = 77 and [Preferred Mutual] = 1 then 1
When ID = 78 and [PROG] = 1 then 1
When ID = 79 and [Rockford Mutual] = 1 then 1
When ID = 80 and [Rockwood Casualty] = 1 then 1
When ID = 81 and [Safeco] = 1 then 1
When ID = 82 and [Safety] = 1 then 1
When ID = 83 and [SAIF] = 1 then 1
When ID = 84 and [Secura] = 1 then 1
When ID = 85 and [Selective] = 1 then 1
When ID = 86 and [Southern Family] = 1 then 1
When ID = 87 and [Southern Mutual] = 1 then 1
When ID = 88 and [St Paul] = 1 else 0 end)
The length of the final string is 4012. The final code is:
declare @STR varchar(8000)
SET @STR = 'insert into Appts( ID, CarID) select P.ProspectID, C.CarID FROM [2004 UIL Prospects Appointments] P cross join Carriers C where 1= (case '+ char(13) + char(10)
select @STR = @STR + 'When ID = ' + cast(Ordinal_Position-10 as varchar(6)) + ' and [' + column_name + '] = 1 then 1 ' + char(13) + char(10)
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments' and
Ordinal_Position between 11 and (select max(Ordinal_Position)-2
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments')
ORDER BY Ordinal_Position
set @STR = @STR + ' else 0 end)'
print @STR
print 'len: ' + cast(len(@str) as varchar(8))
I had to make some minor adjustments. I ran the (select max(Ordinal_Position)-2
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments') subquery independently and it returns "112". I tried hard-coding 112 ('between 11 and 112') in the main query and it still stopped at #88. Could it have something to do with string length? @STR is varchar(8000). I don't get it.
July 8, 2005 at 11:06 am
It has something to do with string length. When I changed the code to:
declare @STR varchar(8000)
SET @STR = 'insert into Appts( ID, CarID) select P.ProspectID, C.CarID FROM [2004 UIL Prospects Appointments] P cross join Carriers C where 1= (case '+ char(13) + char(10)
select @STR = @STR + 'When C.CarID = ' + cast(Ordinal_Position-10 as varchar(6)) + ' and [' + column_name + '] = 1 then 1 ' + char(13) + char(10)
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments' and
Ordinal_Position between 11 and (select max(Ordinal_Position)-2
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments')
ORDER BY Ordinal_Position
set @STR = @STR + ' else 0 end)'
(I forgot that "ID" should have been "C.CarID") it only got up to #79 and the string length was still 4012.
July 8, 2005 at 11:12 am
Don't know if there's a more elegant solution, but this works:
declare @str1 varchar(8000)
declare @str2 varchar(8000)
SET @str1 = 'insert into Appts( ID, CarID) select P.ProspectID, C.CarID FROM [2004 UIL Prospects Appointments] P cross join Carriers C where 1= (case '+ char(13) + char(10)
select @str1 = @str1 + 'When C.CarID=' + cast(Ordinal_Position-10 as varchar(6)) + ' and [' + column_name + ']=1 then 1 ' + char(13) + char(10)
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments' and
Ordinal_Position between 11 and 60
ORDER BY Ordinal_Position
SET @str2 = ''
select @str2 = @str2 + 'When C.CarID=' + cast(Ordinal_Position-10 as varchar(6)) + ' and [' + column_name + ']=1 then 1 ' + char(13) + char(10)
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments' and
Ordinal_Position between 61 and (select max(Ordinal_Position)-2
from information_schema.columns
WHERE table_name='2004 UIL Prospects Appointments')
ORDER BY Ordinal_Position
set @str1 = @str1 + @str2 + ' else 0 end)'
print @str1
print 'len: ' + cast(len(@str1) as varchar(8))
Final length = 4,744
Now to see if it runs.
July 8, 2005 at 11:39 am
The above is essentially the final code. It ran great (26 seconds) and the discrepency in the results vs my original code was a bug in my original code.
Kudos noeld. Of course I would have saved myself some heartache and a few long posts had I noticed your message at the top of this page on string length (duh!). I was able to figure that one out myself though...
Thanks bunches guys. I learned a lot from this one.
Viewing 15 posts - 31 through 45 (of 70 total)
You must be logged in to reply to this topic. Login to reply