August 22, 2005 at 8:49 am
For some reason, this did not post. I'll try again.
I found something that was simple enough to deal with the issue of a cursor, but also would not compromise releasing any data. I have changed some of the names of fields, but others are common enough that I simply left them as is...
Basically, the #Final table 'can' have a large amount of records dealing with a lot of money. This particular cursor shows international codes and percentages, but I was able to find one that did not have the added difficulty of prorating the percentages - that gets real messy...
The #Intl1 table should be fairly self explanatory.
Fortunately, the various codes are simply concatenated into one column, so that should make using this as an example much easier!
Thanks for your help. Hopefully your solution(s) are something we can use in other areas of our coding as well!!
-- International Codes and Percentages...
SELECT C.Country_Name, i.id_intl, i.special_id, i.country_code, i.pct, i.intl_marker
INTO #intl1
FROM tb_intl i
LEFT JOIN Countries C ON( i.country_code = C.NIH_State_Country_Code)
CREATE CLUSTERED INDEX [CIX_id_intl_award] ON [#intl1]( [id_intl], [special_id] )
----------------------------------------------------------------------------------
-- This needs to be a cursor as a special_id can have many International Codes...
DECLARE int_csr CURSOR FAST_FORWARD FOR
SELECT i.id_intl
FROM #intl1 i
INNER JOIN #final f ON( i.special_id = f.special_id)
GROUP BY i.id_intl
ORDER BY i.id_intl
OPEN int_csr
FETCH int_csr INTO @id_intl
WHILE @@fetch_status = 0
BEGIN
UPDATE #final SET
intl_codes1 = ISNULL( f.intl_codes1, '') + ' ' +
CONVERT( varchar, ISNULL( i.country_code, '')) +
' ' + ISNULL( i.country_name, '') + ' ' +
CONVERT( varchar, ISNULL( i.pct, '')) + ' ' +
CONVERT( varchar, ISNULL( i.intl_marker, ''))
FROM #final f
INNER JOIN #intl1 i ON( f.special_id = i.special_id
AND i.id_intl = @id_intl)
FETCH int_csr INTO @id_intl
END
CLOSE int_csr
DEALLOCATE int_csr
I will check as often as I can on your replies! If you need more information, I will provide what I can.
Farrell
I wasn't born stupid - I had to study.
August 22, 2005 at 8:55 am
Can't convert it without sample data and expected results to make sure we're ok.
August 22, 2005 at 9:00 am
Crap! I knew I should have done that... That will take me a bit of time, (and that is where I have to make sure I do not release any real data...).
Sorry for such a novice mistake. I will get back to this...
I wasn't born stupid - I had to study.
August 22, 2005 at 9:04 am
there's a script to generate the insert statements :
August 22, 2005 at 11:22 am
This is very down and dirty, but it gets the point across. I realized special_id could be used instead of id_intl, but there are other Business Rules, (you will note some problems in comments for the INSERTs) that I chose not to include.
Again, thanks in advance...
DECLARE @id_intl integer
CREATE TABLE #Final( special_id integer,
intl_codes1 varchar(255))
INSERT INTO #Final VALUES( 1, '')
INSERT INTO #Final VALUES( 2, '')
INSERT INTO #Final VALUES( 3, '')
INSERT INTO #Final VALUES( 4, '')
INSERT INTO #Final VALUES( 5, '')
INSERT INTO #Final VALUES( 6, '')
INSERT INTO #Final VALUES( 7, '')
INSERT INTO #Final VALUES( 8, '')
INSERT INTO #Final VALUES( 9, '')
INSERT INTO #Final VALUES( 10, '')
-- International Codes and Percentages...
-- I cannot change the design of these tables...
CREATE TABLE #intl1( id_intl integer IDENTITY(1,1),
Country_Name varchar(80),
special_id integer,
country_code integer,
pct integer,
intl_marker integer)
INSERT INTO #intl1 VALUES( 'Nigeria', 1, 495, 20, 4)
INSERT INTO #intl1 VALUES( 'USA', 1, 395, 50, 3)
INSERT INTO #intl1 VALUES( 'Mexico', 1, 295, 35, 3)
-- this will exceed 100% - this record is an example of one of our
-- proration difficulties; but not for this excercise, just and example...
INSERT INTO #intl1 VALUES( 'Nigeria', 2, 495, 80, 5)
-- this will only have one intl_codes1 (80% is acceptable...)
INSERT INTO #intl1 VALUES( 'USA', 3, 395, 20, 4)
INSERT INTO #intl1 VALUES( 'Nigeria', 3, 495, 20, 4)
INSERT INTO #intl1 VALUES( 'Nigeria', 3, 495, 50, 3)
-- another issue not dealt with in this exercise, (choosing one of
-- multiple records...)
INSERT INTO #intl1 VALUES( 'Mexico', 4, 295, 50, 4)
INSERT INTO #intl1 VALUES( 'USA', 4, 395, 50, 6)
-- this will amount to required 100%
-- special_id #5 will have no intl_codes1
INSERT INTO #intl1 VALUES( 'Puerto Rico', 6, 195, 20, 4)
INSERT INTO #intl1 VALUES( 'Mexico', 6, 295, 20, 5)
INSERT INTO #intl1 VALUES( 'El Salvador', 6, 595, 20, 6)
INSERT INTO #intl1 VALUES( 'Venezuela', 6, 695, 20, 3)
INSERT INTO #intl1 VALUES( 'USA', 6, 395, 10, 4)
INSERT INTO #intl1 VALUES( 'Chile', 6, 795, 20, 2)
-- again, over 100%
INSERT INTO #intl1 VALUES( 'Nigeria', 7, 495, 20, 2)
INSERT INTO #intl1 VALUES( 'Tanzania', 7, 895, 80, 3)
-- this will amount to required 100%
INSERT INTO #intl1 VALUES( 'Canada', 8, 995, 25, 1)
INSERT INTO #intl1 VALUES( 'USA', 8, 395, 25, 2)
INSERT INTO #intl1 VALUES( 'Russia', 8, 95, 25, 3)
INSERT INTO #intl1 VALUES( 'Antartica', 8, 550, 25, 4)
-- this will amount to required 100%
INSERT INTO #intl1 VALUES( 'Nigeria', 9, 495, 100, 4)
-- this will only have one intl_codes1
INSERT INTO #intl1 VALUES( 'China', 10, 495, 20, 6)
INSERT INTO #intl1 VALUES( 'Unknown', 10, 1, 20, 6)
INSERT INTO #intl1 VALUES( 'Tiawan', 10, 25, 20, 5)
INSERT INTO #intl1 VALUES( 'Japan', 10, 26, 20, 5)
INSERT INTO #intl1 VALUES( 'Tunisia', 10, 27, 20, 4)
CREATE CLUSTERED INDEX [CIX_id_intl_award] ON [#intl1]( [id_intl], [special_id] )
----------------------------------------------------------------------------------
-- This needs to be a cursor as a special_id can have many International Codes...
DECLARE int_csr CURSOR FAST_FORWARD FOR
SELECT i.id_intl
FROM #intl1 i
INNER JOIN #final f ON( i.special_id = f.special_id)
GROUP BY i.id_intl
ORDER BY i.id_intl
OPEN int_csr
FETCH int_csr INTO @id_intl
WHILE @@fetch_status = 0
BEGIN
UPDATE #final SET
intl_codes1 = ISNULL( f.intl_codes1, '') + ' ' +
CONVERT( varchar, ISNULL( i.country_code, '')) + ' ' +
ISNULL( i.country_name, '') + ' ' +
CONVERT( varchar, ISNULL( i.pct, '')) + ' ' +
CONVERT( varchar, ISNULL( i.intl_marker, ''))
FROM #final f
INNER JOIN #intl1 i ON( f.special_id = i.special_id
AND i.id_intl = @id_intl)
FETCH int_csr INTO @id_intl
END
CLOSE int_csr
DEALLOCATE int_csr
SELECT special_id, intl_codes1 FROM #Final
DROP TABLE #Final
DROP TABLE #intl1
/* EXPECTED OUTPUT
special_id intl_codes1
------------------------------ -----------------------------------------------------------------------------------------------------------------------------
1 495 Nigeria 20 4 395 USA 50 3 295 Mexico 35 3
2 495 Nigeria 80 5
3 395 USA 20 4 495 Nigeria 20 4 495 Nigeria 50 3
4 295 Mexico 50 4 395 USA 50 6
5
6 195 Puerto Rico 20 4 295 Mexico 20 5 595 El Salvador 20 6 695 Venezuela 20 3 395 USA 10 4 795 Chile 20 2
7 495 Nigeria 20 2 895 Tanzania 80 3
8 995 Canada 25 1 395 USA 25 2 95 Russia 25 3 550 Antartica 25 4
9 495 Nigeria 100 4
10 495 China 20 6 1 Unknown 20 6 25 Tiawan 20 5 26 Japan 20 5 27 Tunisia 20 4
*/
I wasn't born stupid - I had to study.
August 22, 2005 at 2:02 pm
Farrell, I've shown this trick so many times I'm surprised you didn't pick it up yet >>>
IF Object_id('ListTableColumns') > 0
DROP FUNCTION ListTableColumns
GO
CREATE FUNCTION dbo.ListTableColumns (@TableID as int)
RETURNS varchar(8000)
AS
BEGIN
Declare @Items as varchar(8000)
SET @Items = ''
SELECT
@Items = @Items + C.Name + ', '
FROMdbo.SysColumns C
WHEREC.id = @TableID
AND OBJECTPROPERTY(@TableID, 'IsTable') = 1
ORDER BYC.Name
SET @Items = LEFT(@Items, ABS(DATALENGTH(@Items) - 2))
RETURN @Items
END
GO
Select dbo.ListTableColumns(Object_id('SysObjects'))
--base_schema_ver, cache, category, crdate, deltrig, ftcatid, id, indexdel, info, instrig, name, parent_obj, refdate, replinfo, schema_ver, seltrig, stats_schema_ver, status, sysstat, type, uid, updtrig, userstat, version, xtype
DROP FUNCTION ListTableColumns
Just convert that fonction to do the concatenation work and you'll be home free WITHOUT temp tables or loops.
August 22, 2005 at 2:45 pm
Thanks. I knew I should have taken the time to include the other processes.
There are a lot of business rules and I cannot really go into them all; in other words, this is really not just concatenating records... I will see how I can incorporate this approach as I use functions in other areas and really like their use.
But, don't you still end up with the same amount of calls back and fourth to capture all of the records for each row? That is one part of this that I do not fully understand...
I wasn't born stupid - I had to study.
August 22, 2005 at 2:48 pm
It's less efficiant than a single select, but it still takes less ressources than updating a temp table for every occurance of every row and then reselecting the temp table.
August 22, 2005 at 2:51 pm
That's a worthwhile trade off. Thanks.
I wasn't born stupid - I had to study.
August 22, 2005 at 2:53 pm
Yup this code really deals more with reporting problems than basic sql operations.
August 22, 2005 at 5:41 pm
Sorry its not more exciting...
I wasn't born stupid - I had to study.
August 22, 2005 at 11:13 pm
Governement is not meant to be entertaining .
August 23, 2005 at 8:24 am
LOL. Excellent response.
I wasn't born stupid - I had to study.
Viewing 13 posts - 1 through 12 (of 12 total)
You must be logged in to reply to this topic. Login to reply