Add IF / CASE statement inside where condition - sql

Dont know whether we can add if or case inside where condition .
I am trying to convert a dynamic query in to simple query
Declare #sQuery varchar(20000)
set #sQuery=''
set #sQuery ='select * from #tb_user ud'
if(#Number<>'')
set #sQuery = #sQuery + 'and upper(ud.ID) like ''' + upper(#Number) + '%'''
if(#Name<>'')
set #sQuery = #sQuery + 'and upper(ud.FName) like ''' + upper(#Name) + '%'''
Exec(#sQuery )
Note :
The below given query is just an example i have put off where i am not getting how to handle the if condition in simple query.(Actual query has a lot of things)
Thanks in advance for any help

Seems that you only want to use a specific filter (#Number or #Name) if it's not empty:
SELECT
*
FROM
#tb_user ud
WHERE
(#Number = '' OR upper(ud.ID) like upper(#Number) + '%')
AND
(#Name = '' OR upper(ud.FName) like upper(#Name) + '%')

You will have to group each test in a OR construct with the parameter being empty (or whatever check -inverted- you do in the if)..
SELECT
*
FROM
#tb_user ud
WHERE
(#Number = '' OR upper(ud.ID) like upper(#Number) + '%')
AND
(#Name = '' OR upper(ud.FName) like upper(#Name) + '%')
thanks go to #bartosz for spotting an error in the initial answer logic

Related

MSSQL searching unicode characthers using LIKE operator

I have a stored procedure where I pass a parameter that is unicode and looks like following:
מוכר שמן קוקוס בכחל מיני ואריציות
Now the problem here is that when I enter something in my form to search for this value in m table like fllowing:
IF LEN(#SearchValue) > 0
BEGIN
SET #WhereQuery = #WhereQuery +
'(Type=' + CAST(#type AS NVARCHAR(10)) + ' and UserId=' + CAST(#userid AS NVARCHAR(10)) + ') and'
+ '(convert(nvarchar(max),SentWord) like ''%' + #SearchValue + '%'' or '
+ 'convert(nvarchar(max),Comment) like ''%' + #SearchValue + '%'')'
END
Where #SearchValue is defined as nvarchar(200) in SQL server and table columns that hold the specific value are:
SentWord and Comment and both are unicode defined as nvarchar(600).
What am I doing wrong here? Why cant MSSQL search by hebrew characthers ? Can someone help me out?
As #Jeroen stated , possible fix would be to add N after LIKE operator like following:
IF LEN(#SearchValue) > 0
BEGIN
SET #WhereQuery = #WhereQuery +
'(Type=' + CAST(#type AS NVARCHAR(10)) + ' and UserId=' + CAST(#userid AS NVARCHAR(10)) + ') and'
+ '(convert(nvarchar(max),SentWord) like N''%' + #SearchValue + '%'' or '
+ 'convert(nvarchar(max),Comment) like N''%' + #SearchValue + '%'')'
END
But it still doesn't works...
Don't concatenate your strings like that!!! It's an injection nightmare!
Next, your declaring your literal unicode string as a varchar, not an nvarchar. if you try SELECT 'מוכר שמן קוקוס בכחל מיני ואריציות'; notice the return value is '???? ??? ????? ???? ???? ????????'. You need to prefix it with N, thus: SELECT N'מוכר שמן קוקוס בכחל מיני ואריציות';.
Now, the important is parametrising that SQL... Unfortunately I don't have enough of the SQL to actually do this in full for you, so here's a different example instead:
DECLARE #SQL nvarchar(MAX);
DECLARE #string nvarchar(20) = N'Test';
SET #SQL = 'SELECT * FROM MyTable WHERE MyColumn = #dString;'; --Notice the variable in the dynamic SQL
PRINT #SQL;
EXEC sp_executesql #SQL, N'dString nvarchar(20)',#dString = #string; --Notice the variable declaration and assignment.

How to use the AND in a variable in the WHERE clause

I'm trying to use AND operator in a variable and use it in the WHERE clause. I'm trying to do this without using Dynamic SQL. i.e without assigning the whole query to a variable.
DECLARE #v_Criteria varchar(500)
DECLARE #jobtype varchar(500) = 'test Job'
IF #inparam ='Report1'
BEGIN
SET #v_Criteria= ''
END
ELSE IF #inparam='Report2'
BEGIN
SET #v_Criteria= ' AND InvoiceValue IS NOT NULL'
END
SELECT *
FROM tblJobs
WHERE JobID NOT IN (63,87,469)
AND JobType LIKE '%' + #jobtype + '%'
+ #v_Criteria
I used + operator before the #v_Criteria and then I get no results. If I use & opertor before #v_Criteria, I get a error. Any help would be greatly appreciated
You can't append a "string" to a query and it become part of the code. It's still just a string. Essentially you're trying to do Dynamic SQL, but then say you don't want Dynamic SQL?
One option is to build the logic for both cases in SQL...
SELECT *
FROM tblJobs
WHERE JobID NOT IN (63,87,469)
AND JobType LIKE '%' + #jobtype + '%'
AND (
(#inparam ='Report1')
OR
(#inparam ='Report2' AND InvoiceValue IS NOT NULL)
)
This means that the query planner has to cope with both cases all the time. One plan to solve both cases. That saves you typing, but can mean that you get a poor execution plan and waste resources or execution time.
To get around that you need two queries...
IF (#inparam = 'Report1')
BEGIN
SELECT *
FROM tblJobs
WHERE JobID NOT IN (63,87,469)
AND JobType LIKE '%' + #jobtype + '%'
END
ELSE IF (#inparam = 'Report2')
BEGIN
SELECT *
FROM tblJobs
WHERE JobID NOT IN (63,87,469)
AND JobType LIKE '%' + #jobtype + '%'
AND InvoiceValue IS NOT NULL
END
Or just use Dynamic SQL...
SET #sql= 'SELECT *
FROM tblJobs
WHERE JobID NOT IN (63,87,469)
AND JobType LIKE ''%''' + #jobtype + '%''' + #v_Criteria
EXEC sp_executesql #sql
Or...
SET #sql= 'SELECT *
FROM tblJobs
WHERE JobID NOT IN (63,87,469)
AND JobType LIKE ''%'' + #jobtype_param + ''%''' + #v_Criteria
EXEC sp_executesql
#sql,
N'#jobtype_param varchar(500)',
#jobtype_param = #jobtype
(The benefit here is that you won't make a new cached query plan for every #jopbtype. Instead it makes a parameterised query plan and re-uses it.)
EDIT:
Basically what you're investigating is Dynamic Search.
If it ever gets more complex than this example, I strongly recommend reading this article : http://www.sommarskog.se/dyn-search.html
It's complicated, and in depth, and you'll learn a lot of valuable lessons.
Before adding " AND " if you check if #v_Criteria is not empty string then you will not get any error.
So split AND from for example " AND InvoiceValue IS NOT NULL"
Then add AND or not according to the value of the #v_Criteria
What about this solution?
DECLARE #v_Criteria varchar(500)
DECLARE #jobtype varchar(500) = 'test Job'
IF #inparam ='Report1'
BEGIN
SET #v_Criteria= ''
END
ELSE IF #inparam='Report2'
BEGIN
SET #v_Criteria= ' AND InvoiceValue IS NOT NULL'
END
SELECT *
FROM tblJobs
WHERE JobID NOT IN (63,87,469)
AND JobType LIKE '%' + #jobtype + '%'
AND ISNULL(InvoiceValue, '') NOT LIKE CASE
WHEN #inparam = 'Report2'
THEN ''
ELSE 'SOMEIMPOSSIBLEVALUE'
END

SQL Server: correct escaping Where clause in dynamic procedure (2)

I have a dynamic procedure where I want to use the below as part of my Where clause (everything else works as intended).
Currently this creates the following error: Incorrect syntax near the keyword 'LIKE'
AND CASE WHEN ' + #searchCategory + ' <> ''dateRec'' THEN
(R.' + #searchCategory + ' LIKE ''%' + #searchTerm + '%'')
ELSE
(R.dateRec = ' + CONVERT(VARCHAR, #searchTerm, 111) + ')
END
What would the proper escaping look like here ?
I believe this is what you're looking for:
declare #sql nvarchar(max), #searchCategory nvarchar(max), #searchTerm nvarchar(max)
set #searchCategory = 'dateRec'
set #searchTerm = 'yyy'
set #sql =
'AND (
(''' + #searchCategory + ''' <> ''dateRec'' AND (R.' + #searchCategory + ' LIKE ''%' + #searchTerm + '%''))
OR
(''' + #searchCategory + ''' = ''dateRec'' AND (R.dateRec = ''' + CONVERT(VARCHAR, #searchTerm, 111) + '''))
)'
print #sql
Assuming the contents of #searchCategory don't actaully contain the characters '...
SET #sql = 'AND ' +
CASE WHEN #searchCategory <> 'dateRec' THEN
'(R.' + #searchCategory + ' LIKE ''%'' + #searchTerm + ''%'')'
ELSE
'(R.dateRec = CONVERT(VARCHAR, #searchTerm, 111))'
END
This will give either....
AND (R.foobar LIKE '%' + #searchTerm + '%')
or...
AND (R.dateRec = CONVERT(VARCHAR, #searchTerm, 111))
This means that you would still pass #searchTerm to sp_executesql as a parameter, so as to protect you from SQL Injection attacks.
You DO NOT want to directly embed a user's free form text in to your SQL. Free form text must stay as a parameter in order to close that security hole.
(I'm also assuming that you have a white-list of valid values of #searchCategory so as to prevent that from being abused with an SQL Injection Attack?.)
EDIT :
An example of dynamic sql that maintains parameterisation....
DECLARE #SQL nvarchar(500);
SET #SQLString = N'SELECT * FROM table WHERE ' + #param1 + ' = #param;';
EXECUTE sp_executesql
#SQL,
'#param NVARCHAR(500)',
#param2
Using this method, you need to check that #param1 really is a legitimate field name, using a white-list for example, but you do not need to check #param2. This is because #param2 is being passed to sp_executesql as a parameter itself. It's just like dynamically making a stored procedure with parameters, rather than embedding all your values in the sql string, which lays you open to serious sql injection attacks.
EDIT :
This is not a case of embedding a LIKE statement within a CASE statement. What is being done here is creating a string that creates the string literal LIKE, by using a CASE statement.
It is much the same as this...
SET #sql = 'AND ' +
CASE WHEN #searchCategory <> 'dateRec' THEN
'A string with the word' + ' LIKE ' + 'in it'
ELSE
'A different string without that word in it'
END

SQL output from dynamic SQL

I have an stupid question about output.
I have an stored procedure that inside is doing a dynamic SQL for checking if there are records in a table, this is the example:
SET #sqlLog =
'SELECT 1 FROM MyTable
WHERE TableName = ''' + #TableName + '''' + '
AND TheKey = ''' + convert(varchar(50), #LoadGuid) + ''''
EXEC(#sqlLog)
After that I'm using ##RowCount to validate if the result is 0 or not.
The problem is that is inside a WHILE and for each row is showing the result in the output window of SQL Management Studio and I don't really want this.
Any idea? Thank you!
Why do you even need dynamic SQL for this?, you could do something like the following:
IF EXISTS ( SELECT 1 FROM MyTable
WHERE TableName = #TableName
AND TheKey = convert(varchar(50), #LoadGuid))
BEGIN
-- Your logic here
END
If you just need to know the number of rows that result from the query, try changing the select list to only be 'SELECT COUNT(*) FROM MyTable ... '. This will give you the count as a single result.
I think you need to use the NOCOUNT option:
SET NOCOUNT ON
See http://msdn.microsoft.com/en-us/library/ms189837.aspx for details.
Good luck,
Dave Cherkassky
declare #count int
exec sp_executeSql
N'set #count = (select count(*) from MyTable where TableName = ''' + #tableName + '''
and TheKey = ''' + convert(varchar(50), #LoadGuid) + '''',
N'#count int output',
#count = #count output
if #count > 0
print 'rows exist'
else
print 'no rows'
There is no way to have it surpress the results of a straight select statement like that. You are literally telling it to return those results to the calling application, here SSMS, and it is doing so. SSMS is properly displaying those results. You have some options as to how you want to display them (results pane or as text, etc.), but I do not know of an option in SSMS to turn it off.
What you could do is use sp_executesql with an output paramater so that instead of requesting any results, you are simply having it put the rowcount in a parameter. That would look something like:
declare #theCount int
SET #sqlLog = 'SELECT #theCount = count(*)
FROM MyTable
WHERE TableName = ''' + #TableName + '''' +
' AND TheKey = ''' + convert(varchar(50), #LoadGuid) + ''''
EXEC sp_executesql #sqlLog, N'#theCount int OUTPUT', #theCount=#theCount OUTPUT
Then you check whether the value of #theCount is 0 instead of ##Rowcount.

Queries using LIKE wildcards in sql server

I want to perform a small SQL server search in my ASP.NET web project. My database is not big so I think it's better not to use full-text-search.
I want to perform a simple search like this:
select * from mytable where columnA LIKE '%something%'
I can use = in the following way:
select * from mytable where columnA='"+myVariable+"'
but how can I use a variable instead of %something% in the LIKE phrase?
Is this correct:
LIKE '"+%myVariable%+"'?
Use:
where columnA LIKE '%' + myVariable + '%'
WHERE
columnName LIKE '%' + myVarCharVariable +'%'
Try this query:
select * from tablename where colname like '%' + #varname + '%'
Hope it helps.
I just tried this and found you can do as below:
SELECT * FROM whatever WHERE column LIKE '%'+#var+'%'
DECLARE #myVariable varchar(MAX)
SET #myVariable = 'WhatYouAreLookingFor'
SELECT * FROM mytable
WHERE columnA LIKE '%' + #myVariable + '%'
In case someone else stumbles into this post like I did. On SSMS 2012 with a SQL 2012 Server back end I was able to use code as follows without issues.
Declare #MyVariable
Set #MyVariable = '%DesiredString%'
Select *
From Table_A
Where Field_A like #MyVariable
Then each time you want to change the Desired String just change it at the Set statement.
I know this post was made prior to 2012 that is why I am mentioning it in case someone with a newer setup looks up this post.
Well you could do something like:
var query = "SELECT * FROM MyTable WHERE columnA LIKE '%" + myVariable + "%'";
If you are worried about sql injection, try something like this instead. It's more complex, but it works and should satisfy security requirements. Let's say someone passed a value into your stored procedure using a parameter called "#searchstring".
DECLARE #searchString nvarchar(100) = 'test',
#SQL nvarchar(max),
#foundSearchHit bit,
#paramdef nvarchar(max) = '#foundSearchHit bit OUTPUT'
SET #searchstring = '%' + #searchString + '%'
SET #SQL = '
SELECT TOP 1 #foundSearchHit = 1
FROM sys.databases WHERE [name] like ' +
QUOTENAME(#searchString,'''')
EXEC sp_executeSQL #SQL, #paramdef, #foundSearchHit = #foundSearchHit OUTPUT
SELECT #foundSearchHit
That should do the trick.