| 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. |
 |
|
|
haoest
Starting Member
8 Posts |
Posted - 2008-08-08 : 21:25:53
|
| I think I got itupdate MyTable set column_A = 'my_value' where CURRENT of MyCursorThanks though. If you see anything wrong with that statement, please let me know. |
 |
|
|
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. |
 |
|
|
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 Answerswhere (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?![]() |
 |
|
|
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 thisselect id from Answers across apply CheckRejectability (RejectAnswer) bwhere b.returnfield=1 |
 |
|
|
GilaMonster
Master Smack Fu Yak Hacker
4507 Posts |
Posted - 2008-08-09 : 14:14:05
|
| Can you post the definition of CheckRejectability please?--Gail ShawSQL Server MVP |
 |
|
|
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 ShawSQL 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 #mytmpI 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. |
 |
|
|
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? |
 |
|
|
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 ShawSQL 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 #mytmpI 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 Answerswhere (SELECT returnfieldFROM OPENROWSET('SQLNCLI', 'Server=yourserver;Trusted_Connection=yes;', 'exec CheckRejectability @RejectableExpression=RejectAnswer') =1i'vent tested this so not fully sure if this works but you try this out. |
 |
|
|
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? |
 |
|
|
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 outputASBEGIN 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_sessionEND |
 |
|
|
|