stored procedure for search string with firstname name - sql

i need query which starts with first name here is my query:
if(#firstName <> '')
BEGIN
set #queryString = #queryString+ ' and UPPER(col_FirstName) like ''%' +#firstName +'%'''
END
if(#lastName <> '')
BEGIN
set #queryString = #queryString + ' and UPPER(col_LastName) like ''%' +#lastName +'%'''
but it is searching first name in middle also i want to search only with initials letters
thanks

Both masks in your constructed condition specify that the search be performed anywhere in the column value:
... + ' and UPPER(col_FirstName) like ''%' + #firstName + '%'''
...
... + ' and UPPER(col_LastName) like ''%' + #lastName + '%'''
The percent sign in the mask stands for "any number of any characters". Placed before the search term, therefore, it would match a value where the search term (#firstName) is preceded by any number of characters. To specify that the col_FirstName value should start with the #firstName value (and possibly have an arbitrary number of characters afterwards), just remove the leading percent, i.e. like this:
... + ' and UPPER(col_FirstName) like ''' + #firstName + '%'''

Insted of these IFs you can do it in one query like so:
...
WHERE ...
AND (#lastName <> '' OR UPPER(col_LastName LIKE '%#lastName%')
AND (#firstName <> '' OR UPPER(col_FirstName LIKE '%#firstName%')

Related

Stored procedure with 2 Like parameters

I am looking to use a stored procedure to filter my datagridview by either the user entering the part name into txtPartName or MRPID into txtMRPID. However, this is not filtering as expected and just shows all results from the parts table regardless.
I have a feeling this is due to the way I have implemented the AND or perhaps that I can't perform 2 LIKE statements in one procedure perhaps? Anyway can someone point me in the right direction as how to properly perform this procedure.
CREATE PROCEDURE Parts_ViewAllOrSearch
#PartNameSearch nvarchar(255),
#MRPIDSearch nvarchar(255)
AS
BEGIN
SELECT *
FROM Parts
WHERE #PartNameSearch = ''
OR PartName LIKE '%' + #PartNameSearch + '%'
AND #MRPIDSearch = ''
OR MRP_ID LIKE '%' + #MRPIDSearch + '%'
END
Basically you need parentheses around the OR condition:
SELECT *
FROM Parts
WHERE
(#PartNameSearch = '' OR PartName LIKE '%' + #PartNameSearch + '%')
AND (#MRPIDSearch = '' OR MRP_ID LIKE '%' + #MRPIDSearch + '%')
Why you need that is because AND has higher logical prescedence than OR. So without the parentheses, the WHERE clause is equivalent to:
WHERE
#PartNameSearch = ''
OR (PartName LIKE '%' + #PartNameSearch + '%' AND #MRPIDSearch = '')
OR MRP_ID LIKE '%' + #MRPIDSearch + '%'
... which obviously is not what you want.
Finally, please note that, as it stands, your code just does not seem to really these OR expressions. If a parameter is the empty string, then, once surrounded with wildcards it will match on all possible values (except null values). You would just write this as:
WHERE
PartName LIKE '%' + #PartNameSearch + '%'
AND MRP_ID LIKE '%' + #MRPIDSearch + '%'

Check a word starting with specific string [SQL Server]

I try to search on a string like Dhaka is the capital of Bangladesh which contain six words. If my search text is cap (which is the starting text of capital), it will give me the starting index of the search text in the string (14 here). And if the search text contain in the string but not starting text any of the word, it will give me 0. Please take a look at the Test Case for better understanding.
What I tried
DECLARE #SearchText VARCHAR(20),
#Str VARCHAR(MAX),
#Result INT
SET #Str = 'Dhaka is the capital of Bangladesh'
SET #SearchText = 'cap'
SET #Result = CASE WHEN #Str LIKE #SearchText + '%'
OR #Str LIKE + '% ' + #SearchText + '%'
THEN CHARINDEX(#SearchText, #Str)
ELSE 0 END
PRINT #Result -- print 14 here
For my case, I need to generate #Str with another sql function. Here, we need to generate #Str 3 times which is costly (I think). So, is there any way so that I need generate #Str only one time? [Is that possible by using PATINDEX]
Note: CASE condition appear in the where clause at my original query. So, It is not possible to set the #Str value in variable then use it in the where clause.
Test Case
Search Text: Dhaka, Result: 1
Search Text: tal, Result: 0
Search Text: Mirpur, Result: 0
Search Text: isthe, Result: 0
Search Text: is the, Result: 7
Search Text: Dhaka Capital, Result: 0
Simply add a leading space to the strings to ensure that you always find only the beginning of a word:
DECLARE #SearchText VARCHAR(20),
#Str VARCHAR(MAX),
#Result INT
SET #Str = 'Dhaka is the capital of Bangladesh'
SET #SearchText = 'Dhaka Capital'
SET #Result = CHARINDEX(' ' + #SearchText, ' ' + #Str)
PRINT #Result -- print 14 here
I have tested the above query against your test cases and it seems to work.
To compute the function only once per row in SELECT make it table valued function. Or if it's impossible for some reason use CROSS APPLY
SELECT .. a, b,
FROM ..
CROSS APPLY (SELECT my_scalar_fn(a,b) as Str) arg
WHERE CASE WHEN arg.Str LIKE SearchText + '%'
OR arg.Str LIKE + '% ' + SearchText + '%'
THEN CHARINDEX(SearchText, arg.Str)
ELSE 0 END

Trying to use SQL Replace in a non-dynamic way

I have the following statement, where I'm passing in a parameter like this:
'0001,0003'
I was following the REPLACE answer from this question:
SQL IN Statement splitting parameter
But I'm trying to take it out of dynamic sql. My returned result is NULL. Is there anyway to get this to work?
DECLARE #partialLNum varchar(MAX)
DECLARE #lNumConCat varchar(500)
DECLARE #tTemp table(lNum varchar(15))
DECLARE #formatIN varchar(MAX)
set #partialLNum = '0001,0003'
set #formatIN = ''''+ REPLACE(#partialLNum,',',''',''')+''''
insert into #tTemp
select substring(lNum,1,2) + '-' + substring(lNum,3,3) + '-' + substring(lNum,6,2) + '-' + substring(lNum,8,3)
from [rpt].[myView]
where LNum IN (#formatIN)
select #lNumConCat = COALESCE(#lNumConCat +'' , '', '''') + LNum from #tTemp
select #lNumConCat
in takes a list of values. So:
where LNum IN ('0001,0003')
has a list with one element, that happens to have a comment in it.
One way to do what you want is using like:
where ',' + partialLNum + ',' like '%,' + LNum + ',%'
There should suffice, but there are other ways using a split() function as well.

SQL: building a filter - can this be done without dynamic sql?

This is what i see all the time in a list made by us.
Have to make a filter for 2 columns (i took a shorter example, we have lists with 50 columns, looks the same...)
I was wondering if there's a way to do this somehow different.
What do you guys use to filter records from a table?
/* parameters */
#CostNumber = ...
#Description = ...
/* parameters */
SET #strSQL = '
SELECT [CostLevelId], [CostNumber], [Description]
FROM [CostLevel]
WHERE 1 = 1 ' /* this looks weird, but we'll add the "WHERE" stuff easier */
IF (#CostNumber IS NOT NULL)
BEGIN
SET #strSQL = #strSQL + ' AND [CostNumber] LIKE ''%' + REPLACE(#CostNumber,'''','''''') + '%'' '
END
IF (#Description IS NOT NULL)
BEGIN
SET #strSQL = #strSQL + ' AND [Description] LIKE ''%' + REPLACE(#Description,'''','''''') + '%'' '
END
EXEC (#strSQL)
Why not scrap the dynamic SQL approach?
/* parameters */
#CostNumber = ...
#Description = ...
/* parameters */
SELECT [CostLevelId], [CostNumber], [Description]
FROM [CostLevel]
WHERE [CostNumber] LIKE '%' + #CostNumber + '%'
AND [Description] LIKE '%' + #Description + '%'
Couple things to watch out for - nulls in the #CostNumber and #Description params - you'll have to make sure you convert them to empty strings.
Another thing you'll need to consider is the fact that #Description might contain a % character, and you'll have to escape that for the LIKE to work correctly.
I don't know how to do it when the LIKE operator is involved, when using comparison operators I'm using default values to obtain something like this:
select *
from dbo.SomeTable a
where
(a.IntColumn = #IntColumnValue or #IntColumnValue = -1)
and (a.VarCharColumn = #VarCharValue or #VarCharValue = 'zzz')
This way, if I don't want to apply a particular filter I just set it to the default value (in this example -1 or zzz), so its check always yelds true.
Using the LIKE operator should be something similar, maybe you should set the default value to some sort of string you know will never be found in your data? Something like this?
where (a.VarCharColumn like '%' + #VarCharValue + '%' or #VarCharValue = '§§§TheDefaultValue§§§')
I don't have a way to test this atm, but how about
SELECT [CostLevelId], [CostNumber], [Description]
FROM [CostLevel]
WHERE (#CostNumber IS NOT NULL AND [CostNumber] LIKE ''%' + REPLACE(#CostNumber,'''','''''') + '%'')
OR
(#Description IS NOT NULL AND [Description] LIKE ''%' + REPLACE(#Description,'''','''''') + '%'')
GROUP BY [CostLevelId], [CostNumber], [Description]
Failing that, you could try a UNION instead of OR (and grouping).
You can test to see if the value is null in the query, coupled with your condition and an or statement this allows for optional parameters.
This would work for a like statement.
SELECT [CostLevelId], [CostNumber], [Description]
FROM [CostLevel]
WHERE
(#CostNumber is null or [CostNumber] LIKE '%'+#CostNumber+'%')
and
(#Description is null or [Description] LIKE '%'+#Description+'%')
if its a straight equality comparison you can use coalesce to compare to either the populated variable or, when the variable is null, itself.
SELECT [CostLevelId], [CostNumber], [Description]
FROM [CostLevel]
WHERE
[CostNumber] = coalesce(#CostNumber,[CostNumber])
and
[Description] = coalesce(#Description,[CostNumber])
Keep in mind that this may have an adverse effect on your query plans dependant on which variables are set, table population and database structure etc. You may even find that the dynamic sql approach executes more efficiently than this despite the additional complication in its construction.

Issue With Apostrophe

I have a Proc that was coded in Dynamic SQl for one of my Application. It is using to search the Applicants with their last name. Right now it is searching applicants with either their first 2 digits of their last name or full last name. But i have a problem searching Applicants that have Apostrophe in their last name(Example O'Connor). If the client try to search applicant with O' or O'Connor it is throwing an error. They want to search every Applicant with or without Apostrophe in their last name. Please Help I tried everything, but its not working. Below is my search code that using in the Proc to pull applicants:
Add wildcards if necessary
if Rtrim(#FirstName) <> ''
begin
If(Len(#FirstName) < 30) and (CharIndex('%', #FirstName) = 0) and #FirstName != ''
Set #FirstName = char(39) + #FirstName + '%' + char(39)
end
if Rtrim(#LastName) <> ''
begin
If(Len(#LastName) < 60) and (CharIndex('%', #LastName) = 0) and #LastName != ''
Set #LastName = Char(39) + #LastName + '%' + char(39)
end
Now build dinamically the filter base on input parameters
if Rtrim(#LastName) <> ''
select #Where = #Where + ' and a.LastName like '+ Rtrim(#LastName)
You need to escape the apostrophe in the input string (basically replace a single ' with two '') as you build your SQL string
You need to pay attention to this anywhere you choose to pass user input to a SQL server database as its a security issue (SQL Injection Attacks) c.f. Bobby Tables
if Rtrim(#LastName) <> ''
select #Where = #Where + ' and a.LastName like '+ Replace(Rtrim(#LastName),'''','''''') + ''
My suggestion is to write the query to contain an alternate column to be used for filtering with the apostrophe/single quote replaced by any special character such as a #. This allows you to leave the original column intact in case you want to display it.
To do that in SQL Server, you could do something like this:
Select
tbl.strName_Last,
REPLACE(tblOrder.strName_Last, '''','#')) as StrLastNameForFilter
....
Then change your code to filter based on this alternate column, and in the user-provided filter string, replace the apostrophe/single quote with the special character.