January 13, 2004 at 5:11 pm
Hi, I have an ADO command object that calls a stored procedure passing in two parameters.
when I call this stored procedure from query analyer it dutifully shows me the results set in the grid area.
When I call this stored procedure from ADO it doesn't error out but it reports rs.fields.length=0 and anything I try to do to it returns a "can't when object is closed" error
The stored procedure runs about 7 distinct jobs, one of which inserts values to a table Variable. The last action is a select against this table variable.
Here is the proc in psuedo_code:
set nocount on
begin tran
--step1
do stuff
--step2
do stuff
--Step3
Do stuff inserting into @tblVar
--Step4
Do yet more stuff
SET NOCOUNT OFF
Commit or rollback
select * from @tblVar
GO
That's about it, and as I say in query analyer I get a result set but via ADO I don't
The command object documentation says:
>>If it is a row-returning query, the results are stored in a new Recordset object. If it is not a row-returning query, the provider will return a closed Recordset object<<
Could ADO somehow think it's a non-rowreturning operation?
I'm not sure if the problem is in my T-SQL or my ADO.
Here is the whole proc for those that have the stomach for it:
CREATE proc sprocket_copycourse
@srcCourseID int,
@trgClientID int
as
SET ANSI_WARNINGS OFF
SET NOCOUNT ON
declare @SampleFilesDir varchar(100)
declare @MediaFilesDir varchar(100)
declare @ClientsDir varchar(100)
declare @SampleCourseID int
set @SampleCourseID = 78
declare @trgCourseID int
declare @srcClientDir varchar(50)
declare @trgClientDir varchar(50)
select @srcClientDir = (SELECT dbo.Client.directory FROM dbo.Course INNER JOIN dbo.Client ON dbo.Course.client_fk = dbo.Client.uid WHERE (dbo.Course.uid = @srcCourseID))
select @trgClientDir = (select dbo.Client.directory from dbo.Client where uid = @trgClientID)
begin tran
--step 1
insert into course SELECT @trgClientID, CourseName, TimeLimit, owner, CourseStatus_fk, toppic, toppich, toppicw, toppicalt, bottompic, bottompich, bottompicw, bottompicalt,
courseusername, coursepassword, hidecourseresults, showcoursereport, showcoursesignoff, completedlockout, description, intro, conclusion,
passpercent, showquestionpicture, showanswerpicture, autoplayansweraudio, autonext, moreinfo, askdemoquestions, publicmodule, contact,
recordtimetaken, reportsintrotext, insequence, insequencepass, shortname, author_fk, madelivedate, enrollreqd, fee, enrolluses, enrolldays,
usercategory, version, HideConclusionPageUntilDone, navBackground1, navBackground2, navText, navActionTextOver, isresources, mentor_fk,
shortdescription, sequence
FROM dbo.Course where uid = @srcCourseID
set @trgCourseID = @@identity
--copy resources
insert into courseresources SELECT @trgCourseID, media_fk FROM dbo.courseresources WHERE (course_fk = @srcCourseID)
--step 2
DECLARE @chpID int
declare @trgChapterID int
declare @prmChapterID int
declare @srcMediaID int
declare @trgMediaID int
declare @srcMediaExt varchar(4)
declare @cmd varchar(200)
declare @TableVar table (
srcMediaID int,
trgMediaID int,
srcMediaExt varchar(4) 
DECLARE chapter_cursor CURSOR FOR
SELECT uid FROM chapter
WHERE course_fk = @srcCourseID
ORDER BY chaptersequence
OPEN chapter_cursor
FETCH NEXT FROM chapter_cursor
into @chpID
WHILE @@FETCH_STATUS = 0
BEGIN
--copy a chapter at a time
EXEC sprocket_copychapter @trgCourseID,@chpID, @prmChapterID OUTPUT
set @trgChapterID = @prmChapterID
--this is for copying the sample course, should gain insight so I can copy any course between clients later.
if @srcCourseID = @SampleCourseID
BEGIN
--so if media is associated with with this chapter get info and save it to tblVar so that I can process outside of tran
if exists (select chaptermedia_fk from chapter where uid= @trgChapterID)
BEGIN
select @srcMediaID = (select chaptermedia_fk from chapter where uid= @trgChapterID)
select @srcMediaExt = (select mediaext from mediabase where uid=@srcMediaID)
--make new media row
insert into mediabase SELECT mediasize, medialength, medialocalpath, medianame, mediaremoteurl, owner_fk, mediamimetype_fk, mediaext, mediatypename, displaywidth,
displayheight, shortname, author_fk, status_fk, keywords, usercategory, quizStorage, editable
FROM dbo.mediabase where uid=@srcMediaID
set @trgMediaID = @@identity
--update the new chapter with the new mediaID
update chapter set chaptermedia_fk = @trgMediaID where uid = @trgChapterID
--store values for file copy outside of transaction
insert into @TableVar (srcMediaID,trgMediaID,srcMediaExt) values (@srcMediaID, @trgMediaID,@srcMediaExt)
END
END
--step 3
exec sprocket_copyquestion @chpID, @trgChapterID, @trgCourseID
FETCH NEXT FROM chapter_cursor
INTO @ChpID
END
CLOSE chapter_cursor
DEALLOCATE chapter_cursor
declare @successreport int
if (@@error <> 0)
set @successreport = 0
else
set @successreport = 1
SET NOCOUNT OFF
if @successreport = 0
begin
rollback
end
else
begin
commit
--if it's sample course then copy neccessary files
if @srcCourseID = @SampleCourseID
BEGIN
--update the paths of any img tags in the chapter
declare @srcImgPath varchar(100)
declare @trgImgPath varchar(100)
set @srcImgPath = '/app1/clients/'+@srcClientDir
set @trgImgPath = '/app1/clients/'+@trgClientDir
update chapter set chapterinstructions=dbo.replace_regular_expression(chapterinstructions,@srcImgPath,@trgImgPath) where course_fk=@trgCourseID
update chapter set quizintroductiontext=dbo.replace_regular_expression(quizintroductiontext,@srcImgPath,@trgImgPath) where course_fk=@trgCourseID
update chapter set chapterintroductiontext=dbo.replace_regular_expression(chapterintroductiontext,@srcImgPath,@trgImgPath) where course_fk=@trgCourseID
update question set questiontext =dbo.replace_regular_expression(questiontext,@srcImgPath,@trgImgPath) where course_fk=@trgCourseID
update question set rightanswerdescription =dbo.replace_regular_expression(rightanswerdescription,@srcImgPath,@trgImgPath) where course_fk=@trgCourseID
update question set wronganswerdescription =dbo.replace_regular_expression(wronganswerdescription,@srcImgPath,@trgImgPath) where course_fk=@trgCourseID
update course set description =dbo.replace_regular_expression(description,@srcImgPath,@trgImgPath) where uid=@trgCourseID
update course set intro =dbo.replace_regular_expression(intro,@srcImgPath,@trgImgPath) where uid=@trgCourseID
END
end
SET ANSI_WARNINGS ON
SELECT * FROM @TableVar
GO
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 13, 2004 at 5:48 pm
Great article here about a problem returning a temp table from a stored procedure using OLEDB. Sure seems to fit my problem, but Im still fighting with it.
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 13, 2004 at 10:21 pm
I did a few tests:
CREATE PROCEDURE [dbo].[tblVarTest] AS
declare @TableVar table ( uid int)
insert into @TableVar (uid) values (1)
insert into @TableVar (uid) values (2)
insert into @TableVar (uid) values (3)
insert into @TableVar (uid) values (4)
select * from @tableVar
Generates the same error when called from ADO
CREATE PROCEDURE [dbo].[tblVarTest] AS
SET NOCOUNT ON
declare @TableVar table ( uid int)
insert into @TableVar (uid) values (1)
insert into @TableVar (uid) values (2)
insert into @TableVar (uid) values (3)
insert into @TableVar (uid) values (4)
select * from @tableVar
Does works with no error, however I still can't get my proc to work. I have tried placing the statment at the top, just above the final select, and in both places but I still get the error.
Any ideas welcome...
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 14, 2004 at 10:18 am
Had a brainwave this morning that since this proc calls two other proc's I should ensure that nocount is on in them as well. I had allot of hopes but they were dashed..same error.
I am almost at wits end. Doesn't help to have a conversation with myself in this forum. Guess I'll go post in experts-exchange.com
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 15, 2004 at 3:31 am
Leave the SET NOCOUNT ON active for the entire procedure...
At the end of your procedure you reverse course by SET NOCOUNT OFF....this will give you the typical '55 records updated' message....which is the 1st recordset ADO thinks it is receiving....
Alternatively you could do a getnextrecordset comand....and this should be the recordset containing your SELECT * FROM @Table data.
Totally seperately....I'd advise you to move away from the use of cursors...the poor performance hit is astronomical compared to doing things set-based....which is what SQLServer is designed for.
Unless you are comparing consecutative records together....99.9999% of the time there is no need for cursors and avoiding them will vastly improve the performance of your code.
January 15, 2004 at 6:03 am
or u can try...
SELECT * FROM @TableVar
SET NOCOUNT OFF
instead of
SET NOCOUNT OFF
...
SELECT * FROM @TableVar
HTH
Regards,
Sachin Dedhia
January 15, 2004 at 8:30 am
Well
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 15, 2004 at 8:31 am
hmmm forum only giving me one line for my reply
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 15, 2004 at 9:25 am
thats better...
well unfortunetly i think the fetch is neccessary and in this case probable more efficient then any sql statement that if even possible would have too many joins. The fetch set is only 10 - 30 records and this proc is only called when an account is created so it shouldn't be to often compared with other operations in the app. Within the fetch loop I use the fetched value to check some conditions perform a number of inserts, an update and various selects.
So looking back at the code I originaly posted and my now working code and it's hard for me to see all the differences. I think it was a combination of setting ansi warnings off and adding for read only to the cursor declarartion and open. Also not setting nocount off again as suggested.
But now I am having another problem. I am doing a statement like this:
insert into A select replace(fld,@srcVal,@trgValue) from B where...
when I call the proc from Query analyzer it runs fine, however when I call it from ADO OLEDB the fields using the replace() are NULL ??? (using the same account)
My state of confusion returns....
So my mostly working proc now looks like this:
CREATE proc sprocket_copycourse
@srcCourseID int,
@trgClientID int
as
SET NOCOUNT ON
SET ANSI_WARNINGS OFF
declare @SampleCourseID int
set @SampleCourseID = 78
declare @trgCourseID int
declare @srcClientDir varchar(16)
declare @trgClientDir varchar(16)
select @srcClientDir = (SELECT dbo.Client.directory FROM dbo.Course INNER JOIN dbo.Client ON dbo.Course.client_fk = dbo.Client.uid WHERE (dbo.Course.uid = @srcCourseID))
select @trgClientDir = (select dbo.Client.directory from dbo.Client where uid = @trgClientID)
declare @srcImgPath varchar(100)
declare @trgImgPath varchar(100)
set @srcImgPath = '/app1/clients/'+@srcClientDir
set @trgImgPath = '/app1/clients/'+@trgClientDir
begin tran
--step 1
insert into course SELECT @trgClientID, CourseName, TimeLimit, owner, CourseStatus_fk, toppic, toppich, toppicw, toppicalt, bottompic, bottompich, bottompicw, bottompicalt,
courseusername, coursepassword, hidecourseresults, showcoursereport, showcoursesignoff, completedlockout, replace([description],@srcImgPath, @trgImgPath),
replace(intro,@srcImgPath, @trgImgPath),conclusion, passpercent, showquestionpicture, showanswerpicture, autoplayansweraudio, autonext, moreinfo, askdemoquestions, publicmodule, contact,
recordtimetaken, reportsintrotext, insequence, insequencepass, shortname, author_fk, madelivedate, enrollreqd, fee, enrolluses, enrolldays,
usercategory, version, HideConclusionPageUntilDone, navBackground1, navBackground2, navText, navActionTextOver, isresources, mentor_fk,
shortdescription, [sequence]
FROM dbo.Course where uid = @srcCourseID
set @trgCourseID = @@identity
--copy resources
insert into courseresources SELECT @trgCourseID, media_fk FROM dbo.courseresources WHERE (course_fk = @srcCourseID)
--going to need a list of these as well...
--step 2
DECLARE @chpID int
declare @trgChapterID int
declare @prmChapterID int
declare @srcMediaID int
declare @trgMediaID int
declare @srcMediaExt varchar(4)
declare @cmd varchar(200)
declare @tblVar table (srcID int,trgID int, Ext varchar(4))
declare @chapter_cursor cursor
SET @chapter_cursor = CURSOR FOR
SELECT uid FROM chapter
WHERE course_fk = @srcCourseID
ORDER BY chaptersequence
FOR READ ONLY
OPEN @chapter_cursor
FETCH NEXT FROM @chapter_cursor
into @chpID
WHILE @@FETCH_STATUS = 0
BEGIN
insert into chapter SELECT passrequired4complete, chaptername, chapterstatus_fk, chaptersequence, mediamimetype_fk, chaptermedia_fk, @trgCourseID,
replace(chapterinstructions,@srcImgPath,@trgImgPath), chapterconclusiontext, ap_lesson, allowcontinue, showqpic, ap_qaudio, autonext, showapic, ap_aaudio, showadesc, subtractwrong, mediaurl,
randomquestionorder, randomanswerorder, showquizresults, Prerequisitecomplete, Prerequisitepass, passpercent, shortname,
replace(chapterintroductiontext,@srcImgPath,@trgImgPath), replace(quizintroductiontext,@srcImgPath,@trgImgPath), noshowcheckanswer, noshowresults, noshowweight, noshowback, forcecorrect, savemethod_fk,
noshownext, noshownumberlist, quizlockout, noshowjumplist, onlyshowscorewhenmarked, Showpasspercentrequired, showpassfail,
showmarkername, showmarkedstatus, Showscores, Showrightanswer, showquestioncorrectstatus, showquestionscore, showmarkercomment
FROM dbo.chapter where uid =@chpID
set @trgChapterID = @@identity
if @srcCourseID = @SampleCourseID
BEGIN
--so if media is associated with with this chapter get info and save for later
select @srcMediaID = (select chaptermedia_fk from chapter where uid= @trgChapterID)
select @srcMediaExt = (select mediaext from mediabase where uid=@srcMediaID)
--make new media row
if @srcMediaID <> ''
begin
insert into mediabase SELECT mediasize, medialength, medialocalpath, [medianame], mediaremoteurl, owner_fk, mediamimetype_fk, mediaext, mediatypename, displaywidth,
displayheight, shortname, author_fk, status_fk, keywords, usercategory, quizStorage, editable
FROM dbo.mediabase where uid=@srcMediaID
set @trgMediaID = @@identity
--update the new chapter with the new mediaID
update chapter set chaptermedia_fk = @trgMediaID where uid = @trgChapterID
--store values for file copy outside of transaction
insert into @tblVar (srcID,trgID,Ext) values (@srcMediaID, @trgMediaID,@srcMediaExt)
end
END
--step 3
insert into question SELECT [sequence], shortname, questiontype_fk, replace(questiontext,@srcImgPath,@trgImgPath), answers, rightanswer, anyright, replace(rightanswerdescription,@srcImgPath,@trgImgPath), replace(wronganswerdescription,@srcImgPath,@trgImgPath),
rightanswernext, wronganswernext, weight, @trgCourseID, status_fk, qpic, @trgChapterID, qpich, qpicw, qpicalt, apic, apicfilename, apictype, apich, apicw,
apicalt, apic2, apic2h, apic2w, apic2alt, audio_question, audio_right, audio_wrong, audio_question_filename, audio_right_filename,
audio_wrong_filename, optionimage1, optionimage2, optionimage3, optionimage4, optionimagealt1, optionimagealt2, optionimagealt3,
optionimagealt4, questiongroup_fk, answerText, required
FROM dbo.Question where chapter_fk = @chpID
FETCH NEXT FROM @chapter_cursor
INTO @ChpID
END
CLOSE @chapter_cursor
DEALLOCATE @chapter_cursor
declare @successreport int
if (@@error <> 0)
set @successreport = 0
else
set @successreport = 1
if @successreport = 0
begin
rollback
end
else
begin
commit
end
select * from @tblVar
GO
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 15, 2004 at 10:00 am
Go back to basic debugging principles.....Put in some PRINT statements before the INSERT statement to check what you think is being replaced and what you think it is being replaced with.....
January 15, 2004 at 10:58 am
Yes I did that. The vars contain what they are supposed to. But the proc is working fine from query analyer only not from ADO.
running this in qa performs the replaces as expected:
exec sprocket_copycourse @srcCourseID=78,@trgClientID=160
However from ASP ADO OLEDB
oCommand.activeconnection = cn
oCommand.commandtype = 4
oCommand.commandtext = "sprocket_copycourse"
oCommand.Parameters.Append oCommand.createparameter("@srcCourseID",3,1,4,78)
oCommand.Parameters.Append oCommand.createparameter("@trgClientID",3,1,4,vnewlID)
set rs = oCommand.execute
Does everything correct except that the fields inserted using the replace() are NULL. All the other fields in the inserted record are fine.
When running it from Query analyzer I log into the db with the same account I am using for the connection object.
For the life of me I can't figure out why I should get different results with the same account simply by calling the proc from a different place.
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 15, 2004 at 10:58 am
Yes I did that. The vars contain what they are supposed to. But the proc is working fine from query analyer only not from ADO.
running this in qa performs the replaces as expected:
exec sprocket_copycourse @srcCourseID=78,@trgClientID=160
However from ASP ADO OLEDB
oCommand.activeconnection = cn
oCommand.commandtype = 4
oCommand.commandtext = "sprocket_copycourse"
oCommand.Parameters.Append oCommand.createparameter("@srcCourseID",3,1,4,78)
oCommand.Parameters.Append oCommand.createparameter("@trgClientID",3,1,4,vnewlID)
set rs = oCommand.execute
Does everything correct except that the fields inserted using the replace() are NULL. All the other fields in the inserted record are fine.
When running it from Query analyzer I log into the db with the same account I am using for the connection object.
For the life of me I can't figure out why I should get different results with the same account simply by calling the proc from a different place.
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 15, 2004 at 12:26 pm
When you get different results in different environments, suspect some setting differs between the environments. Try adding this at the beginning of your stored procedure:
SET CONCAT_NULL_YIELDS_NULL OFF
--Jonathan
January 15, 2004 at 4:05 pm
Jonathan! You are the man!
SET CONCAT_NULL_YIELDS_NULL OFF
Ya know after all the other troubles I had with this procedure I was almost all outta fight. It was a fantastic learning event for me. I have stuck to basic SQL statements for so long. It's fun getting into what you can do with T-SQL.
my procedure is humming nicly and the feature is available to my users.
dave
Dave
Trainmark.com IT Training B2B Marketplace
(Jobs for IT Instructors)
January 16, 2004 at 9:28 am
If you are doing multiple things in the stored procedure, it may actually be returning multiple recordsets and the results you are really looking for will have to be accessed using the NextRecordset property of the Recordset object.
Set up a loop similiar to the following
Do
Set Rs = Rs.NextRecordset
If Rs Is Nothing Then
Else
If Rs.State = adStateOpen Then
If Rs.EOF = False Then
End If
End If
Loop Until itemsRs Is Nothing Or foundItems = 1
Viewing 15 posts - 1 through 15 (of 16 total)
You must be logged in to reply to this topic. Login to reply