Help with the Following SQl SP

Thread Solved

Join Date: Mar 2007
Posts: 158
Reputation: vuyiswamb is an unknown quantity at this point 
Solved Threads: 5
vuyiswamb's Avatar
vuyiswamb vuyiswamb is offline Offline
Junior Poster

Help with the Following SQl SP

 
0
  #1
Jun 11th, 2009
Good day All

I have a Challenge. I have the Following StoredProcedure that is doing the Following

  1. IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[temp]'))
  2. DROP TABLE [temp]
  3.  
  4. --Creation of Temp1
  5. SELECT MTN.ID,S.DESCR,ISNULL(MTN.CYCLETEMPLATE,C.CYCLES) AS CYCLETEMPLATE
  6. INTO temp FROM TBL_STAFF S
  7. INNER JOIN MTM_ACTV_STAFF MTN ON
  8. S.ID = MTN.STAFF
  9. LEFT OUTER JOIN tbl_Cycles_Staff C
  10. ON C.IDL = MTN.ID

All this takes less than a second with (17672 row(s) affected)

and its Cool and it Bring records like this

  1. ID DESCR CYCLETEMPLATE
  2. ===============================
  3. 7620 Campbell P Dr 26
  4. 7620 Campbell P Dr 27
  5. 7620 Campbell P Dr 28
  6. 7620 Campbell P Dr 29
  7. 7620 Campbell P Dr 31
  8. 7621 Jones D Dr 23
  9. 7621 Jones D Dr 24
  10. 7621 Jones D Dr 26
  11. 7621 Jones D Dr 28
  12. 7621 Jones D Dr 29
  13. 7621 Jones D Dr 33
  14. 7621 Jones D Dr 34
This is Cool, So now i want to Have one Campbell P Dr wilth all the CycleTemplate Feld on one line and not Duplicated and sepated by a "," So in Simple it Should be like this


  1. ID DESCR CYCLETEMPLATE
  2. ===============================
  3. 7620 Campbell P Dr 26,2728,29,31
  4. 7621 Jones D Dr 23,24,26,28,29,33,34

So to do this i created a user defined function to Remove the Duplicates in a Table Level, the Function looks like this

  1. /*This Userdefined Function is used to Remove Duplicates*/
  2.  
  3. ALTER FUNCTION [dbo].[DistinctList]
  4. (
  5. @List VARCHAR(MAX),
  6. @Delim CHAR
  7. )
  8. RETURNS
  9. VARCHAR(MAX)
  10. AS
  11. BEGIN
  12. DECLARE @ParsedList TABLE
  13. (
  14. Item VARCHAR(MAX)
  15. )
  16. DECLARE @list1 VARCHAR(MAX)
  17. DECLARE @Pos INT
  18. DECLARE @rList VARCHAR(MAX)
  19.  
  20. SET @list = LTRIM(RTRIM(@list)) + @Delim
  21. SET @pos = CHARINDEX(@delim, @list, 1)
  22. WHILE @pos > 0
  23. BEGIN
  24. SET @list1 = LTRIM(RTRIM(LEFT(@list, @pos - 1)))
  25. IF @list1 <> ''
  26. INSERT INTO @ParsedList
  27. VALUES (CAST(@list1 AS VARCHAR(MAX)))
  28. SET @list = SUBSTRING(@list, @pos+1, LEN(@list))
  29. SET @pos = CHARINDEX(@delim, @list, 1)
  30. END
  31. SELECT @rlist = COALESCE(@rlist+',','') + item
  32. FROM (SELECT DISTINCT Item FROM @ParsedList) t
  33. RETURN @rlist
  34. END

And the above function remove the first above mentioned problem and place the cycletemplate like this. Now


  1. ID DESCR CYCLETEMPLATE
  2. ===============================
  3. 7620 Campbell P Dr 26,27,28,29,31,26,26,,28,28
  4. 7621 Jones D Dr 23,24,26,28,29,33,34,34,34,34,34

Now as you can see the Duplicates on the Row level are removed but not the Field level are Still there. So i created the Following User Defined Function that Removes the Duplicates in a Field Level like this

  1. ALTER FUNCTION [dbo].[GetCycle_Timetable] (@Descr Varchar(50))
  2. RETURNS Varchar(500)
  3. AS
  4. BEGIN
  5. Declare @RetStr AS varchar(500)
  6. DECLARE @Cycle Int --<-- Assuming Cycle field is of Type Integer
  7. --Creating a Cursor--
  8. Declare TmpCur Cursor FOR
  9. SELECT CyCleTEMPLATE FROM temp WHERE Descr = @Descr
  10. Open TmpCur --open the cursor
  11. SET @RetStr='' --initialize the string to nothing
  12. Fetch Next
  13. FROM TmpCur INTO @Cycle --take the cycles into the cursor variable
  14. While @@Fetch_status=0
  15. Begin
  16. SET @RetStr = @RetStr +
  17. Case when @RetStr=''
  18. then
  19. '' else
  20. ' ' End
  21. + Cast(@Cycle AS varchar)
  22. Fetch Next FROM TmpCur INTO @Cycle
  23. End
  24. Close TmpCur
  25. Deallocate TmpCur
  26. RETURN (@RetStr)
  27. END

and my sp i conbine this and Call it like this

Select DISTINCT Descr AS [Staff],dbo.DistinctList(.dbo.[GetCycle_Timetable](Descr),'') As [Cycles] 
into Temp2 From temp

and it worked Perfectly and brought desired Results as i shown in the Beginning. Now My Problem with this it Runs for 3 Minutes and in an ASP.net page it times out.

Is there another way that i could have dont this ?

Please Help me with your Example Code by Changing the statement in your way.


Thank you
Few companies that installed computers to reduce the employment of clerks have realized their expectations.... They now need more and more expensive clerks even though they call them "Developers" or "Programmers."
Reply With Quote Quick reply to this message  
Join Date: Apr 2006
Posts: 143
Reputation: cutepinkbunnies is an unknown quantity at this point 
Solved Threads: 8
cutepinkbunnies's Avatar
cutepinkbunnies cutepinkbunnies is offline Offline
Junior Poster

Re: Help with the Following SQl SP

 
0
  #2
Jun 13th, 2009
This may correct the issue if implemented correctly, and at the same time eliminate the need of your functions.

To correct the function and not use an Over Clause, just make sure you search for that particular string/value in the field before you insert into it into the destination column.

And please, try to stay away from cursors at all costs!!
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 3,460
Reputation: sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of 
Solved Threads: 629
Sponsor
sknake's Avatar
sknake sknake is offline Offline
.NET Enthusiast

Re: Help with the Following SQl SP

 
1
  #3
Jun 13th, 2009
Your biggest problem here is that you're calling the function to concat a string in the same query as you're distincting() the records. Lets say you have 5 unique people in the list but a total of 90 records then the function should only run 5 times but in this case it is running 90 times. That means you have an exponentially negative performance impact as your data scales up. I have demonstrated a way to concat a string people don't know about and I tried to set up an accurate test environment. Here you go:

  1. IF OBJECT_ID('People', 'U') IS NOT NULL DROP TABLE People
  2. IF OBJECT_ID('PeopleCycle', 'U') IS NOT NULL DROP TABLE PeopleCycle
  3. IF OBJECT_ID('PeopleJoin', 'U') IS NOT NULL DROP TABLE PeopleJoin
  4. IF OBJECT_ID('Concat', 'FN') IS NOT NULL DROP FUNCTION dbo.CONCAT
  5.  
  6. IF OBJECT_ID('TempDetail', 'U') IS NOT NULL DROP TABLE dbo.TempDetail
  7. IF OBJECT_ID('TempSummary', 'U') IS NOT NULL DROP TABLE dbo.TempSummary
  8.  
  9. GO
  10.  
  11. CREATE TABLE People
  12. (
  13. PeopleId INT identity(1000, 1) PRIMARY KEY NONCLUSTERED,
  14. Name VARCHAR(50),
  15. )
  16.  
  17.  
  18. CREATE TABLE PeopleCycle
  19. (
  20. PeopleCycleId INT identity(1000, 1) PRIMARY KEY NONCLUSTERED,
  21. PeopleId INT NOT NULL,
  22. CycleId INT,
  23. )
  24.  
  25. --This is a useless table to demonstrate the join then distinction
  26. CREATE TABLE PeopleJoin
  27. (
  28. PeopleJoinId INT identity(1000, 1) PRIMARY KEY NONCLUSTERED,
  29. PeopleId INT NOT NULL
  30. )
  31.  
  32.  
  33. GO
  34.  
  35. CREATE FUNCTION dbo.CONCAT (@Name VARCHAR(50))
  36. RETURNS VARCHAR(8000)
  37. WITH EXECUTE AS CALLER
  38. AS
  39. BEGIN
  40.  
  41.  
  42. DECLARE @s VARCHAR(8000)
  43. SET @s = ''
  44.  
  45. SELECT @s = @s + IsNull(',' + Cast(CycleId as VARCHAR), '')
  46. FROM TempDetail (NOLOCK)
  47. WHERE TempDetail.Name = @Name
  48. GROUP BY CycleId
  49. ORDER BY CycleId
  50.  
  51. IF (@S IS NOT NULL) AND (@S <> '') SET @S = SUBSTRING(@s, 2, Len(@S)-1)
  52.  
  53. RETURN @S
  54.  
  55. END
  56.  
  57. GO
  58.  
  59.  
  60. DECLARE @PeopleId INT
  61.  
  62. SET NOCOUNT ON
  63.  
  64. INSERT INTO People (Name) VALUES ('Scott')
  65. SET @PeopleId = Cast(SCOPE_IDENTITY() as INT)
  66. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 1)
  67. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 2)
  68. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 3)
  69. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 4)
  70. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 5)
  71. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 6)
  72. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  73. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  74. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  75. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  76.  
  77. INSERT INTO People (Name) VALUES ('Ken')
  78. SET @PeopleId = Cast(SCOPE_IDENTITY() as INT)
  79. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 7)
  80. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 8)
  81. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 9)
  82. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 10)
  83. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 11)
  84. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 12)
  85. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  86. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  87. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  88. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  89.  
  90. INSERT INTO People (Name) VALUES ('Jake')
  91. SET @PeopleId = Cast(SCOPE_IDENTITY() as INT)
  92. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 13)
  93. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 14)
  94. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 15)
  95. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 16)
  96. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 17)
  97. INSERT INTO PeopleCycle (PeopleId, CycleId) VALUES (@PeopleId, 18)
  98. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  99. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  100. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  101. INSERT INTO PeopleJoin (PeopleId) VALUES (@PeopleId)
  102.  
  103. SET NOCOUNT OFF
  104.  
  105. GO
  106.  
  107. --Create the first table with all the pertinent cycle ids
  108. SELECT Name, CycleId As CycleId
  109. INTO TempDetail
  110. FROM People (NOLOCK) INNER JOIN PeopleJoin (NOLOCK) On (People.PeopleId = PeopleJoin.PeopleId)
  111. INNER JOIN PeopleCycle (NOLOCK) On (People.PeopleId = PeopleCycle.PeopleId)
  112.  
  113.  
  114. --Lets create a summary table. You dont want to do the aggregation on the join because
  115. --it will run for every row that is joined even though you distinct them out later and
  116. --get the same result. That murders performance and doesn't scale.
  117. SELECT Name, Cast(NULL as VARCHAR(8000)) As CycleIdList
  118. INTO TempSummary
  119. FROM TempDetail (NOLOCK)
  120. GROUP BY Name
  121. ORDER BY Name
  122.  
  123. UPDATE TempSummary
  124. SET CycleIdList = dbo.CONCAT(TempSummary.Name)
  125.  
  126. SELECT *
  127. FROM TempSummary (NOLOCK)
  128. ORDER BY Name
Scott Knake
Custom Software Development
Apex Software, Inc.
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 3,460
Reputation: sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of 
Solved Threads: 629
Sponsor
sknake's Avatar
sknake sknake is offline Offline
.NET Enthusiast

Re: Help with the Following SQl SP

 
0
  #4
Jun 13th, 2009
Oh, and the results:
  1. Name CycleIdList
  2. ------ ------------------
  3. Jake 13,14,15,16,17,18
  4. Ken 7,8,9,10,11,12
  5. Scott 1,2,3,4,5,6
Scott Knake
Custom Software Development
Apex Software, Inc.
Reply With Quote Quick reply to this message  
Join Date: Mar 2007
Posts: 158
Reputation: vuyiswamb is an unknown quantity at this point 
Solved Threads: 5
vuyiswamb's Avatar
vuyiswamb vuyiswamb is offline Offline
Junior Poster

Re: Help with the Following SQl SP

 
0
  #5
Jun 15th, 2009
This is the Best Answer i have ever got from Daniweb. Am a C#,ASP.NEt Programmer and do a lot of SQL but never went this deep, and most of the time am the one helping others and i needed help and this is the Best answer i have ever got from this Forum.

Thank you and its working like charm

Kind Regards

Vuyiswa Maseko
Few companies that installed computers to reduce the employment of clerks have realized their expectations.... They now need more and more expensive clerks even though they call them "Developers" or "Programmers."
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the MS SQL Forum


Views: 601 | Replies: 4
Thread Tools Search this Thread



Tag cloud for MS SQL
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC