473,396 Members | 1,738 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

stuck again, if else after where clause

So thanks to another member here I got my view sorted out :D but now that I've begun to write my stored proc I've ran into another problem!

Basically, my stored proc takes about 30 variables and I want to build a WHERE CLAUSE constraint upon these variables. Only thing is, I would like to check the variable values before adding them to the WHERE clause and if the value of the variable is null or "" then I would like to omit the constraint from the Clause.

Here's a simple example of what I'd like to do:

Select * from TestTable

Where

If (@Variable1 is not null AND @Variable1 <> "")
begin
Column1FromTestTable = @Variable1
end

If (@Variable2 is not null AND @Variable2 <> "")
begin
AND Column2FromTestTable = @Variable2
end

etc....


Is something like this possible? Because I've been looking at Books Online for MSSQL 2k5 and searched the web without any conclusive answers.

Many thanks

Davinski
Mar 27 '07 #1
28 7173
iburyak
1,017 Expert 512MB
Try this:


select *
from TestTable
where column1 like case when isnull(@Variable1,'') = '' then '%' else @Variable1 end
and column2 like case when isnull(@Variable2,'') = '' then '%' else @Variable1 end
and .....
This way if Variable is null or '' will be replaced with % which basically selects all from this column.

Good Luck

Irina.
Mar 27 '07 #2
iburyak
1,017 Expert 512MB
Correction


[PHP]select *
from TestTable
where column1 like case when isnull(@Variable1,'') = '' then '%' else @Variable1 end
and column2 like case when isnull(@Variable2,'') = '' then '%' else @Variable2 end
and ..... [/PHP]
Mar 27 '07 #3
Hello,

Thanks for the prompt reply and answer. Good news is that when I use your syntax template in my stored proc I don't get any error messages, only thing is that I can't test it because I don't have any data in my table yet :S

I've been taking another look at Books Online to make sense of your syntax however I get a little confused.

I think I understand

... where column1 like (uses the like to compare, this is the left side)
case (start use of case statement)
when isnull(@Variable1,'') = '' (isnull converts Variable1 to '' if @Variable1 is null' then it is compared with '' to go to)
then '%' (I don't understand this part)
else @Variable1
end

So what I'm not understanding clearly is the comparison of using like with column1 and '%'

I'm not sure what this does. Can someone explain please?

Also, what is the implications when using the like command with nvarchars, will the above syntax still hold true and do what I require?

Many thanks again

Davinski




Correction


[PHP]select *
from TestTable
where column1 like case when isnull(@Variable1,'') = '' then '%' else @Variable1 end
and column2 like case when isnull(@Variable2,'') = '' then '%' else @Variable2 end
and ..... [/PHP]
Mar 27 '07 #4
iburyak
1,017 Expert 512MB
OK
Like is comparison operator like “=” or “>” or “<”.
When you can use like you can use wild cards instead of actual values.

Try these examples:

[PHP]select * from sysobjects where name like '%' order by name

-- above is the same as because % means everything
select * from sysobjects

-- next means I want all names that start with sys
select * from sysobjects where name like 'sys%' order by name[/PHP]


1 case (start use of case statement)
2 when isnull(@Variable1,'') = '' --(isnull converts Variable1 to '' if @Variable1 is null' then it is compared with '' to go to)
3 then '%' --(I don't understand this part)
4 else @Variable1
5 end
So in line 2 I check if variable is null then I convert it to '' if it is '' then it is already '' and will be as is
in both cases null or '' they will be converted to '' and compared if it is true or not.
If it is TRUE and variable is null or '' we go to line 3
Here I convert result to % meaning give me everything from this column no conditions.
If it is FALSE we go to line 4 and get what is in a variable no wild cards involved.



To test me do following:

[PHP]-- 1. Create test proc
Create proc GetObjectName
@Name varchar(30) = Null
AS

select * from sysobjects
where name like case when isnull(@Name, '') = '' then '%' else @Name end

-- 2. Execute proc with different parameters and see results.
EXEC GetObjectName
EXEC GetObjectName Null
EXEC GetObjectName ''
EXEC GetObjectName 'syscolumns'
EXEC GetObjectName 'sys%'[/PHP]

Good Luck
Mar 27 '07 #5
Thank you so much for the explanation, it was enlightening and you do truely know what you are doing!

In light to understand your methods more completely, I also created a Test Database with 1 table.

What I found was that the 'like' comparison doesn't hold true for int, or should I say that when the column definition is an 'int' and the variable is passed through as null, the int column definition gets compared with '%' which I believe is where my Query Editor is reporting an error.

Would it be possible for you to modify your template to accomodate for 'int' and 'bit' column definitions?

Many thanks

Davinski
Mar 28 '07 #6
iburyak
1,017 Expert 512MB
I don't think this is a problem.

To test me execute following statements:


[PHP]select * from sysobjects where id like '%' -- id is int
select * from syscomments where encrypted like '%' -- encrypted is bit[/PHP]
Mar 28 '07 #7
Right you are iburyak!!!

using like '%' on int and encrypted bits works just fine and it's great, thank you.

I have however stumbled upon a small problem with your template that maybe you can solve, that is in using your template I tried to do the following, nAge is of int definition.

Expand|Select|Wrap|Line Numbers
  1. nAge like 
  2.     case 
  3.     when isnull(@nAge,'') = '' 
  4.         then '%' 
  5.         else @nAge 
  6.     end
  7.  
This works fine if the variable @nAge is NULL, however if @nAge is in integer value, I receive an error.

Any ideas? I think it might have something to do with the like comparison on integers?

Thanks

Davinski



I don't think this is a problem.

To test me execute following statements:


[PHP]select * from sysobjects where id like '%' -- id is int
select * from syscomments where encrypted like '%' -- encrypted is bit[/PHP]
Mar 28 '07 #8
iburyak
1,017 Expert 512MB
Unfortunately I can't reproduce your error. It is possible that my server version handles it differently...

But I have a hunch on what might happen.
Statement below returns mixed datatypes in True case it returns character datatype and in False it is integer.

[PHP]case
when isnull(@nAge,'') = ''
then '%'
else @nAge
end[/PHP]

Try to do following:
[PHP]nAge like
case
when isnull(@nAge,'') = ''
then '%'
else cast(@nAge AS varchar(20))
end[/PHP]

Show me full text of error message if any.

Thank you.
Mar 28 '07 #9
iburyak, many thanks, I can see how your cast will work however I can't test it right now because I've created another error :S btw the error before was something along the lines of

Expand|Select|Wrap|Line Numbers
  1. Conversion failed when converting the varchar value '%' to data type int.
  2.  
I'll let you know how I get on with your CAST, however one other little modification to your template if you could as that is if I wanted to test for

Expand|Select|Wrap|Line Numbers
  1. nAge > @nAge
  2.  
based on an input Variable for example @bMoreOrLessThanAge

in psuedo I'd like

Expand|Select|Wrap|Line Numbers
  1. @nAge int,
  2. @bMoreOrLessThanAge int
  3.  
  4. select * from TestTable 
  5.  
  6. Where 
  7.  
  8. if nAge is NOT NULL
  9. begin
  10. if @bMoreOrLessThanAge = 0
  11.  
  12. nAge > @nAge
  13.  
  14. else if @bMoreOrLessThanAge = 1
  15.  
  16. nAge < @nAge
  17.  
  18. end
  19.  
  20.  

I hope you understand my scribbling, and hope you've got some suggestions?

Thanks again

Davinski
Mar 28 '07 #10
iburyak
1,017 Expert 512MB
Try this:

[PHP]@nAge int,
@bMoreOrLessThanAge int

select * from TestTable
where nAge between case when nAge is NULL then 0
when @bMoreOrLessThanAge = 0 then @nAge
when @bMoreOrLessThanAge = 1 then 0
end
and case when nAge is NULL then 200
when @bMoreOrLessThanAge = 0 then 200
when @bMoreOrLessThanAge = 1 then @nAge
end[/PHP]

In this case when
1. nAge is NULL you select nAge between 0 and 200 which basically all available valid age values
2. @bMoreOrLessThanAge = 0 you select nAge between @nAge and 200 which is basically >
3. @bMoreOrLessThanAge = 1 you select nAge between 0 and nAge which is basically <
Mar 28 '07 #11
Hey, that last example works great, amazing!

Can you help me find out what the problem is with this snippet of your template?

Expand|Select|Wrap|Line Numbers
  1.  
  2. nAge like 
  3.     case 
  4.     when isnull(@nAge,'') = '' 
  5.     then '%'
  6.     else @nAge
  7.     end
  8.  
When I run the stored proc and @nAge is NULL I get this error

Expand|Select|Wrap|Line Numbers
  1.  
  2. Conversion failed when converting the varchar value '%' to data type int.
  3.  
  4.  
Can you help me understand why I'm getting this error?

Thanks again

Davinski
Mar 28 '07 #12
iburyak
1,017 Expert 512MB
Did you try my previous suggestion?

[PHP]
nAge like
case
when isnull(@nAge,'') = ''
then '%'
else cast(@nAge AS varchar(20))
end [/PHP]
Mar 28 '07 #13
iburyak,

Yes I've tried your previous suggestion with absolute success :D

I just don't understand the cryptic message when I don't use the CAST

Expand|Select|Wrap|Line Numbers
  1. Conversion failed when converting the varchar value '%' to data type int.
  2.  
I think that this message does not relate to this line does it?

Expand|Select|Wrap|Line Numbers
  1. then '%'
  2.  
Thanks for all of your help

Davinski



Did you try my previous suggestion?

[PHP]
nAge like
case
when isnull(@nAge,'') = ''
then '%'
else cast(@nAge AS varchar(20))
end [/PHP]
Mar 28 '07 #14
iburyak
1,017 Expert 512MB
Message does relate to this line but you should ignore it if it all works.
You have to understand that on the left side you have integer and on the right side you have character data that is converted to int according to situation if possible. In our case it is possible. Why I had to convert @nAge to character datatype because ‘%’ is a character and parser wants to be consistent and always return the same datatype on the right side of equation.

Try all possible parameters to make sure everything works.

I do believe you need to do some upgrade or latest service pack on SQL Server.
I used to have errors like that but not any more.

My server is constantly upgraded to latest Service packs by DBA team.

Good Luck.
Mar 28 '07 #15
Wow, do you ever sleep? you're like a machine!!!

Just one last anomaly I think, and that is when I use your template on a column in the table that is declared as a bool, bActive and in the stored procedure I take a variable defined as a bit, @bActive (the reasoning for it being a bit definition is to do with nettiers), when I run my stored proc, for null values and value of 1 I get the disired results, however passing the @bActive a 0 returns everything and I would just like to return the rows which are False, what am I doing wrong?

Here is some code

Expand|Select|Wrap|Line Numbers
  1.  
  2. bActive is defined as a bool in the table definition.
  3.  
  4.  
  5.  
  6.  
  7. @bActive bit,
  8.  
  9. select * from TestTable where
  10.  
  11. bActive like 
  12.     case 
  13.         when isnull(@bActive,'') = '' 
  14.         then '%'
  15.         else cast(@bActive AS char(20))
  16.  
  17.         end
  18.  
  19.  
Any ideas on why I'm not able to just retreive the rows that are false?

if I pass 1 to @bActive variable and get all the rows which are True, null and I get everything, but 0 I get everything too? that shouldn't be happenning should it?

Thanks

Davinski


Message does relate to this line but you should ignore it if it all works.
You have to understand that on the left side you have integer and on the right side you have character data that is converted to int according to situation if possible. In our case it is possible. Why I had to convert @nAge to character datatype because ‘%’ is a character and parser wants to be consistent and always return the same datatype on the right side of equation.

Try all possible parameters to make sure everything works.

I do believe you need to do some upgrade or latest service pack on SQL Server.
I used to have errors like that but not any more.

My server is constantly upgraded to latest Service packs by DBA team.

Good Luck.
Mar 28 '07 #16
iburyak
1,017 Expert 512MB
Change

[PHP]@bActive bit,

select * from TestTable where

bActive like
case
when isnull(@bActive,'') = ''
then '%'
else cast(@bActive AS char(20))

end[/PHP]

To

[PHP]@bActive char(1),

select * from TestTable where

bActive like
case
when isnull(@bActive,'') = ''
then '%'
else @bActive

end[/PHP]

It is just a work around. It shoud work but it looks like it converts bit to char(20) incorrectly and then it is lost at all.
Mar 29 '07 #17
iburyak
1,017 Expert 512MB
I am in a different time zones with you it is 8:00 PM my time... :)
Mar 29 '07 #18
Thanks for the work around, I'm yet to test it with CodeSmith and nettiers but I think it might cause a problem :S not sure.

Is there another work around or is the problem caused by my SQL server not being up to date?

I'm using MSSQL 2005 but it might not be patched and up to date.

Many thanks for any insight or other work arounds.

Davinski

Change

[PHP]@bActive bit,

select * from TestTable where

bActive like
case
when isnull(@bActive,'') = ''
then '%'
else cast(@bActive AS char(20))

end[/PHP]

To

[PHP]@bActive char(1),

select * from TestTable where

bActive like
case
when isnull(@bActive,'') = ''
then '%'
else @bActive

end[/PHP]

It is just a work around. It shoud work but it looks like it converts bit to char(20) incorrectly and then it is lost at all.
Mar 29 '07 #19
iburyak
1,017 Expert 512MB
You didn't try a solution and asking for another one....
It sounds strange. You think I made it up or just guessed it?
Mar 29 '07 #20
Yes I am sorry that I did not try your other solution before requesting another one however I am simply trying to cover all bases and as we all are able to use our experience from similar problems to solves new ones. And I believe I made a good judgement call with the Codesmith and Nettiers constraint on the problem I have so given forth.

I'm sure you didn't make anything up or guess your solution, but I am now confident that your last solution will not work for me. The reason why is as I've said before is that I am using Codesmith and Nettiers.

In my aspx page I will have many textboxes, many drop downs and checkboxes in a search page.

And from my .cs file on postback I would make a call something similar to

DataRepository.MyTable.DoSearch(TextBox1Value, DropDown1Value, CheckBox1Value);

Now from the above code, it will call the relevant stored procedure in my MSSQL 2k5 db, namely here DoSearch which would take in variables as

DoSearch( nvarchar(50), int, bit)

The reason why the last variable is required to be a 'bit' is because although in C# the definition of checkbox values are of type bool, the equivelent in the db is of type bit so the conversion by Enterprise Manager is automatic.

I therefore cannot have my stored proc be

DoSearch( nvarchar(50), int, char(1))

Because this conversion will simply just NOT happen.

So I only see two solutions,

1. I convert the bool to char(1) in C# which is something really rubbish before calling my stored proc.

2. Read the value as type BIT in the stored proc then do the conversion within DB which we have already seen not to work.


The other constraint on the design of the stored proc is that if a checkbox is not selected, a drop down is not selected OR a textbox is not filled, then ALL the results from the DB is returned and is only constrained by the particular fields the user selects, for example, ticks a checkbox or fills in a textbox.




This is then simply the reason why I asked you if there was something wrong with my MSSQL2k5 server or if there was another solution that from your experience you might know of and wouldn't mind sharing.

Many thanks

Davinski











You didn't try a solution and asking for another one....
It sounds strange. You think I made it up or just guessed it?
Mar 30 '07 #21
iburyak
1,017 Expert 512MB
I hope one of these would work:

1.
[PHP]@bActive bit,

select * from TestTable where

bActive like case when @bActive is null then '%' else cast(@bActive AS varchar(20)) end [/PHP]

2.

[PHP]@bActive bit,

select * from TestTable where

(
bActive = case when isnull(@bActive,'') = '' then 0 else @bActive end
or
bActive = case when isnull(@bActive,'') = '' then 1 else @bActive end
)[/PHP]
Mar 30 '07 #22
iburyak
1,017 Expert 512MB
Correction to number 2.

[PHP]
@bActive bit,

select * from TestTable where

(
bActive = case when @bActive is null then 0 else @bActive end
or
bActive = case when @bActive is null then 1 else @bActive end
)[/PHP]

Good Luck.
Mar 30 '07 #23
Yay, finally, this is the solution, the one below is what I've been looking for and fulfills all the conditions required.

Many thanks for all your 'Thinking' whether it was hard for you or not; it would have definately been hard for me!

Regards

Davinski



Correction to number 2.

[PHP]
@bActive bit,

select * from TestTable where

(
bActive = case when @bActive is null then 0 else @bActive end
or
bActive = case when @bActive is null then 1 else @bActive end
)[/PHP]

Good Luck.
Mar 30 '07 #24
iburyak
1,017 Expert 512MB
Did you try this one? It is more compact and consistent with other cases you are going to use.


[PHP]
@bActive bit,

select * from TestTable where

bActive like case when @bActive is null then '%' else cast(@bActive AS varchar(20)) end [/PHP]



@bActive is null - solved the problem.

It looks like isnull(@bActive ,'') was converting variable itself which is a bug and shouldn't happen.
Mar 30 '07 #25
Correction


[PHP]select *
from TestTable
where column1 like case when isnull(@Variable1,'') = '' then '%' else @Variable1 end
and column2 like case when isnull(@Variable2,'') = '' then '%' else @Variable2 end
and ..... [/PHP]
For my current project I am in the same situation. I tried this solution and I'm not getting any results (records) from this code.

We have a user interface where a person enters in someone's personal data (ie. first name, last name, address, etc.) and the program runs the below query.

[PHP]
SELECT CustID, LName, FName, MI, Address1, Address2,
City, State, Sex, Zip, Birthdate
FROM Customers
WHERE LName LIKE '%' + @LName + '%' AND
FName LIKE @FName + '%' AND
Address1 LIKE CASE WHEN isnull(@Address1,'') = '' THEN '%' ELSE @Address1 END AND
City LIKE CASE WHEN isnull(@City,'') = '' THEN '%' ELSE @City END AND
State LIKE CASE WHEN isnull(@State,'') = '' THEN '%' ELSE @State END AND
Zip LIKE CASE WHEN isnull(@Zip,'') = '' THEN '%' ELSE @Zip END AND
Birthdate LIKE CASE WHEN isnull(@Birthdate,'') = '' THEN '%' ELSE @Birthdate END
[/PHP]

But when I run this, I get only people with blank addresses.

Any suggestions?
Apr 19 '07 #26
iburyak
1,017 Expert 512MB
I suspect you pass spaces somewhere.

Try this:

[PHP]
SELECT CustID, LName, FName, MI, Address1, Address2,
City, State, Sex, Zip, Birthdate
FROM Customers
WHERE LName LIKE '%' + @LName + '%' AND
FName LIKE @FName + '%' AND
Address1 LIKE CASE WHEN isnull(RTRIM(@Address1),'') = '' THEN '%' ELSE @Address1 END AND
City LIKE CASE WHEN isnull(RTRIM(@Address1),'') = '' THEN '%' ELSE @City END AND
State LIKE CASE WHEN isnull(RTRIM(@Address1),'') = '' THEN '%' ELSE @State END AND
Zip LIKE CASE WHEN isnull(RTRIM(@Address1),'') = '' THEN '%' ELSE @Zip END AND
Birthdate LIKE CASE WHEN isnull(RTRIM(@Address1),'') = '' THEN '%' ELSE @Birthdate END [/PHP]


Hope it helps.
Apr 19 '07 #27
Thanks, we figured it out, though, I don't know why it would cause an issue.

State and Zip were defined as char instead of varchar. When I change the definition to varchar, it works fine.
Apr 19 '07 #28
iburyak
1,017 Expert 512MB
When it is a char for example char(10)

When you save something shorter then that it adds spaces for you to make column 10 characters long for example you have 6 digit zip code it will return value like this with static length:

[PHP]"123456 "[/PHP]

Varchar is variable length and takes as much space as necessary so in this code zip code will be:

"123456"

Hope my explanation is clear.

If you'll need my help in a future send me a PM.
Good Luck.
Apr 20 '07 #29

Sign in to post your reply or Sign up for a free account.

Similar topics

33
by: Diez B. Roggisch | last post by:
Hi, today I rummaged through the language spec to see whats in the for ... else: for me. I was sort of disappointed to learn that the else clauses simply gets executed after the loop-body -...
1
by: Samuel Hon | last post by:
Hi I'm a bit stuck with a SELECT query. This is a simplified version of what I need. I've had a look in a few books and online but I'm definitely missing something. I'm trying to avoid looping...
7
by: jcochran | last post by:
What would be the correct way of writing a sql select state with where clause while also using IF ELSE. I am using T-SQL and I cannot get it to work. I probably have the syntax wrong. I want to...
3
by: visionstate | last post by:
Hi All, I have used the following article to help me build a query 'on the fly': http://www.fontstuff.com/access/acctut17.htm It's a very useful article and is exactly what I was looking for to...
25
by: metaperl.etc | last post by:
A very old thread: http://groups.google.com/group/comp.lang.python/browse_frm/thread/2c5022e2b7f05525/1542d2041257c47e?lnk=gst&q=for+else&rnum=9#1542d2041257c47e discusses the optional "else:"...
5
by: clear1140 | last post by:
Good day!! I was wondering if it is possible to put an if else statement inside a where clause of an sql statement... you see i would like my update statement to do this: update...
23
by: bearophileHUGS | last post by:
So far in Python I've almost hated the 'else' of the 'for' loops: - I have problems to remember its meaning; - It gives me little problems when I later want to translate Python code to other...
4
bencoding
by: bencoding | last post by:
Hello, I'm new to this board and new to T-SQL, I have a project at my work that is requiring me to modify an existing stored procedure to add more functionality. How can I use a CASE or...
3
by: BlueroY | last post by:
hi, I'm working on an exercise, i did a lot of work already and i just can't figure where I'm going wrong, this is what I'm trying to achieve Sample IO...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.