Unix Technical Forum

Stored procedure does not complete until result set is retrieved from ODBC

This is a discussion on Stored procedure does not complete until result set is retrieved from ODBC within the MS SQL ODBC forums, part of the Microsoft SQL Server category; --> I have a SQL Server Stored procedure that I am executing via ODBC. However, I am seeing behavior that ...


Go Back   Unix Technical Forum > Database Server Software > Microsoft SQL Server > MS SQL ODBC

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-27-2008, 10:01 PM
Fred Foozle
 
Posts: n/a
Default Stored procedure does not complete until result set is retrieved from ODBC

I have a SQL Server Stored procedure that I am executing via ODBC.
However, I am seeing behavior that I cannot explain and do not
understand.

Given the following T-SQL code that I have applied to my database:

--
-- BEGIN SQL CODE
--

--
-- Create a non-temp table to access at any time. Drop the table
first,
-- just in case it already exists.
--
if exists (select *
from dbo.sysobjects
where ((id = object_id(N'MyStatusTable'))
and (OBJECTPROPERTY(id, N'IsUserTable') = 1))
)
begin
drop table MyStatusTable
end
go

create table MyStatusTable
(
Status varchar(256)
)
go


--
-- Insert a value into the table. This value
-- will be modified when the MyTestProc stored procedure
-- is executed. (see below)
--
insert into MyStatusTable
(Status)
values
('EXECUTING...')
go


--
-- If the stored procedure we are about to create already
-- exists, then drop it
--
if exists (select *
from dbo.sysobjects
where ((id = object_id(N'MyTestProc'))
and (OBJECTPROPERTY(id, N'IsProcedure') = 1))
)
begin
drop procedure MyTestProc
end
go

create procedure MyTestProc
as
begin
set nocount on

declare @Ctr integer -- counter
declare @MyCursorInteger integer -- value read
from cursor


--
-- Create a result set
--
select 0, 'Begin MyTestProc'


--
-- Create a temp table to hold integer values.
-- Load the table with 2500 integers.
--
if (exists( select 1
from tempdb.dbo.sysobjects
where (name like '%#MyIntegerTable%')
and (xtype = 'U')))
begin
drop table #MyIntegerTable
end

create table #MyIntegerTable
(
MyIntValue integer
)


set @Ctr = 0
while (@Ctr < 2500)
begin
set @Ctr = @Ctr + 1
insert into #MyIntegerTable
(MyIntValue)
values
(@Ctr)
end


/*
--
-- Start Code without cursor
--
set @Ctr = 0

while(1=1)
begin
set @Ctr = @Ctr + 1

select @MyCursorInteger = MyIntValue
from #MyIntegerTable
where MyIntValue = @Ctr

if (@@ROWCOUNT = 0)
begin
break
end
end
--
-- End Code Without Cursor
--
*/


--
-- Create and open a cursor to walk the table.
--
-- Note: Depending upon the memory available to your SQL Server
-- you may require more or fewer values. You can tinker
-- with fewer by replacing the "top xxx" within the select
clause
-- and adjusting the number of values used to populate
each
-- row in #MyIntegerTable above
--

declare MyCursor cursor local for
select top 2500 MyIntValue
from #MyIntegerTable

open MyCursor


--
-- Grab each row in turn, until there is nothing left
--
while (1=1)
begin

fetch next from MyCursor
into @MyCursorInteger

if (@@fetch_status <> 0)
begin
break
end

end


--
-- Update the status table
--
update MyStatusTable
set status = 'FINISHED'


--
-- Close and deallocate cursor
--
close MyCursor
deallocate MyCursor



--
-- Create a result set before exiting
--
select 1, 'End MyTestProc'


set nocount off
return 0

end
go


--
-- END SQL CODE
--



Before executing the MyTestProc stored procedure, if I issue the
command:

SELECT * FROM MyStatusTable

I will receive the result set

EXECUTING...


If I then do the following:

1. Within ODBCTest, obtain a full connection to the database
2. Within ODBCTest, issue the SQL command 'EXEC MyTestProc'
3. I receive back the following within ODBCTest:

SQLExecDirect:
In: hstmt = 0x00821A00, szSqlStr = "exec MyTestProc",
cbSqlStr = -3
Return: SQL_SUCCESS=0

This leads me to believe the stored procedure has executed
successfully.

4. Within Query Analyzer, I re-issue the command:

SELECT * FROM MyStatusTable

I still obtain the result set

EXECUTING...


5. Within ODBCTest, I choose Results | Get All Data.

6. I receive the following within ODBCTest:

"", ""
0, "Begin MyTestProc"
1 row fetched from 2 columns.

"", ""
1, "End MyTestProc"
1 row fetched from 2 columns.
--


7. Within Query Analyzer, I re-issue the command:

SELECT * FROM MyStatusTable

This time I get the following

FINISHED


Why is it that the ODBC indicates that the stored procedure has
finished executing successfully, when it really hasn't? Why does the
database update MyStatusTable only after I retrieve the result sets?
What is going on?


Some things to note:
1. If you eliminate the cursor, the problem will not occur (i.e., the
status updates to 'FINISHED') [There will still be result sets to be
retrieved.]
2. If you eliminate the result sets within the stored proc, the problem
will not occur
3. If you reduce the number of items associated with the cursor (e.g.
"top 10"), the problem will not occur
4. The SQL Server that I am executing on has dynamically configured SQL
Server Memory with a minimum of 255 MB and a maximum of 510MB. ( I
have also tried this with a fixed memory size.) If I reproduce this
test on a SQL Server with more memory (3967 MB), the problem DOES NOT
OCCUR
5. There does not appear to be a "time out" period where things will
complete. When executing MyTestProc within ODBCTest, it completes
instantaneously. I have waited in excess of 30 minutes to determine if
the status will change. It will not change until I retrieve the result
sets.



It appears that this is a memory consumption problem, but only when I
use result sets in conjunction with a cursor that is associated with a
large number of items. In other words, if I (a) increase the amount of
memory available on the SQL Server, (b) reduce the number of rows
associated with the cursor, (c) eliminate the usage of the cursor or
(d) eliminate the result set that is generated, then the problem "goes
away".

This proble will only occur under an ODBC connection. If this test
scenario is executed within Query Analyzer, then the result sets will
be returned immediately and MyStatusTable will be updated.

Any helpful suggestions would be greatly appreciated.

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 08:41 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com