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)
 Cursor Help!

Author  Topic 

haoest
Starting Member

8 Posts

Posted - 2008-08-08 : 20:23:41
hello,

My first time using cursor.

So I have a cursor variable opened and the values fetched into @a and @b. Is there any ways I can update @a or @b, or any other ways, so that the changes will be made to the real value that they correspond to from the original row?

Thanks,
Hao


Vinnie881
Master Smack Fu Yak Hacker

1231 Posts

Posted - 2008-08-08 : 21:08:29
It sounds like you want a update statement not a cursor please post your table structure and sample data and desired output.
Go to Top of Page

haoest
Starting Member

8 Posts

Posted - 2008-08-08 : 21:25:53
I think I got it

update MyTable set column_A = 'my_value'
where CURRENT of MyCursor

Thanks though. If you see anything wrong with that statement, please let me know.

Go to Top of Page

Vinnie881
Master Smack Fu Yak Hacker

1231 Posts

Posted - 2008-08-08 : 22:14:27
I don't think you need to us a cursor. If you post your table info some sample data and a desired output, then there is good chance someone can help you with a better alternative.
Go to Top of Page

haoest
Starting Member

8 Posts

Posted - 2008-08-09 : 12:19:40
I have a question table with answers which the user has entered. It looks like this:



I have a stored procedure called GetAllRejectedAnswers that returns the ID of all rows whose AnswerValue matches RejectableAnswer. Up until now, the RejectableAnswer was always a single value such as 'Yes' or 'No', which is easy, so row with id 3 in my sample table would be returned by the stored procedure. My job now is to extend the rejectable validator to check for an expression in the RejectableAnswer field, such as the one in Row 4, which means the row is returned if the answer to Question 3 is 'Yes' AND the answer to 4 is 'No'. In this example it should returned because Answer to 3 is indeed 'Yes' and 4 'No'. In reality though, AnswerValue is not limited to 'Yes' or 'No', it could be words or numbers, in which case I still like my method to evaluate the expression in RejectableAnswer field and return a correct result set. As far as I know, evaluating data as an expression is another dimension, so to run dynamic SQL I created another helper SP called CheckRejectability, which takes a @RejectableExpression and returns 1 if the expression in the parameter is evaluated to true, 0 otherwise.

All that has been done and working. The biggest challenge for me know is to integrate the CheckRejectability SP with my main query. To start, I acted like a noob and had something like this:

select id from Answers
where (exec CheckRejectability @RejectableExpression=RejectAnswer)

which doesn't work because the syntax is not correct. I also tried converting the helper SP into a user defined function, but I was cornered by the limitations of UDF.

So that's my challenge, I am left with cursors to solve the problem. Do you see a better way?
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-08-09 : 12:39:20
you can convert the stored procedure to a UDf which returns the value and use it like this

select id from Answers a
cross apply CheckRejectability (RejectAnswer) b
where b.returnfield=1
Go to Top of Page

GilaMonster
Master Smack Fu Yak Hacker

4507 Posts

Posted - 2008-08-09 : 14:14:05
Can you post the definition of CheckRejectability please?

--
Gail Shaw
SQL Server MVP
Go to Top of Page

haoest
Starting Member

8 Posts

Posted - 2008-08-09 : 22:24:49
quote:
Originally posted by GilaMonster

Can you post the definition of CheckRejectability please?

--
Gail Shaw
SQL Server MVP



I don't have it with me as it's in the computer at work, but it basically builds a dynamic SQL string with the @RejectableExpression in it somewhere, and then I run Exec() on it. It looks back at the answer table and see if the expression is true or false.

If I were to pull it up from memory, it would be something like this:

set @sqlstr = replace(@rejectableExpression, '[', 'select answerValue from Answers where id = ')

... I call replace() again just to make @sqlstr a valid sql statement. I don't think the detail is too important here...

In the end I do this:

set @sqlstr = 'select case when (' + @sqlstr + ') 1 else 0 end'

select into #mytmp exec(@sqlstr)

Now come to think of it, I have a @ReturnValue (int) output parameter initialized to 0, which is only used for better usability. Anyways, i do this in the very end:

if (select count(*) from #mytmp) > 0
select @ReturnValue = retval from #mytmp

I tried UDF like visakh16 recommended, but with exec(), selecting from a permanent table, try/catch, and other small stuff, UDF doesn't like it and spits Time-dependent error at me.
Go to Top of Page

Vinnie881
Master Smack Fu Yak Hacker

1231 Posts

Posted - 2008-08-10 : 01:08:19
Please post your actual procedure. In all liklyhood it can be tweeked to be a function. Second the method you described here has a huge amount of potential issues, are you stuck using this methodolgy to validate the answeres (I am referring to te layout and structure), or would you like to discuss possible better alternatives?
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-08-10 : 02:32:30
quote:
Originally posted by haoest

quote:
Originally posted by GilaMonster

Can you post the definition of CheckRejectability please?

--
Gail Shaw
SQL Server MVP



I don't have it with me as it's in the computer at work, but it basically builds a dynamic SQL string with the @RejectableExpression in it somewhere, and then I run Exec() on it. It looks back at the answer table and see if the expression is true or false.

If I were to pull it up from memory, it would be something like this:

set @sqlstr = replace(@rejectableExpression, '[', 'select answerValue from Answers where id = ')

... I call replace() again just to make @sqlstr a valid sql statement. I don't think the detail is too important here...

In the end I do this:

set @sqlstr = 'select case when (' + @sqlstr + ') 1 else 0 end'

select into #mytmp exec(@sqlstr)

Now come to think of it, I have a @ReturnValue (int) output parameter initialized to 0, which is only used for better usability. Anyways, i do this in the very end:

if (select count(*) from #mytmp) > 0
select @ReturnValue = retval from #mytmp

I tried UDF like visakh16 recommended, but with exec(), selecting from a permanent table, try/catch, and other small stuff, UDF doesn't like it and spits Time-dependent error at me.


if you cant go for UDF method you could also try using OPENROWSET method to get the result of procedure onto WHERE clause of select. something like:-

select id from Answers
where (SELECT returnfield
FROM OPENROWSET('SQLNCLI', 'Server=yourserver;Trusted_Connection=yes;',
'exec CheckRejectability @RejectableExpression=RejectAnswer') =1


i'vent tested this so not fully sure if this works but you try this out.
Go to Top of Page

haoest
Starting Member

8 Posts

Posted - 2008-08-10 : 15:34:49
quote:
Originally posted by Vinnie881

Please post your actual procedure. In all liklyhood it can be tweeked to be a function. Second the method you described here has a huge amount of potential issues, are you stuck using this methodolgy to validate the answeres (I am referring to te layout and structure), or would you like to discuss possible better alternatives?



I would love to move the validation to C# level, but there's much work that's been done in SQL level that I can not take advantage of if I do so. I will post the exact code first thing tomorrow. And can you think of any potential risks if I do it this way? I was guessing performance would take a hit because of cursors and exec() from recompilation and stuff.

And visakh16, I would love to give OpenRowSet a try. The first impression it gives me though, is that it opens a new connection. Even if it connects to the same server, does it take a lot of overhead?

Go to Top of Page

haoest
Starting Member

8 Posts

Posted - 2008-08-11 : 12:24:52
Hi, here's what the SP looks like, can you see anything wrong with it?
[url]http://img196.imagevenue.com/img.php?image=71736_sp_122_514lo.jpg[/url]

Here's the equivalent in textual form:

CREATE PROCEDURE [dbo].CheckRejectability
@exp varchar(7000), @returnValue int output
AS
BEGIN
SET NOCOUNT ON;
declare @s varchar(8000)
if object_id('tempdb..#risk_rej_check_session') is not null
drop table #risk_rej_check_session
set @returnValue = 0
begin try
set @exp = replace(@exp, '[', '(select answervalue from Answers ' +
'where QuestionID = ''')
set @exp = replace(@exp, ']', ''')')
set @s = 'select case when (' + @exp + ') then 1 else 0 end as returnValue '
create table #risk_rej_check_session (returnValue int)
insert into #risk_rej_check_session exec(@s)
end try
begin catch
end catch
-- select @s
if ((select count(0) from #risk_rej_check_session) > 0) begin
select @returnValue = returnValue from #risk_rej_check_session
end
drop table #risk_rej_check_session
END

Go to Top of Page
   

- Advertisement -