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
Related
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.
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
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
I'm trying to use the LIKE keyword with the % wildcards wrapping the parameter, but I'm not sure how to get the % characters into the statement without breaking it. Right now I have:
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE %#search%'
I get a SqlException error in my .net app that says "Incorrect syntax near '#search' when I run it. The error goes away if I remove the % characters surrounding the #search parameter.
The % characters have to be in the search string...
SET #search = '%' + #search + '%'
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE #search'
Note that the following would also work, but introduces potential for a SQL injection vulnerability...
-- DON'T do this!
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE ''%' + #search + '%'''
SET #SQLQuery = 'SELECT * from [tblApps] WHERE [firstName] LIKE ''%'' + #search + ''%'''
exec sp_executesql #query=#SQLQuery, #params=N'#search nvarchar(96)', #search=#search
The only difference from this version as compared to the others is that the dynamic execution of the sql is in fact parameterized which mitigates sql injection a bit.
SET #search = '%' + #search
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE ' + #search + '%'
This worked for me!
SET #search = '''%' + #search + '%'''
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE' + #search
EXEC sp_executesql #SQLQuery
declare #Cmd nvarchar(2000)
declare #eName varchar(10)
set #eName='a'
set #Cmd= 'select * from customer1 where name LIKE '''+'%' +#eName+ '%' + ''''
print #Cmd
EXECUTE sp_executesql #Cmd
I want to use the like keyword in a dynamic parameterized query. I want to protect my query from SQL injections so I don't want to pass the value, instead I want to pass my criteria while executing the query,
Is there a way I can do this?
SELECT
ComposeMail.ID,
ComposeMail.DateTime,
ComposeMail.Subject,
ComposeMail.CreatedBy,
ComposeMail.ReceiverStatus,
Users.Name,
ROW_NUMBER() OVER(ORDER BY '+ #p_SortExpression +') AS Indexing
FROM
ComposeMail
INNER JOIN
Users
ON
ComposeMail.CreatedBy = Users.ID
WHERE
(ToReceipientID=#p)
AND (
ReceiverStatus=3
OR ReceiverStatus=4
)
AND (
(Subject Like ''%' + #p3 + '%'')
OR (Body Like ''%' + #p3 + '%'')
OR (Name Like ''%' + #p3 + '%'')
)
This is my dynamic query string. I don't want to pass the value here.
To prevent against injection in a dynamic query you always want to do something like this (instead of doing ' + #var + ' in your example)
DECLARE #query nvarchar(2000),
#paramList nvarchar(2000)
SET #query = 'SELECT * FROM dbo.Orders WHERE custLastName LIKE ''%'' + #custLastName + ''%'''
SET #paramList = '#custLastName varchar(30)'
EXEC SP_EXECUTESQL #query, #paramList, #custLastName
edit: example updated to use LIKE
WHERE (LastName LIKE N'%' + #Family + N'%') OR
(RegNo LIKE N'%' + #Codemeli + N'%')
like in dynamic sql query