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.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 How to loop the value from sp_executesql

Author  Topic 

ryanlcs
Yak Posting Veteran

62 Posts

Posted - 2010-03-24 : 07:38:15
Hi

I 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 output



The 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.
Go to Top of Page

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 do

Vaibhav T
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2010-03-24 : 11:49:40
quote:
Originally posted by ryanlcs

Hi

I 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 output



The 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 MVP
http://visakhm.blogspot.com/

Go to Top of Page

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 ... )
Go to Top of Page

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 MVP
http://visakhm.blogspot.com/

Go to Top of Page

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 table

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

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
"
Go to Top of Page

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 in
DECLARE @ProductID INT
DECLARE @ProductNumber NVARCHAR(25)
DECLARE @Name NVARCHAR(50)

-- Define the select statement used to populate the cursor
DECLARE cr CURSOR FOR
SELECT ProductID, ProductNumber, [Name]
FROM Production.Product
WHERE [Name] LIKE 'b%'

-- Open the Cursor
OPEN cr

-- Loop through each row in the cursor
-- Fetch the first row from the cursor
FETCH NEXT FROM cr INTO @ProductID, @ProductNumber, @Name
-- Check the fetch status. If a row was fetched, enter the loop
WHILE @@FETCH_STATUS = 0
BEGIN
-- 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, @Name
END

-- VERY IMPORTANT!!! Close and deallocate the cursor
CLOSE cr
DEALLOCATE 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.
Go to Top of Page

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
Go to Top of Page

DBA in the making
Aged Yak Warrior

638 Posts

Posted - 2010-03-25 : 08:17:16
quote:
Originally posted by Kristen
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



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 AdventureWorks
GO

CREATE PROCEDURE dbo.currency_cursor
@currency_cursor CURSOR VARYING OUTPUT
AS
SET @currency_cursor = CURSOR
FORWARD_ONLY STATIC FOR
SELECT CurrencyCode, Name
FROM Sales.Currency;
OPEN @currency_cursor;
GO

DECLARE @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;
GO

DROP PROCEDURE dbo.currency_cursor
GO


There are 10 types of people in the world, those that understand binary, and those that don't.
Go to Top of Page

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#cursor0

DECLARE @my_cur CURSOR
EXEC sp_executesql
N'SET @my_cur = CURSOR STATIC FOR
SELECT name FROM dbo.sysobjects;
OPEN @my_cur',
N'@my_cur cursor OUTPUT', @my_cur OUTPUT
FETCH NEXT FROM @my_cur

There are 10 types of people in the world, those that understand binary, and those that don't.
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2010-03-25 : 08:24:37
That's a good link/example. But I hope I never need it!
Go to Top of Page

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.
Go to Top of Page

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/
Go to Top of Page

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.
Go to Top of Page
   

- Advertisement -