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 |
|
ryanlcs
Yak Posting Veteran
62 Posts |
Posted - 2010-03-24 : 07:38:15
|
HiI got the following statement:SET @strSQL = 'SELECT @mainID = E.Main_ID, @curTitle = F.Title, @violateRules = Violate_Rules, @Testcell = Testcell, @Series_Name = Series_Name From ' + @dataTable + ' A,'SET @strSQL = @strSQL + ' ' + @headerTable + ' B,'SET @strSQL = @strSQL + ' ' + @seriesTable + ' C,'SET @strSQL = @strSQL + ' tbl_Setting_Series D, tbl_Setting_Main_Series_Mapping E, tbl_Setting_Main F'SET @strSQL = @strSQL + ' Where A.Line_ID = C.Line_ID And B.Header_ID = C.Header_ID'SET @strSQL = @strSQL + ' And C.Series_ID = D.Series_ID And D.Series_ID = E.Series_ID And C.Line_ID IN (' + Cast(@allLineID as Varchar(5000)) + ')'SET @strSQL = @strSQL + ' And E.Main_ID = F.Main_ID' SET @strSQL = @strSQL + ' And A.Date = ''' + @Date + ''' And A.Interval = ''' + @Interval + '''' Exec sp_executesql @strSQL, N'@violateRules nvarchar(100) output, @Testcell nvarchar(100) output, @Series_Name nvarchar(100) output, @mainID int output, @curTitle nvarchar(100) output', @ViolateRules output, @Testcell output,@Series_Name output, @mainID output, @curTitle outputThe query will return more than 1 record, but from the output command in the Exec sp_executesql, I can only get 1 return value.Is there a way to retrieve more than 1 value from the query or is the a way I can loop the query ?Thanks. |
|
|
DBA in the making
Aged Yak Warrior
638 Posts |
Posted - 2010-03-24 : 08:01:57
|
| You're looking for something like a CURSOR. You should find all you need in SQL Books Online. Use them sparingly, they're fairly slow. And unless you really need to, I wouldn't use sp_executesql unless you really need to.There are 10 types of people in the world, those that understand binary, and those that don't. |
 |
|
|
vaibhavktiwari83
Aged Yak Warrior
843 Posts |
Posted - 2010-03-24 : 08:06:23
|
| I am sorry but Really i m not getting what exactly you want to doVaibhav T |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2010-03-24 : 11:49:40
|
quote: Originally posted by ryanlcs HiI got the following statement:SET @strSQL = 'SELECT @mainID = E.Main_ID, @curTitle = F.Title, @violateRules = Violate_Rules, @Testcell = Testcell, @Series_Name = Series_Name From ' + @dataTable + ' A,'SET @strSQL = @strSQL + ' ' + @headerTable + ' B,'SET @strSQL = @strSQL + ' ' + @seriesTable + ' C,'SET @strSQL = @strSQL + ' tbl_Setting_Series D, tbl_Setting_Main_Series_Mapping E, tbl_Setting_Main F'SET @strSQL = @strSQL + ' Where A.Line_ID = C.Line_ID And B.Header_ID = C.Header_ID'SET @strSQL = @strSQL + ' And C.Series_ID = D.Series_ID And D.Series_ID = E.Series_ID And C.Line_ID IN (' + Cast(@allLineID as Varchar(5000)) + ')'SET @strSQL = @strSQL + ' And E.Main_ID = F.Main_ID' SET @strSQL = @strSQL + ' And A.Date = ''' + @Date + ''' And A.Interval = ''' + @Interval + '''' Exec sp_executesql @strSQL, N'@violateRules nvarchar(100) output, @Testcell nvarchar(100) output, @Series_Name nvarchar(100) output, @mainID int output, @curTitle nvarchar(100) output', @ViolateRules output, @Testcell output,@Series_Name output, @mainID output, @curTitle outputThe query will return more than 1 record, but from the output command in the Exec sp_executesql, I can only get 1 return value.Is there a way to retrieve more than 1 value from the query or is the a way I can loop the query ?Thanks.
you problem is you're trying to return value through variables so in any case they can hold only a single set of values. If you need to return multiple records why not use temporary table instead and insert into it using this query.------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-03-24 : 12:30:17
|
Is it possible to return a Cursor as an Output variable from an Sproc call? (Don't like cursors, try never to use them, so I'm not sure ... ) |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2010-03-24 : 12:32:12
|
quote: Originally posted by Kristen Is it possible to return a Cursor as an Output variable from an Sproc call? (Don't like cursors, try never to use them, so I'm not sure ... )
I'm also in your club ...have never ever used cursors except for learning purposes... ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2010-03-25 : 03:27:54
|
| One solution is dont use variables and move the result to temporary tableMadhivananFailing to plan is Planning to fail |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-03-25 : 04:12:01
|
| For SQL Documentation Books Online:"Transact-SQL stored procedures can use the cursor data type only for OUTPUT parameters. If the cursor data type is specified for a parameter, both the VARYING and OUTPUT parameters are required. If the VARYING keyword is specified for a parameter, the data type must be cursor and the OUTPUT keyword must be specified" |
 |
|
|
DBA in the making
Aged Yak Warrior
638 Posts |
Posted - 2010-03-25 : 06:18:33
|
quote: Originally posted by Kristen Is it possible to return a Cursor as an Output variable from an Sproc call? (Don't like cursors, try never to use them, so I'm not sure ... )
Sorry, that's not what I was suggesting. The OP didn't say that this query was part of a stored Proc, only that it called one to execute the SQL String. I don't like Cursors anymore than anyone else, hence my warning about performance. But if you want to write a script that loops through a set of rows, and does something with each row, that's precisely what a cursor does. For the OP, a Cursor is a sql server construct that allows you to loop through the results of a query, passing each row, one at a time, to a set of variables, and then doing something with those variables. Here's a really simple example. Most people don't like them, because they're fairly slow, and are often used unnecessarily. However, if you absolutely must loop through the result of a select statement, a cursor is the way to go. -- Define Variables to store the result inDECLARE @ProductID INTDECLARE @ProductNumber NVARCHAR(25)DECLARE @Name NVARCHAR(50)-- Define the select statement used to populate the cursorDECLARE cr CURSOR FORSELECT ProductID, ProductNumber, [Name]FROM Production.ProductWHERE [Name] LIKE 'b%'-- Open the CursorOPEN cr-- Loop through each row in the cursor-- Fetch the first row from the cursorFETCH NEXT FROM cr INTO @ProductID, @ProductNumber, @Name-- Check the fetch status. If a row was fetched, enter the loopWHILE @@FETCH_STATUS = 0BEGIN -- Do something with the results. PRINT CAST(@ProductID AS VARCHAR) + ' - ' + @ProductNumber + ' - ' + @Name -- Fetch the nest row from the cursor FETCH NEXT FROM cr INTO @ProductID, @ProductNumber, @NameEND-- VERY IMPORTANT!!! Close and deallocate the cursorCLOSE crDEALLOCATE cr You might not need to use a cursor. It depends on exactly what you're trying to achieve. Can you give more details on that?There are 10 types of people in the world, those that understand binary, and those that don't. |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-03-25 : 07:53:28
|
| "Sorry, that's not what I was suggesting. The OP didn't say that this query was part of a stored Proc, only that it called one to execute the SQL String. I don't like Cursors anymore than anyone else, hence my warning about performance. But if you want to write a script that loops through a set of rows, and does something with each row, that's precisely what a cursor does. "I wasn't implying that you did suggest that, only that an Sproc (i.e. sp_ExecuteSQL in this case) could return a Cursor as an OUTPUT parameter and that could be used to loop through the records |
 |
|
|
DBA in the making
Aged Yak Warrior
638 Posts |
Posted - 2010-03-25 : 08:17:16
|
quote: Originally posted by KristenI wasn't implying that you did suggest that, only that an Sproc (i.e. sp_ExecuteSQL in this case) could return a Cursor as an OUTPUT parameter and that could be used to loop through the records
Sorry again for the misunderstanding. :)Yes, you can return a cursor from a stored proc, but the the proc has to be written with that intent. See the example below (Stolen from Books Online, but modified to actually work. :) ).According to Books Online for sp_ExecuteSQL, "OUTPUT: Indicates that the parameter is an output parameter. text, ntext, and image parameters can be used as OUTPUT parameters, unless the procedure is a common language runtime (CLR) procedure. An output parameter that uses the OUTPUT keyword can be a cursor placeholder, unless the procedure is a CLR procedure.", However, it gives no example of how to do that. USE AdventureWorksGO CREATE PROCEDURE dbo.currency_cursor @currency_cursor CURSOR VARYING OUTPUTAS SET @currency_cursor = CURSOR FORWARD_ONLY STATIC FOR SELECT CurrencyCode, Name FROM Sales.Currency; OPEN @currency_cursor;GODECLARE @MyCursor CURSOR;DECLARE @CurrencyCode NCHAR(3)DECLARE @Name NVARCHAR(50)EXEC dbo.currency_cursor @currency_cursor = @MyCursor OUTPUT;FETCH NEXT FROM @MyCursor INTO @CurrencyCode, @Name;WHILE (@@FETCH_STATUS = 0)BEGIN; PRINT @CurrencyCode + ' - ' + @Name FETCH NEXT FROM @MyCursor INTO @CurrencyCode, @Name;END;CLOSE @MyCursor;DEALLOCATE @MyCursor;GODROP PROCEDURE dbo.currency_cursorGO There are 10 types of people in the world, those that understand binary, and those that don't. |
 |
|
|
DBA in the making
Aged Yak Warrior
638 Posts |
Posted - 2010-03-25 : 08:22:23
|
| There is an example here: http://www.sommarskog.se/dynamic_sql.html#cursor0DECLARE @my_cur CURSOREXEC sp_executesql N'SET @my_cur = CURSOR STATIC FOR SELECT name FROM dbo.sysobjects; OPEN @my_cur', N'@my_cur cursor OUTPUT', @my_cur OUTPUTFETCH NEXT FROM @my_curThere are 10 types of people in the world, those that understand binary, and those that don't. |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-03-25 : 08:24:37
|
| That's a good link/example. But I hope I never need it! |
 |
|
|
DBA in the making
Aged Yak Warrior
638 Posts |
Posted - 2010-03-25 : 08:51:17
|
quote: Originally posted by Kristen That's a good link/example. But I hope I never need it!
Same here. I try to say away from both cursors and dynamic SQL.There are 10 types of people in the world, those that understand binary, and those that don't. |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-03-25 : 09:23:31
|
Used to be anti-dynamic-SQL but now using dynamic SQL here (via sp_ExecuteSQL) to get good reusable query plans for complex WHERE clauses (where user can set Criteria on any of many different columns - but most/many column criteria are left blank).Also to influence query plan - e.g. if selecting a single customer's invoices for a single date then Date Index works better, for longer time range then Customer index works better.Ideas that came from http://www.sommarskog.se/ |
 |
|
|
DBA in the making
Aged Yak Warrior
638 Posts |
Posted - 2010-03-25 : 10:34:54
|
| Yeah, I've used them for similar things as well. However, I just don't like the way they look. I take great care to layout my T-SQL to make it as easy to read as possible for the next person. And when I come to work on poorly laid out code written by others, the first thing I do is lay it out correctly, before I even start analyzing it. Poorly laid out T-SQL is one of my pet hates. So when I work on dynamic SQL code, just reading the code really hurts my head.There are 10 types of people in the world, those that understand binary, and those that don't. |
 |
|
|
|
|
|
|
|