Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
barlowr70
Starting Member
1 Post |
Posted - 2003-08-26 : 06:25:32
|
| I need to produce a report that involves currency conversion. All Report costs need to be reported in Dollars. What I've done is create a temporary table to hold the values, which are Spend, Save and ProjSave. I then set up a cursor to pick up the actual values. I loop through the records. If the Currency is dollars I update all values, otherwise I set up another loop and pass the currency values and the loop counter to another procedure that returns the converted values, then depending on the counter value I update a single field in the Temp table, but I'm having a problem with the second loop, it's falling over and terminating the outer loop also. I've included the code below. Many Thanks.CREATE PROCEDURE dbo.spConversionTestAS BEGINSET NOCOUNT ON--Step one: create a temp table to hold the results of your querycreate table #DollarValues (P_ID int not null, AnnualSave float, AnnualSpend float, ProjAnnualSave float)--step two: Populate temp table with the ID of each Project. INSERT #DollarValues (P_ID)SELECT p.ProjIDFROM tblProjects AS pDeclare @lngProject intDeclare @Currency varchar(5)Declare @dblAnnualSave floatDeclare @dblAnnualSpend floatDeclare @dblProjAnnualSave floatDeclare @dblUSD floatDeclare @dblGBP floatDeclare @varDate datetimeDeclare @myValue floatDeclare @intCounter intDeclare curs1 Cursor FOR SELECT p.ProjID, p.ProjCurrency, p.ExpectedAnnualSaving, p.AnnualSpend,p.ProjectedAnnualSavingFROM tblProjects AS pOPEN curs1FETCH NEXT FROM curs1 INTO @lngProject, @Currency, @dblAnnualSave, @dblAnnualSpend, @dblProjAnnualSave--Start Loop WHILE @@fetch_status = 0 BEGIN--Move to Next RecordFETCH NEXT FROM curs1 INTO @lngProject, @Currency, @dblAnnualSave, @dblAnnualSpend, @dblProjAnnualSaveUPDATE #DollarValuesSET AnnualSave=@dblAnnualSave, AnnualSpend=@dblAnnualSpend, ProjAnnualSave=@dblProjAnnualSaveWHERE P_ID = @lngProject--If the Currency is Dollars append all Values to Temp TableIF @Currency ='USD' --Append Values to Temp TableUPDATE #DollarValuesSET AnnualSave = @dblAnnualSave, AnnualSpend=@dblAnnualSpend, ProjAnnualSave=@dblProjAnnualSaveWHERE P_ID = @lngProject--If the Currency is not Dollars--**** PROBLEM AREA ****ELSE IF @Currency !='USD' SET @intCounter=0--Start Loop, I'm having a problem with this loop and it sets the @@fetch_status to 0--I need to take the cursor variables and pass them to the dbo.spConversionValue procedure WHILE @intCounter < 3 BEGINDECLARE @dblConversion floatEXEC dbo.spConversionValue @dblConversion OUTPUT, @intCounter, @Currency, @dblAnnualSave, @dblAnnualSpend, @dblProjAnnualSave--Depending on the Counter value updaet a field in the Temp Tableif @intCounter = 1 --Annual SavingUPDATE #DollarValues SET AnnualSave = @dblConversion WHERE P_ID = @lngProjectelse if @intCounter = 2 --Annual SpendUPDATE #DollarValues SET AnnualSpend = @dblConversion WHERE P_ID = @lngProjectelse if @intCounter = 3 --Projected SavingUPDATE #DollarValues SET ProjAnnualSave = @dblConversion WHERE P_ID = @lngProject--Increment the CounterSet @intCounter=@intCounter+1END--**** END PROBLEM AREA ****ENDENDCLOSE curs1DEALLOCATE curs1select * from #DollarValues |
|
|
mohdowais
Sheikh of Yak Knowledge
1456 Posts |
Posted - 2003-08-26 : 07:46:43
|
I have a couple of comments before I get to the problem area. Firstly, look at the following snippet of your code. FETCH NEXT FROM curs1 INTO @lngProject, @Currency, @dblAnnualSave, @dblAnnualSpend, @dblProjAnnualSaveUPDATE #DollarValuesSET AnnualSave=@dblAnnualSave, AnnualSpend=@dblAnnualSpend, ProjAnnualSave=@dblProjAnnualSaveWHERE P_ID = @lngProject--If the Currency is Dollars append all Values to Temp TableIF @Currency ='USD' --Append Values to Temp TableUPDATE #DollarValuesSET AnnualSave = @dblAnnualSave, AnnualSpend=@dblAnnualSpend, ProjAnnualSave=@dblProjAnnualSaveWHERE P_ID = @lngProject You are running the same update statement before the IF statement, and when the currency is USD. You could easily get rid of the one inside the IF statement.Secondly, for the first condition (Currency = USD), you dont need a cursor at all, you can accomplish this with a simple UPDATE...INNER JOIN statement:UPDATE d SET AnnualSave = p.ExpectedAnnualSaving, AnnualSpend = p.AnnualSpend, ProjAnnualSave = p.ProjectedAnnualSavingFROM #DollarValues d INNER JOIN tblProjects pON d.P_ID = p.P_IDAND p.ProjCurrency = 'USD' After having run the above code, you'll be left with only the non-USD records to deal with. Here you might need a cursor to invoke the stored procedure for each row.I am wondering why you have a 1-3 loop to get three values out of the stored proc. Can you re-write your procedure to return all the three values as output parameters, so they can be obtained in a single call to the proc?Owais Make it idiot proof and someone will make a better idiot |
 |
|
|
TSQLMan
Posting Yak Master
160 Posts |
Posted - 2003-08-27 : 14:25:34
|
For this project cursors are a waste of keystrokes. #TemporaryTables are much better peformers. The advice already given will work well, so I won't re hash. I used to use cursors, because I thought it would show my skill. I now, very rarely find a need to use cursors, except with app development. quote: Originally posted by barlowr70 I need to produce a report that involves currency conversion. All Report costs need to be reported in Dollars. What I've done is create a temporary table to hold the values, which are Spend, Save and ProjSave. I then set up a cursor to pick up the actual values. I loop through the records. If the Currency is dollars I update all values, otherwise I set up another loop and pass the currency values and the loop counter to another procedure that returns the converted values, then depending on the counter value I update a single field in the Temp table, but I'm having a problem with the second loop, it's falling over and terminating the outer loop also. I've included the code below. Many Thanks.CREATE PROCEDURE dbo.spConversionTestAS BEGINSET NOCOUNT ON--Step one: create a temp table to hold the results of your querycreate table #DollarValues (P_ID int not null, AnnualSave float, AnnualSpend float, ProjAnnualSave float)--step two: Populate temp table with the ID of each Project. INSERT #DollarValues (P_ID)SELECT p.ProjIDFROM tblProjects AS pDeclare @lngProject intDeclare @Currency varchar(5)Declare @dblAnnualSave floatDeclare @dblAnnualSpend floatDeclare @dblProjAnnualSave floatDeclare @dblUSD floatDeclare @dblGBP floatDeclare @varDate datetimeDeclare @myValue floatDeclare @intCounter intDeclare curs1 Cursor FOR SELECT p.ProjID, p.ProjCurrency, p.ExpectedAnnualSaving, p.AnnualSpend,p.ProjectedAnnualSavingFROM tblProjects AS pOPEN curs1FETCH NEXT FROM curs1 INTO @lngProject, @Currency, @dblAnnualSave, @dblAnnualSpend, @dblProjAnnualSave--Start Loop WHILE @@fetch_status = 0 BEGIN--Move to Next RecordFETCH NEXT FROM curs1 INTO @lngProject, @Currency, @dblAnnualSave, @dblAnnualSpend, @dblProjAnnualSaveUPDATE #DollarValuesSET AnnualSave=@dblAnnualSave, AnnualSpend=@dblAnnualSpend, ProjAnnualSave=@dblProjAnnualSaveWHERE P_ID = @lngProject--If the Currency is Dollars append all Values to Temp TableIF @Currency ='USD' --Append Values to Temp TableUPDATE #DollarValuesSET AnnualSave = @dblAnnualSave, AnnualSpend=@dblAnnualSpend, ProjAnnualSave=@dblProjAnnualSaveWHERE P_ID = @lngProject--If the Currency is not Dollars--**** PROBLEM AREA ****ELSE IF @Currency !='USD' SET @intCounter=0--Start Loop, I'm having a problem with this loop and it sets the @@fetch_status to 0--I need to take the cursor variables and pass them to the dbo.spConversionValue procedure WHILE @intCounter < 3 BEGINDECLARE @dblConversion floatEXEC dbo.spConversionValue @dblConversion OUTPUT, @intCounter, @Currency, @dblAnnualSave, @dblAnnualSpend, @dblProjAnnualSave--Depending on the Counter value updaet a field in the Temp Tableif @intCounter = 1 --Annual SavingUPDATE #DollarValues SET AnnualSave = @dblConversion WHERE P_ID = @lngProjectelse if @intCounter = 2 --Annual SpendUPDATE #DollarValues SET AnnualSpend = @dblConversion WHERE P_ID = @lngProjectelse if @intCounter = 3 --Projected SavingUPDATE #DollarValues SET ProjAnnualSave = @dblConversion WHERE P_ID = @lngProject--Increment the CounterSet @intCounter=@intCounter+1END--**** END PROBLEM AREA ****ENDENDCLOSE curs1DEALLOCATE curs1select * from #DollarValues
|
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-08-27 : 15:26:49
|
| Do me a favor: give us some sample data and the table structure you are starting with, and then what you hope to return. Forget about how you are currently solving the problem; just tell us what calculations you need to make and what results you are looking to return.For example:create table foo (f1,f2,f3)insert into foo values (1,2,3)insert into foo values (4,5,6)insert into foo values (7,8,9)I would like to return the sum of all columns:f1,f2,f312,15,18---then, I have a feeling you will get a really quick and efficient solution not using temp tables, cursors, or loops of any kind.- Jeff |
 |
|
|
|
|
|
|
|