Showing posts with label cursor. Show all posts
Showing posts with label cursor. Show all posts

Tuesday, March 20, 2012

Case in Where Clause

Can you put a Case statement in a Where clause?
I have the following Cursor I am setting up that is giving me the error:
Server: Msg 170, Level 15, State 1, Line 26
Line 26: Incorrect syntax near '>'.
Declare @.SearchCursor Cursor
Set @.SearchCursor = Cursor for Select
CommandText,WhereClause,SearchID,UserID
from CandidateSearches where SearchAgent=1 and SearchAgentActive=1 and
(CASE WHEN NotifyFrequency = 'D' THEN
(DATEDIFF(DAY,SearchAgentLastRun,GetDate
()) > 0)
WHEN NotifyFrequency = 'W' THEN
(DATEDIFF(DAY,SearchAgentLastRun,GetDate
()) >= 7)
WHEN NotifyFrequency = 'M' THEN
(DATEDIFF(DAY,SEarchAgentLastRun,GetDate
()) >= 30) END)
Line 26 is the line the Case Statement is on.
What is the problem with this line?
Thanks,
TomHi Tom
The most important thing to keep in mind is that there is no case STATEMENT
in Transact-SQL. There is a case EXPRESSION, which can be used anywhere you
use an expression. So, you can use a case EXPRESSION in a WHERE, in place of
a value.
Without any more details like the DDL, or a description of what you're
trying to accomplish, my guess is that you want to compare
DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) to one of several different
values, depending on the value of NotifyFrequency. If that is a correct
understanding, you might try something like this in your WHERE clause:
where SearchAgent=1 and SearchAgentActive=1 and
DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= CASE NotifyFrequency
WHEN 'D' THEN 0
WHEN 'W' THEN 7
WHEN 'M' THEN 30
END
Also make sure to consider the case where NotifyFrequency is not one of (D,
W, M)
--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com
"tshad" <tscheiderich@.ftsolutions.com> wrote in message
news:eeyXs5cMGHA.3960@.TK2MSFTNGP09.phx.gbl...
> Can you put a Case statement in a Where clause?
> I have the following Cursor I am setting up that is giving me the error:
> Server: Msg 170, Level 15, State 1, Line 26
> Line 26: Incorrect syntax near '>'.
> Declare @.SearchCursor Cursor
> Set @.SearchCursor = Cursor for Select
> CommandText,WhereClause,SearchID,UserID
> from CandidateSearches where SearchAgent=1 and SearchAgentActive=1 and
> (CASE WHEN NotifyFrequency = 'D' THEN
> (DATEDIFF(DAY,SearchAgentLastRun,GetDate
()) > 0)
> WHEN NotifyFrequency = 'W' THEN
> (DATEDIFF(DAY,SearchAgentLastRun,GetDate
()) >= 7)
> WHEN NotifyFrequency = 'M' THEN
> (DATEDIFF(DAY,SEarchAgentLastRun,GetDate
()) >= 30) END)
> Line 26 is the line the Case Statement is on.
> What is the problem with this line?
> Thanks,
> Tom
>|||"Kalen Delaney" <replies@.public_newsgroups.com> wrote in message
news:OQDXBGdMGHA.500@.TK2MSFTNGP15.phx.gbl...
> Hi Tom
> The most important thing to keep in mind is that there is no case
> STATEMENT in Transact-SQL. There is a case EXPRESSION, which can be used
> anywhere you use an expression. So, you can use a case EXPRESSION in a
> WHERE, in place of a value.
> Without any more details like the DDL, or a description of what you're
> trying to accomplish, my guess is that you want to compare
> DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) to one of several different
> values, depending on the value of NotifyFrequency. If that is a correct
> understanding, you might try something like this in your WHERE clause:
Exactly, but how would I do the instance where the case of 'D' is > 0 and
not >= 0?
Thanks,
Tom

> where SearchAgent=1 and SearchAgentActive=1 and
> DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= CASE NotifyFrequency
> WHEN 'D' THEN 0
> WHEN 'W' THEN 7
> WHEN 'M' THEN 30
> END
> Also make sure to consider the case where NotifyFrequency is not one of
> (D, W, M)
> --
> HTH
> Kalen Delaney, SQL Server MVP
> www.solidqualitylearning.com
>
> "tshad" <tscheiderich@.ftsolutions.com> wrote in message
> news:eeyXs5cMGHA.3960@.TK2MSFTNGP09.phx.gbl...
>
>|||I think what you are trying to do is this
Declare @.SearchCursor Cursor
Set @.SearchCursor = Cursor for Select
CommandText,WhereClause,SearchID,UserID
from CandidateSearches where SearchAgent=1 and
SearchAgentActive=1 and
((NotifyFrequency = 'D'
and DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) > 0) OR
(NotifyFrequency = 'W'
and DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 7) OR
(NotifyFrequency = 'M'
and DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 30))|||<markc600@.hotmail.com> wrote in message
news:1140022428.091421.209720@.g14g2000cwa.googlegroups.com...
>I think what you are trying to do is this
> Declare @.SearchCursor Cursor
> Set @.SearchCursor = Cursor for Select
> CommandText,WhereClause,SearchID,UserID
> from CandidateSearches where SearchAgent=1 and
> SearchAgentActive=1 and
> ((NotifyFrequency = 'D'
> and DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) > 0) OR
> (NotifyFrequency = 'W'
> and DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 7) OR
> (NotifyFrequency = 'M'
> and DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 30))
That was exactly what I ended up doing. I was just curious as to how to it
(if you can do it) using the Case statement.
Thanks,
Tom|||>> Declare @.SearchCursor Cursor
>That was exactly what I ended up doing. I was just curious as to how to it
>(if you can do it) using the Case statement.
You can do it using CASE, but it doesn't let you do anything that AND,
OR and () don't already let you do. Since it resolves to a values,
you have to use it to set a value that indicates success or failure,
then test that in a comparison.
SELECT CommandText, WhereClause, SearchID, UserID
FROM CandidateSearches
WHERE SearchAgent=1
AND SearchAgentActive=1
AND CASE
WHEN NotifyFrequency = 'D'
AND DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) > 0
THEN 1
WHEN NotifyFrequency = 'W'
AND DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 7
THEN 1
WHEN NotifyFrequency = 'M'
AND DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 30
THEN 1
ELSE 0
END = 1
Roy|||"Roy Harvey" <roy_harvey@.snet.net> wrote in message
news:31l7v1dnjf97n234q7ih23mnbq4rtti9u1@.
4ax.com...
> You can do it using CASE, but it doesn't let you do anything that AND,
> OR and () don't already let you do. Since it resolves to a values,
> you have to use it to set a value that indicates success or failure,
> then test that in a comparison.
> SELECT CommandText, WhereClause, SearchID, UserID
> FROM CandidateSearches
> WHERE SearchAgent=1
> AND SearchAgentActive=1
> AND CASE
> WHEN NotifyFrequency = 'D'
> AND DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) > 0
> THEN 1
> WHEN NotifyFrequency = 'W'
> AND DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 7
> THEN 1
> WHEN NotifyFrequency = 'M'
> AND DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 30
> THEN 1
> ELSE 0
> END = 1
>
I was as to what this did at first, but then I realized what it was
doing.
In the "OR" example, I would only get a record if one of the 3 tests (as
well as the SearchAgent and SearchAgentActive) were matched.
In your example, you are testing if the Case statement was "1". It was
clear when I put parens around the case statement. I thought at first you
were setting "End=1". But when I put the parans in, it made sense:
... AND (CASE
WHEN NotifyFrequency = 'D'
AND DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) > 0
THEN 1
WHEN NotifyFrequency = 'W'
AND DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 7
THEN 1
WHEN NotifyFrequency = 'M'
AND DATEDIFF(DAY,SearchAgentLastRun,GetDate(
)) >= 30
THEN 1
ELSE 0
END) = 1
I think that is what is happening.
But as you said the OR does the same thing and is a little more clear and
you don't have to do the extra step of setting it to 0 or 1.
Thanks,
Tom
> Roy

Sunday, February 12, 2012

Cant use cursor with SP

Hi

I have a SP and in it I call another SP which returns one row in one column, I need to concatenate the value (varchar) to the query in the first SP.
I tried to use cursor with FAST_FORWARD to fetch the result and concatenate it, but I get an error, here is what I tried:

DECLARE Cur CURSOR FAST_FORWARD
FOR SP_Something @.SomeValue

So is it possible to use cursor on SP ? And if it's possible so how ?

Thanks,

Inon.I don't think so...why not put the result set into a table variable?|||I don't think so...why not put the result set into a table variable?

This also don't work, I get an error when I try to INSERT the result from the inner SP to a table var... so is THIS option possible ??

I just want to add that I have several ways to make this work, but I'm trying to be efficient, this is why I want to use an inner SP and not just make the process in the same big SP, I can also make changes in the code (PHP) but I'm trying to make it work this way.

Thanks,

Inon.|||doooh

Yup...can't do that...but you can do

USE Northwind
GO

SET NOCOUNT ON
GO

CREATE PROC mySproc99
AS
SELECT OrderId FROM Orders
GO

CREATE TABLE #myTemp99(OrderId int)

INSERT INTO #myTemp99(OrderId) EXEC mySproc99

SELECT * FROM #myTemp99
GO

SET NOCOUNT ON
DROP TABLE #myTemp99
DROP PROC mySproc99
GO|||doooh

Yup...can't do that...but you can do

USE Northwind
GO

SET NOCOUNT ON
GO

CREATE PROC mySproc99
AS
SELECT OrderId FROM Orders
GO

CREATE TABLE #myTemp99(OrderId int)

INSERT INTO #myTemp99(OrderId) EXEC mySproc99

SELECT * FROM #myTemp99
GO

SET NOCOUNT ON
DROP TABLE #myTemp99
DROP PROC mySproc99
GO

Hmmm... there goes the efficient part... :)

Inon.|||Well...

I don't think (I hate when that happens) that I would ever use effecient and cursor in the same sentence...

Unless it was like

"I wish the developer wrote effecient code instead of using a cursor"

:D|||Well...

I don't think (I hate when that happens) that I would ever use effecient and cursor in the same sentence...

Unless it was like

"I wish the developer wrote effecient code instead of using a cursor"

:D

I agree, didn't mean to express discontent of your solution BTW...

You see, the DB is for a web page, that SP will be called many times.

Thanks for the help,

Inon.|||I'm not sure what you're trying to do, but it looks like you want to use a SP to return a varchar that contains a query that you then want to execute - am I right ?

If so, try making the SP a function, viz:

create function dbo.some_func (@.inp_value char(?))
returns varchar(100)
as
begin
declare @.temp_var varchar(100)

set @.temp_var = 'select * from ' + @.inp_value
return @.temp_var

end

then in your calling sp:

select @.mysql = some_func(@.parm)
execute(@.mysql)

HTH|||I'm not sure what you're trying to do, but it looks like you want to use a SP to return a varchar that contains a query that you then want to execute - am I right ?

Almost right, the inner SP returns only a string that will be concatenate to the query in the outer SP, meaning, the inner SP returns only a part of a query, not entire query.

I have a SP that returns a result, I want to use this result in another SP, I didn't want to run both queries because (and correct me if I'm wrong) I know that for optimal performance it's not recommended to run two separated queries on two table in one SP, because the optimizer will confuse with the best execution plans for each query...

Anyway, this is what I finally did, ran both in one SP... is it as bad as I think ?? And should I just make some process in the code and just run two separated SPs? I wanted to make it in one connection session since it will run many many times and by using one SP I cut traffic (for this option only of course) in 50%...

So what do you say is better? One SP with two queries or two SP's with two connections? (But each has its own optimal execution plan).

Thanks,

Inon.