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 |
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-19 : 22:55:42
|
I am trying to implement a program by using the cursor. From some reason it does not recognize my declare statement @wScenarioName. "The error 170 line 31: Incorrect syntax near '@wScenarioName: Must declare variable @wScenarioName"Hoping someone might be able to look at the attached code (I only included partial for simplcity purposes) and see why I may be receiving the error. Thought a 2nd pair of eyes might help. Thanks for your time in advance. CREATE PROCEDURE [SOE_SCENARIOS] ASgo------------------------------------------------------------------------- Declare variable step 1 & 3 will read for the filename -- and the scenario name it will save ---------------------------------------------------------------------BEGINDECLARE @wScenarioName Varchar(50)DECLARE cur CURSOR FOR SELECT scenario_name FROM ScenariosToRunOPEN curFETCH NEXT FROM cur INTO @wScenarioNameWHILE @@fetch_status = 0 BEGIN ------------------------------------ -- Step 1: -- Creates SOEbyProduct table ------------------------------------ IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'SOEbyProduct') and OBJECTPROPERTY(id, N'IsUserTable') = 1) Begin create table SOEbyProduct ( Scenario char(20), Product char(50), BankName char(50), SumOfNotional float, SumOfAvgBal float, SumOfEOPBal float, SumOfIntCF float, SumOfAmortCF float, SumOfPrepayCF float, SumOfPrinCF float, SumOfAddAmt float, SumOfFTEIncome float,AvgAccruedInt float, AvgYield float, AvgPeriodCap float, AvgCap float, AvgFloor float, AvgPriceRateBase float, AvgRepriceSpread float , AvgRepriceRate float) CREATE INDEX SoeID_IDX on @wScenarioName (AccountID) -- CREATE INDEX SoeID_IDX on soebasecase (AccountID) End ELSE Truncate TABLE SOEbyProduct ----------------------------------------------------------------------------- -- Step2: -- -- CREATES a TEMPORY table for the CvgWriteOut_Account table -- so that it can PARSE out the AccountName to obtain product & bankname ------------------------------------------------------------------------------ IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'Parsed_CVGWriteOut') and OBJECTPROPERTY(id, N'IsUserTable') = 1) Begin create table Parsed_CVGWriteout ( [w_id] int, Scenid int, Product char(50), BankName char(50) ) CREATE INDEX ParseID_IDX on Parsed_CVGWriteout(w_id); END ELSE Truncate TABLE SOEbyProduct Insert into Parsed_CVGWriteOut ([w_id],scenid,product,bankname) select [id],scenid, --these would also work if function failed at some point - keep in here --replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),2),'#~@','.') as dimension, --replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),3),'#~@','.') as bank, --replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),4),'#~@','.') as product DBO.GetStringAtPos(AccountName,':',1 ), DBO.GetStringAtPos(AccountName,':',2 ) from dbo.CvgWriteOut_Accounts as w ------------------------------------------------------------------------------------------ -- Step3: -- -- Performs match b/w the above 2 files and create a sum/wavg file called SOEbyProduct -- ------------------------------------------------------------------------------------------- INSERT INTO SOEbyProduct (Scenario, Product, BankName, SumOfNotional, SumOfAvgBal, SumOfEOPBal, SumOfIntCF, sumOfAmortCF, SumOfPrepayCF, SumOfPrinCF, SumOfAddAmt, SumOfFTEIncome, AvgAccruedInt, AvgYield, AvgPeriodCap, AvgCap, AvgFloor, AvgPriceRateBase, AvgRepriceSpread, AvgRepriceRate) SELECT 'wScenarioName' as Scenario, Product, BankName, sum(s.notional) as SumOfNotional, sum(s.avgbal) as SumOfAvgBal, sum(s.eopbal) as SumOfEOPBAL, sum(s.Intcf) as SumOfIntCF, sum(s.amortCF) as SumOfAmortCF, sum(s.prepaycf) as SumOfPrepayCF, sum(s.princf) as SumofPrinCF, -- if null value in field replaces it with 0.0 since floating, otherwise if int would have used 0 sum (coalesce(s.addamt,0.0)) as SumAddamt, sum(coalesce(s.FTEIncome,0.0)) as SumofFTEIncome, sum(s.[accruedint]*s.[eopbal])/NULLIF(sum(s.[eopbal]),0.0) as AvgAccruedInt, sum(coalesce(s.[avgyld],0.0)*s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgYield, sum(s.[PeriodicCap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPeriodCap, sum(s.[Cap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgCap, sum(s.[Floor] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgFloor, sum(s.[ReprRateBase] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPriceRateBase, sum(s.[ReprRateAvgAdj] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceSpread, sum(s.[ReprRate] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceRate --from SOEBasecase as s JOIN dbo.Parsed_CVGWriteOut as W --on w.[w_id]=s.accountid from Parsed_CVGWriteout as w inner JOIN @wScenarioName as s on w.[w_id]=s.accountid group by PRODUCT,BANKNAME,S.SCENDATEINDEX FETCH NEXT FROM CUR INTO @WscenarionameENDCLOSE curDEALLOCATE curEND |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-19 : 23:50:57
|
| The code is incorrect .CREATE PROCEDURE [SOE_SCENARIOS] ASgo------------------------------------------------------------------------- Declare variable step 1 & 3 will read for the filename -- and the scenario name it will save ---------------------------------------------------------------------BEGINDECLARE @wScenarioName Varchar(50)DECLARE cur CURSOR FOR SELECT scenario_name FROM ScenariosToRunOPEN curFETCH NEXT FROM cur INTO @wScenarioNameWHILE @@fetch_status = 0 BEGIN ------------------------------------ -- Step 1: -- Creates SOEbyProduct table ------------------------------------ IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'SOEbyProduct') and OBJECTPROPERTY(id, N'IsUserTable') = 1) Begin create table SOEbyProduct ( Scenario char(20), Product char(50), BankName char(50), SumOfNotional float, SumOfAvgBal float, SumOfEOPBal float, SumOfIntCF float, SumOfAmortCF float, SumOfPrepayCF float, SumOfPrinCF float, SumOfAddAmt float, SumOfFTEIncome float,AvgAccruedInt float, AvgYield float, AvgPeriodCap float, AvgCap float, AvgFloor float, AvgPriceRateBase float, AvgRepriceSpread float , AvgRepriceRate float) CREATE INDEX SoeID_IDX on soebasecase (AccountID) --Index can only be created on tables or views but not on variable. End ELSE Truncate TABLE SOEbyProduct ----------------------------------------------------------------------------- -- Step2: -- -- CREATES a TEMPORY table for the CvgWriteOut_Account table -- so that it can PARSE out the AccountName to obtain product & bankname ------------------------------------------------------------------------------ IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'Parsed_CVGWriteOut') and OBJECTPROPERTY(id, N'IsUserTable') = 1) Begin create table Parsed_CVGWriteout ( [w_id] int, Scenid int, Product char(50), BankName char(50) ) CREATE INDEX ParseID_IDX on Parsed_CVGWriteout(w_id); END ELSE Truncate TABLE SOEbyProduct Insert into Parsed_CVGWriteOut ([w_id],scenid,product,bankname) select [id],scenid, --these would also work if function failed at some point - keep in here --replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),2),'#~@','.') as dimension, --replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),3),'#~@','.') as bank, --replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),4),'#~@','.') as product DBO.GetStringAtPos(AccountName,':',1 ), DBO.GetStringAtPos(AccountName,':',2 ) from dbo.CvgWriteOut_Accounts as w ------------------------------------------------------------------------------------------ -- Step3: -- -- Performs match b/w the above 2 files and create a sum/wavg file called SOEbyProduct -- ------------------------------------------------------------------------------------------- INSERT INTO SOEbyProduct (Scenario, Product, BankName, SumOfNotional, SumOfAvgBal, SumOfEOPBal, SumOfIntCF, sumOfAmortCF, SumOfPrepayCF, SumOfPrinCF, SumOfAddAmt, SumOfFTEIncome, AvgAccruedInt, AvgYield, AvgPeriodCap, AvgCap, AvgFloor, AvgPriceRateBase, AvgRepriceSpread, AvgRepriceRate) SELECT 'wScenarioName' as Scenario, Product, BankName, sum(s.notional) as SumOfNotional, sum(s.avgbal) as SumOfAvgBal, sum(s.eopbal) as SumOfEOPBAL, sum(s.Intcf) as SumOfIntCF, sum(s.amortCF) as SumOfAmortCF, sum(s.prepaycf) as SumOfPrepayCF, sum(s.princf) as SumofPrinCF, -- if null value in field replaces it with 0.0 since floating, otherwise if int would have used 0 sum (coalesce(s.addamt,0.0)) as SumAddamt, sum(coalesce(s.FTEIncome,0.0)) as SumofFTEIncome, sum(s.[accruedint]*s.[eopbal])/NULLIF(sum(s.[eopbal]),0.0) as AvgAccruedInt, sum(coalesce(s.[avgyld],0.0)*s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgYield, sum(s.[PeriodicCap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPeriodCap, sum(s.[Cap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgCap, sum(s.[Floor] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgFloor, sum(s.[ReprRateBase] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPriceRateBase, sum(s.[ReprRateAvgAdj] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceSpread, sum(s.[ReprRate] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceRate --from SOEBasecase as s JOIN dbo.Parsed_CVGWriteOut as W --on w.[w_id]=s.accountid from Parsed_CVGWriteout as w inner JOIN @wScenarioName as s -- @wScenarioName is a variable. You cannot join the variable on w.[w_id]=s.accountid group by PRODUCT,BANKNAME,S.SCENDATEINDEX FETCH NEXT FROM CUR INTO @WscenarionameENDCLOSE curDEALLOCATE curEND |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-19 : 23:59:44
|
| Try this:CREATE PROCEDURE [SOE_SCENARIOS] AS------------------------------------------------------------------------- Declare variable step 1 & 3 will read for the filename -- and the scenario name it will save ---------------------------------------------------------------------BEGINDECLARE @wScenarioName Varchar(50)DECLARE @sqlStmt Varchar(Max)DECLARE cur CURSOR FOR SELECT scenario_name FROM ScenariosToRunOPEN curFETCH NEXT FROM cur INTO @wScenarioNameWHILE @@fetch_status = 0BEGIN-------------------------------------- Step 1: -- Creates SOEbyProduct table------------------------------------IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'SOEbyProduct')and OBJECTPROPERTY(id, N'IsUserTable') = 1)Begincreate table SOEbyProduct (Scenario char(20), Product char(50), BankName char(50), SumOfNotional float, SumOfAvgBal float, SumOfEOPBal float, SumOfIntCF float, SumOfAmortCF float, SumOfPrepayCF float, SumOfPrinCF float, SumOfAddAmt float, SumOfFTEIncome float,AvgAccruedInt float, AvgYield float, AvgPeriodCap float, AvgCap float, AvgFloor float, AvgPriceRateBase float, AvgRepriceSpread float , AvgRepriceRate float)Exec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)')EndELSETruncate TABLE SOEbyProduct------------------------------------------------------------------------------- Step2: ---- CREATES a TEMPORY table for the CvgWriteOut_Account table -- so that it can PARSE out the AccountName to obtain product & bankname------------------------------------------------------------------------------IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'Parsed_CVGWriteOut')and OBJECTPROPERTY(id, N'IsUserTable') = 1)Begincreate table Parsed_CVGWriteout ( [w_id] int,Scenid int,Product char(50),BankName char(50) )CREATE INDEX ParseID_IDX on Parsed_CVGWriteout(w_id);ENDELSETruncate TABLE SOEbyProductInsert into Parsed_CVGWriteOut([w_id],scenid,product,bankname)select [id],scenid,--these would also work if function failed at some point - keep in here--replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),2),'#~@','.') as dimension,--replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),3),'#~@','.') as bank,--replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),4),'#~@','.') as productDBO.GetStringAtPos(AccountName,':',1 ),DBO.GetStringAtPos(AccountName,':',2 ) from dbo.CvgWriteOut_Accounts as w-------------------------------------------------------------------------------------------- Step3: -- -- Performs match b/w the above 2 files and create a sum/wavg file called SOEbyProduct -- -------------------------------------------------------------------------------------------set @sqlStmt = 'INSERT INTO SOEbyProduct(Scenario, Product, BankName,SumOfNotional, SumOfAvgBal, SumOfEOPBal, SumOfIntCF, sumOfAmortCF, SumOfPrepayCF, SumOfPrinCF, SumOfAddAmt, SumOfFTEIncome, AvgAccruedInt, AvgYield, AvgPeriodCap, AvgCap, AvgFloor, AvgPriceRateBase, AvgRepriceSpread, AvgRepriceRate)SELECT ''wScenarioName'' as Scenario,Product,BankName,sum(s.notional) as SumOfNotional,sum(s.avgbal) as SumOfAvgBal,sum(s.eopbal) as SumOfEOPBAL,sum(s.Intcf) as SumOfIntCF,sum(s.amortCF) as SumOfAmortCF,sum(s.prepaycf) as SumOfPrepayCF,sum(s.princf) as SumofPrinCF,-- if null value in field replaces it with 0.0 since floating, otherwise if int would have used 0sum (coalesce(s.addamt,0.0)) as SumAddamt,sum(coalesce(s.FTEIncome,0.0)) as SumofFTEIncome,sum(s.[accruedint]*s.[eopbal])/NULLIF(sum(s.[eopbal]),0.0) as AvgAccruedInt,sum(coalesce(s.[avgyld],0.0)*s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgYield,sum(s.[PeriodicCap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPeriodCap,sum(s.[Cap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgCap,sum(s.[Floor] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgFloor,sum(s.[ReprRateBase] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPriceRateBase,sum(s.[ReprRateAvgAdj] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceSpread,sum(s.[ReprRate] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceRate--from SOEBasecase as s JOIN dbo.Parsed_CVGWriteOut as W --on w.[w_id]=s.accountidfrom Parsed_CVGWriteout as w inner JOIN ' + @wScenarioName +' as s on w.[w_id]=s.accountidgroup by PRODUCT,BANKNAME,S.SCENDATEINDEX'--Print @sqlStmtExec (@sqlStmt)FETCH NEXT FROM CUR INTO @WscenarionameENDCLOSE curDEALLOCATE curENDRegards,BohraI am here to learn from Masters and help new bees in learning. |
 |
|
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-20 : 09:56:34
|
| Hi Bohra,Thank you for your feedback. I implemented your suggestion and ran into a small issue with step3 where it states SELECT 'wScenarioName' as Scenario. This actually stores the value of 'wScenarioName', what I really need it to store is thevalue in the scenario_name field that it is reading from the ScenariosToRun table. I guess it is the same value as what is stored in the @wScenarioName. How can I do this? --------------------My overall thought process was to use the cursor so that I maybe able to execute the program numerous times, each time referencing a different table (same structure). I just did not want to have to repeat the logic 40+ time. The tablenames it needs to run each time are stored in the 'ScenariosToRun' table within the 'scenario_name' field. The value of this field is also storedin step3 Select .... as Scenario line. Maybe there is a quicker and better way? My apologies for my ignorance on this. Your help is greatly appreciate. Regards, cirugio |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-20 : 23:33:17
|
quote: Originally posted by cirugio Hi Bohra,Thank you for your feedback. I implemented your suggestion and ran into a small issue with step3 where it states SELECT 'wScenarioName' as Scenario. This actually stores the value of 'wScenarioName', what I really need it to store is thevalue in the scenario_name field that it is reading from the ScenariosToRun table. I guess it is the same value as what is stored in the @wScenarioName. How can I do this?
ReplaceSELECT 'wScenarioName' as Scenario,with SELECT @wScenarioName as Scenario,quote: --------------------My overall thought process was to use the cursor so that I maybe able to execute the program numerous times, each time referencing a different table (same structure). I just did not want to have to repeat the logic 40+ time. The tablenames it needs to run each time are stored in the 'ScenariosToRun' table within the 'scenario_name' field. The value of this field is also storedin step3 Select .... as Scenario line. Maybe there is a quicker and better way? My apologies for my ignorance on this. Your help is greatly appreciate. Regards, cirugio
There are other ways too for avoiding the cursor and using while loop etc..Try googling. |
 |
|
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-21 : 09:58:50
|
| -- |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-21 : 12:31:23
|
quote: Originally posted by cirugio I actually had tried that, but was getting the following error message. I am not sure why, for it is defined in the beginning of the program. Maybe the @sqlstmt plays into it? Server: Msg 137, Level 15, State 2, Line 8Must declare the variable '@wScenarioName'.
Since dynamic statement is used, a small change is required.set @sqlStmt = 'INSERT INTO SOEbyProduct(Scenario, Product, BankName,SumOfNotional, SumOfAvgBal, SumOfEOPBal, SumOfIntCF, sumOfAmortCF, SumOfPrepayCF, SumOfPrinCF, SumOfAddAmt, SumOfFTEIncome, AvgAccruedInt, AvgYield, AvgPeriodCap, AvgCap, AvgFloor, AvgPriceRateBase, AvgRepriceSpread, AvgRepriceRate)SELECT ' + @wScenarioName + ' as Scenario,Product,BankName,sum(s.notional) as SumOfNotional,sum(s.avgbal) as SumOfAvgBal,Hope now the issue should be resolved.Regards,Bohra I am here to learn from Masters and help new bees in learning. |
 |
|
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-21 : 13:54:24
|
| Hi Bohra,I changed it to --> SELECT ' +@wScenarioName+ ' as Scenario,but now getting the following errors: Server: Msg 207, Level 16, State 3, Line 1Invalid column name 'SOEBaseCase'.(7272 row(s) affected)Server: Msg 207, Level 16, State 3, Line 1Invalid column name 'SOERampDn200'.(7272 row(s) affected)Server: Msg 207, Level 16, State 3, Line 1Invalid column name 'SOERampUp200'.(7272 row(s) affected)It appears to be returning the correct values (e.g. SOEBASE, SOERampDn200, SoeRampUP200), but that value is needs to be stored in the table SOEbyProduct's Scenario field . I am not sure how to store this value. I thinking some kind of additional quotes. I tried " quotes, but also received an error. Thoughts? |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-22 : 02:02:12
|
quote: Originally posted by cirugio Hi Bohra,I changed it to --> SELECT ' +@wScenarioName+ ' as Scenario,but now getting the following errors: Server: Msg 207, Level 16, State 3, Line 1Invalid column name 'SOEBaseCase'.(7272 row(s) affected)Server: Msg 207, Level 16, State 3, Line 1Invalid column name 'SOERampDn200'.(7272 row(s) affected)Server: Msg 207, Level 16, State 3, Line 1Invalid column name 'SOERampUp200'.(7272 row(s) affected)It appears to be returning the correct values (e.g. SOEBASE, SOERampDn200, SoeRampUP200), but that value is needs to be stored in the table SOEbyProduct's Scenario field . I am not sure how to store this value. I thinking some kind of additional quotes. I tried " quotes, but also received an error. Thoughts?
My fault. In hurry, i gave incomplete answer.Try this:set @sqlStmt = 'INSERT INTO SOEbyProduct(Scenario, Product, BankName,SumOfNotional, SumOfAvgBal, SumOfEOPBal, SumOfIntCF, sumOfAmortCF, SumOfPrepayCF, SumOfPrinCF, SumOfAddAmt, SumOfFTEIncome, AvgAccruedInt, AvgYield, AvgPeriodCap, AvgCap, AvgFloor, AvgPriceRateBase, AvgRepriceSpread, AvgRepriceRate)SELECT '''+ @wScenarioName + ''' as Scenario,Product,BankName,.......... |
 |
|
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-22 : 10:10:36
|
| That worked. Thanks.But for some reason, even though it looks like it is using the cursor, it is only storing the last value the cursor points to.For example, the ScenariosToRun table contains the following values:SOEBaseCase SOERampDn200 SOERampUp200 When the program runs through the cursor, the only value that gets stored from the SELECT '''+ @wScenarioName + ''' as Scenario, statement is SOERampUp200 for all the records. Your thoughts on this are greatly appreciated. Regards,cirugio |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-22 : 12:37:19
|
quote: Originally posted by cirugio That worked. Thanks.But for some reason, even though it looks like it is using the cursor, it is only storing the last value the cursor points to.For example, the ScenariosToRun table contains the following values:SOEBaseCase SOERampDn200 SOERampUp200 When the program runs through the cursor, the only value that gets stored from the SELECT '''+ @wScenarioName + ''' as Scenario, statement is SOERampUp200 for all the records. Your thoughts on this are greatly appreciated. Regards,cirugio
Do a small check :1. Print the value of @sqlStmt.2. Remove the "Insert part" from the statement printed from @sqlstmt. You will be left only with "Select" part.3. Execute the "Select" part and see if it returns any record.4. It the step 3 returns the record then it will also be inserted in SOEbyProduct table. |
 |
|
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-22 : 13:46:08
|
Ok. I think I found my issue. It looks like I was truncating the ByProduct table each time each looped through and only the last run was being saved. I had to move around my steps and then only execute the WHILE FETCH statement within step3. I think it may be working now, I just need to test a bit further. The issue I am experiencing now is with creating the index on each of the tables. Each time it runs it goes down on an error "There is already an index on table 'SOEBasecase' named 'SoeID_IDX'". I thought a create overwrites any existing idx which may be out there. Thoughts???Most current logic:SET QUOTED_IDENTIFIER OFF GOSET ANSI_NULLS OFF GOALTER PROCEDURE [SOE_SCENARIOS] AS------------------------------------------------------------------------------- Step1: ---- CREATES a TEMPORY table containing parsed out data rom the CvgWriteOut_Account table -- AccountName is parased into two seperate fields containing product & bankname------------------------------------------------------------------------------IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'Parsed_CVGWriteOut')and OBJECTPROPERTY(id, N'IsUserTable') = 1)Begincreate table Parsed_CVGWriteout ( [w_id] int,Scenid int,Product char(50),BankName char(50) )CREATE INDEX ParseID_IDX on Parsed_CVGWriteout(w_id);ENDELSETruncate TABLE Parsed_CVGWriteoutInsert into Parsed_CVGWriteOut([w_id],scenid,product,bankname)select [id],scenid,--these would also work if function failed at some point - keep in here--replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),2),'#~@','.') as dimension,--replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),3),'#~@','.') as bank,--replace(parsename(replace(replace(AccountName+'x','.','#~@'),':','.'),4),'#~@','.') as productDBO.GetStringAtPos(AccountName,':',1 ),DBO.GetStringAtPos(AccountName,':',2 ) from dbo.CvgWriteOut_Accounts as w-------------------------------------- Step 2: -- Creates SOEbyProduct table - which will stored aggregated data (sum/avgs)-- ------------------------------------IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'SOEbyProduct')and OBJECTPROPERTY(id, N'IsUserTable') = 1)Begincreate table SOEbyProduct (Scenario char(20), Product char(50), BankName char(50), SumOfNotional float, SumOfAvgBal float, SumOfEOPBal float, SumOfIntCF float, SumOfAmortCF float, SumOfPrepayCF float, SumOfPrinCF float, SumOfAddAmt float, SumOfFTEIncome float,AvgAccruedInt float, AvgYield float, AvgPeriodCap float, AvgCap float, AvgFloor float, AvgPriceRateBase float, AvgRepriceSpread float , AvgRepriceRate float)EndELSETruncate TABLE SOEbyProduct-------------------------------------------------------------------------------------------- Step3: -- -- Performs match b/w the above 2 files and aggreates the summed/avegered data into the SOEbyProduct table-- This step is performed multiple times for each table identified in the dbo.ScenariosToRun -------------------------------------------------------------------------------------------BEGINDECLARE @wScenarioName Varchar(50)DECLARE @sqlStmt Varchar (8000)DECLARE cur CURSOR FOR SELECT scenario_name FROM ScenariosToRunOPEN curFETCH NEXT FROM cur INTO @wScenarioNameExec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)')WHILE @@fetch_status = 0BEGINset @sqlStmt = 'INSERT INTO SOEbyProduct(Scenario, Product, BankName,SumOfNotional, SumOfAvgBal, SumOfEOPBal, SumOfIntCF, sumOfAmortCF, SumOfPrepayCF, SumOfPrinCF, SumOfAddAmt, SumOfFTEIncome, AvgAccruedInt, AvgYield, AvgPeriodCap, AvgCap, AvgFloor, AvgPriceRateBase, AvgRepriceSpread, AvgRepriceRate)SELECT '''+ @wScenarioName + ''' as Scenario,Product,BankName,sum(s.notional) as SumOfNotional,sum(s.avgbal) as SumOfAvgBal,sum(s.eopbal) as SumOfEOPBAL,sum(s.Intcf) as SumOfIntCF,sum(s.amortCF) as SumOfAmortCF,sum(s.prepaycf) as SumOfPrepayCF,sum(s.princf) as SumofPrinCF,-- if null value in field replaces it with 0.0 since floating, otherwise if int would have used 0sum (coalesce(s.addamt,0.0)) as SumAddamt,sum(coalesce(s.FTEIncome,0.0)) as SumofFTEIncome,sum(s.[accruedint]*s.[eopbal])/NULLIF(sum(s.[eopbal]),0.0) as AvgAccruedInt,sum(coalesce(s.[avgyld],0.0)*s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgYield,sum(s.[PeriodicCap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPeriodCap,sum(s.[Cap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgCap,sum(s.[Floor] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgFloor,sum(s.[ReprRateBase] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPriceRateBase,sum(s.[ReprRateAvgAdj] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceSpread,sum(s.[ReprRate] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceRate--from SOEBasecase as s JOIN dbo.Parsed_CVGWriteOut as W --on w.[w_id]=s.accountidfrom Parsed_CVGWriteout as w inner JOIN ' + @wScenarioName +' as s on w.[w_id]=s.accountidgroup by PRODUCT,BANKNAME,S.SCENDATEINDEX'--Print @sqlStmtExec (@sqlStmt)FETCH NEXT FROM CUR INTO @WscenarionameENDCLOSE curDEALLOCATE curENDGOSET QUOTED_IDENTIFIER OFF GOSET ANSI_NULLS ON GO |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-23 : 03:24:16
|
quote: FETCH NEXT FROM cur INTO @wScenarioNameExec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)')WHILE @@fetch_status = 0
Index name must be unique.You are trying to create the index with same name in different table. This is not supported.If this SP is going to be called frequently and the tables to be processed are going to be same then I suggest that you add the index outside the SP.If for some reason you don't want to add the index outside the SP, then you can use some meaningful name while creating index in the SP.Ex: SOEBaseCase_AccId_IdxIn the SP, you can check whether the index exists before creating it. In case it exists then skip the index creation part. In case the index doesn't exists, then create it.Regards,Bohra |
 |
|
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-23 : 08:40:37
|
Hi Bohar,Per your suggestion, I modified the logic to check if the index exists. The program is running fine, but it only creates the index the first time around for the SOEBaseCase table but not for the others (SOERampDn200 & SOERampUp20). I tried moving the logic around (see below) to different parts within Step3, but still only creates it for the first time around. Thoughts??-------------------------------------------------------------------------------------------- Step3: -- -- Performs match b/w the above 2 files and aggreates the summed/avegered data into the SOEbyProduct table-- This step is performed multiple times for each table identified in the dbo.ScenariosToRun -------------------------------------------------------------------------------------------BEGIN DECLARE @wScenarioName Varchar(50) DECLARE @sqlStmt Varchar (8000) DECLARE cur CURSOR FOR SELECT scenario_name FROM ScenariosToRun OPEN cur FETCH NEXT FROM cur INTO @wScenarioName-- IF NOT EXISTS (SELECT name from sysindexes WHERE name = 'soeid_idx')-- Exec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)')WHILE @@fetch_status = 0BEGIN IF NOT EXISTS (SELECT name from sysindexes WHERE name = 'soeid_idx') Exec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)')set @sqlStmt = 'INSERT INTO SOEbyProduct(Scenario, Product, BankName,SumOfNotional, SumOfAvgBal, SumOfEOPBal, SumOfIntCF, sumOfAmortCF, SumOfPrepayCF, SumOfPrinCF, SumOfAddAmt, SumOfFTEIncome, AvgAccruedInt, AvgYield, AvgPeriodCap, AvgCap, AvgFloor, AvgPriceRateBase, AvgRepriceSpread, AvgRepriceRate)SELECT '''+ @wScenarioName + ''' as Scenario,Product,BankName,sum(s.notional) as SumOfNotional,sum(s.avgbal) as SumOfAvgBal,sum(s.eopbal) as SumOfEOPBAL,sum(s.Intcf) as SumOfIntCF,sum(s.amortCF) as SumOfAmortCF,sum(s.prepaycf) as SumOfPrepayCF,sum(s.princf) as SumofPrinCF,-- if null value in field replaces it with 0.0 since floating, otherwise if int would have used 0sum (coalesce(s.addamt,0.0)) as SumAddamt,sum(coalesce(s.FTEIncome,0.0)) as SumofFTEIncome,sum(s.[accruedint]*s.[eopbal])/NULLIF(sum(s.[eopbal]),0.0) as AvgAccruedInt,sum(coalesce(s.[avgyld],0.0)*s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgYield,sum(s.[PeriodicCap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPeriodCap,sum(s.[Cap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgCap,sum(s.[Floor] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgFloor,sum(s.[ReprRateBase] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPriceRateBase,sum(s.[ReprRateAvgAdj] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceSpread,sum(s.[ReprRate] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceRate--from SOEBasecase as s JOIN dbo.Parsed_CVGWriteOut as W --on w.[w_id]=s.accountidfrom Parsed_CVGWriteout as w inner JOIN ' + @wScenarioName +' as s on w.[w_id]=s.accountidgroup by PRODUCT,BANKNAME,S.SCENDATEINDEX'--Print @sqlStmtExec (@sqlStmt)FETCH NEXT FROM CUR INTO @WscenarionameENDCLOSE curDEALLOCATE curEND |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-23 : 11:33:46
|
| What version of SQL server you are using ? |
 |
|
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-23 : 11:37:59
|
| Were currently using SQL Server 2000. |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-23 : 11:48:09
|
quote: IF NOT EXISTS (SELECT name from sysindexes WHERE name = 'soeid_idx') Exec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)')
Try this:IF NOT EXISTS (SELECT name from sysindexes WHERE name = 'soeid_idx' and id = object_id(@wScenarioName)) Exec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)') |
 |
|
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-23 : 11:51:21
|
Thanks. I think that did the trick.I am going to test this program a bit more to ensure it is doing exactly what I need to do. Can you clarify for me before I do that:1) If I really need the first BEGIN statement in step 3? when I developed it, I was basing it off another example. It appears to run without it. 2) I am trying to understand why I need the set @sqlStmt = ' ? Would you mind providing me with a brief explanatin. I want to ensure I have a good understnading so that if I have to code another cursor, I understand the reasoning behind it. 3) Last question, can you clarify for me why the following statemetn has to be an EXCEC and use ticks : Exec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)')-------------------------------------------------------------------------------------------- Step3: -- -- Performs match b/w the above 2 files and aggreates the summed/avegered data into the SOEbyProduct table-- This step is performed multiple times for each table identified in the dbo.ScenariosToRun -------------------------------------------------------------------------------------------BEGIN DECLARE @wScenarioName Varchar(50) DECLARE @sqlStmt Varchar (8000) DECLARE cur CURSOR FOR SELECT scenario_name FROM ScenariosToRun OPEN cur FETCH NEXT FROM cur INTO @wScenarioNameWHILE @@fetch_status = 0BEGIN IF NOT EXISTS (SELECT name from sysindexes WHERE name = 'soeid_idx' and id = object_id(@wScenarioName)) Exec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)')set @sqlStmt = 'INSERT INTO SOEbyProduct(Scenario, Product, BankName,SumOfNotional, SumOfAvgBal, SumOfEOPBal, SumOfIntCF, sumOfAmortCF, SumOfPrepayCF, SumOfPrinCF, SumOfAddAmt, SumOfFTEIncome, AvgAccruedInt, AvgYield, AvgPeriodCap, AvgCap, AvgFloor, AvgPriceRateBase, AvgRepriceSpread, AvgRepriceRate)SELECT '''+ @wScenarioName + ''' as Scenario,Product,BankName,sum(s.notional) as SumOfNotional,sum(s.avgbal) as SumOfAvgBal,sum(s.eopbal) as SumOfEOPBAL,sum(s.Intcf) as SumOfIntCF,sum(s.amortCF) as SumOfAmortCF,sum(s.prepaycf) as SumOfPrepayCF,sum(s.princf) as SumofPrinCF,-- if null value in field replaces it with 0.0 since floating, otherwise if int would have used 0sum (coalesce(s.addamt,0.0)) as SumAddamt,sum(coalesce(s.FTEIncome,0.0)) as SumofFTEIncome,sum(s.[accruedint]*s.[eopbal])/NULLIF(sum(s.[eopbal]),0.0) as AvgAccruedInt,sum(coalesce(s.[avgyld],0.0)*s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgYield,sum(s.[PeriodicCap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPeriodCap,sum(s.[Cap] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgCap,sum(s.[Floor] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgFloor,sum(s.[ReprRateBase] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgPriceRateBase,sum(s.[ReprRateAvgAdj] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceSpread,sum(s.[ReprRate] *s.[eopbal])/nullif(sum(s.[eopbal]),0.0) as AvgRepriceRatefrom Parsed_CVGWriteout as w inner JOIN ' + @wScenarioName +' as s on w.[w_id]=s.accountidgroup by PRODUCT,BANKNAME,S.SCENDATEINDEX'--Print @sqlStmtExec (@sqlStmt)FETCH NEXT FROM CUR INTO @WscenarionameENDCLOSE curDEALLOCATE curEND |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-23 : 12:02:57
|
quote: Originally posted by cirugio OK. I will try it out now and will get back to you shortly. In the meanwhile, can you tell me do you think I need that 1st set of begin in the program? I was following another example, but not sure if its necessary??
If you meant that Table creation and index creation are required in Begin and End then my answer is Yes.Begincreate table Parsed_CVGWriteout ( [w_id] int,Scenid int,Product char(50),BankName char(50) )CREATE INDEX ParseID_IDX on Parsed_CVGWriteout(w_id);ENDIf you question was something different then let us know the same. |
 |
|
|
cirugio
Yak Posting Veteran
90 Posts |
Posted - 2010-07-23 : 12:09:55
|
| Sorry, I modified my reply (see my previous post). I actually meant the 1st BEGIN statement in Step3. Also, hope you don't mind the additional questions I posted . I havesuch a large learning curve to accomplish, but please note that your help is so greatly appreciated. |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-07-23 : 12:25:44
|
quote: 1) If I really need the first BEGIN statement in step 3?when I developed it, I was basing it off another example. It appears to run without it.
The first begin is not essential but you can still keep it. This will help you in differentiating the blocks. (Easy readabilityquote: 2) I am trying to understand why I need the set @sqlStmt = ' ? Would you mind providing me with a brief explanatin. I want to ensure I have a good understnading so that if I have to code another cursor, I understand the reasoning behind it.
Since the table name needs to be read from another table and to be used in select query, We have to use dynamic query.You can remove the @sqlStmt = ' and put the complete statement in Exec(' block, it will still work.The reason for using the variable is, if required while debugging we can print the value of variable. It is generally recommended to store such big chunks in a variable and execute it instead of keeping such big statement in Exec(' block directly.quote: 3) Last question, can you clarify for me why the following statemetn has to be an EXCEC and use ticks :Exec ('CREATE INDEX SoeID_IDX on ' + @wScenarioName +' (AccountID)')
Exec (' :- This is one of way of dynamic execution in SQL server. It have its own Pros and cons. Google for dynamic exeuction in Sql server and you will find lot of information. |
 |
|
|
Next Page
|
|
|
|
|