How to use wildcards correctly in Stored Procedures - sql

I have stored procedure where is 1 variable as input.
CREATE PROCEDURE spExample
#name NVARCHAR(60) = ''
AS
BEGIN
SELECT [name], [dom]
FROM [DomName]
INNER JOIN [Domain]
ON LEFT([name], 1)+'%' LIKE #name +'%'
END
For now It returning records from table if first letter of the record is as input. For example if record in table is "Test", excecuting following procedure : EXEC spExample 'T' It returns correct record.
But It should return record even If I type T, Te, Tes, or Test as procedure inputs. Any ideas?

I am not sure why you trying to join two tables using variable.
SELECT [name], [dom]
FROM [DomName]
INNER JOIN [Domain] ON [name] LIKE +'%' + #var +'%'
I believe this should go to the where condition
SELECT [name], [dom]
FROM [DomName]
INNER JOIN [Domain] ON [[[Some condition here based on two table relationship]]]
Where [name] LIKE +'%' + #var +'%'

Try This:
Select column1,column2 from Table1 where column1 like '''+'%'+ #var +'%'+'''

Related

How can I create a conditional WHERE clause in SQL Server that returns multiple values?

I have the following SQL code for a SSRS report. I simplified the code because the original query is much longer.
There is a parameter #ARTICLE which a user can input. What I want to do is create a conditional WHERE statement. If a user enters an article number (#ARTICLE) the query should filter ID's from Table1 that match with ID's for which the entered article number (#ARTICLE) have a match with a 'detailcode' from another table. If there is no article number given, do not filter (or skip the whole WHERE statement)
With the code below I get the following error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.'
Logically it works perfectly fine without the CASE statement, so when only the subquery is used to check for matching ID's. However, I only want to return matching IDs if the #ARTICLE parameter has a value. If it is NULL or an empty string I want to return all IDs (or just skip the entire WHERE statement). How can I include a condition in the WHERE clause that allows multiple rows to return given the example below?
I feel like my approach is way to complicated, any help is much appreciated!
DECLARE #ARTICLE AS VARCHAR(50) = '1234567'
SELECT * FROM Table1
WHERE
Table1.ID IN (
CASE
WHEN ISNULL(#ARTICLE,'')<>'' THEN
(
SELECT ID
FROM Table2
WHERE detailcode IN (#ARTICLE)
)
ELSE Table1.ID
END
)
You're right, you're overcomplicating it a bit - if you look at the LIKE operator you can do something like:
DECLARE #filter NVARCHAR(50) = '123456';
DECLARE #f NVARCHAR(100) = '%' + #filter + '%';
SELECT *
FROM [Table1] AS [t1]
INNER JOIN [Table2] AS [t2]
ON [t2].[joinField] = [t1].[joinField]
AND [t2].[detailCode] LIKE #f;
Where #filter is a parameter to the stored procedure.
Or to account for detailCode being null:
DECLARE #filter NVARCHAR(50) = '123456';
DECLARE #f NVARCHAR(100) = '%' + #filter + '%';
IF #filter != NULL
SELECT *
FROM [Table1] AS [t1]
INNER JOIN [Table2] AS [t2]
ON [t2].[joinField] = [t1].[joinField]
AND [t2].[detailCode] LIKE #f;
ELSE
SELECT *
FROM [Table1] AS [t1]
INNER JOIN [Table2] AS [t2]
ON [t2].[joinField] = [t1].[joinField];
I would check wether #ARTICLE is NULL or if it is NOT NULL and your subquery is fulfilled, like so:
WHERE
ISNULL(#ARTICLE, '') = ''
OR
(
ISNULL(#ARTICLE, '') <> ''
AND ID IN
(
SELECT ID FROM Table2
WHERE detailcode = #ARTICLE
)
)
Maybe you can do it entire different, with an exists for example.
So you return all rows when #ARTICLE is null or '' OR exists at least one row in table2 with this article
The OR will have the effect that no filtering is done when the variable is null or ''
DECLARE #ARTICLE AS VARCHAR(50) = '1234567'
select t1.*
from table1 t1
where ( isnull(#ARTICLE, '') = ''
or
exists ( select 1 from table2 t2 where t2.detailcode = #ARTICLE )
)

Is there a possibility to Avoid multiple "OR" statement in Microsoft SQL?

I have a query that has to filter our results from a text field based on certain keywords used in the textline .. currently the SQL statement looks like the below.
and (name like '%Abc%') or (name like '%XYZ%') or (name like '%CSV%')...
Is there a way to avoid multiple or statements and achieve the same results?
You could put your filter keywords into a table or temp table and query them like this:
select a.*
from table_you_are_searching a
inner join temp_filter_table b
on charindex(b.filtercolumn,a.searchcolumn) <> 0
A slightly more shorthand way of doing this if you have a large amount of different patterns is to use EXISTS and a table value constructor:
SELECT *
FROM T
WHERE EXISTS
( SELECT 1
FROM (VALUES ('abc'), ('xyz'), ('csv')) m (match)
WHERE T.Name LIKE '%' + m.Match + '%'
);
A similar approach can be applied with table valued parameters. Since this is usually a requirement where people want to pass a variable number of search terms for a match it can be quite a useful approach:
CREATE TYPE dbo.ListOfString TABLE (value VARCHAR(MAX));
Then a procedure can take this type:
CREATE PROCEDURE dbo.GetMatches #List dbo.ListOfString READONLY
AS
BEGIN
SELECT *
FROM T
WHERE EXISTS
( SELECT 1
FROM #List AS l
WHERE T.Name LIKE '%' + l.value + '%'
);
END
Then you can call this procedure:
DECLARE #T dbo.ListOfString;
INSERT #T VALUES ('abc'), ('xyz'), ('csv');
EXECUTE dbo.GetMatches #T;
Just to give you another option you could also try this, an IN statement mixed with a PATINDEX:
Select *
from tbl
Where 0 not in (PATINDEX('%Abc%', name), PATINDEX('%XYZ%', name), PATINDEX('%CSV%', name))

LIKE and NULL in WHERE clause in SQL

I have a store procedure which i have planned to use for search and get all values.
Scenario:
If the parameter passed is NULL it should return all the values of the table and if the parameter passed is not NULL it should return the values according to the condition which is in LIKE.
//Query:
ALTER procedure [dbo].[usp_GetAllCustomerDetails]
(
#Keyword nvarchar(20) = null
)
As
Begin
Select CustomerId,CustomerName,CustomerTypeName,CustomerCode,CategoryName,CustomerMobile,CustomerEmail,CustomerAddress,CustomerCity,CustomerState,Pincode
from tblCustomerMaster CM
inner join dbo.tblCustomerTypeMaster CTM on CTM.CustomerTypeId = CM.CustomerType
inner join dbo.tblCategoryMaster CCM on CCM.CategoryId= CM.CustomerCategory
where CustomerName like '%'+#Keyword+'%'
In the above query it returns no values when i execute since the NULL is assumed as string by SQL, so what should i write in the where clause to get the desired output?
You can use condition like this in you where clause
where #Keyword is null or CustomerName like '%' + #Keyword + '%'
I just want to point out another way of solving this problem. The issue is that the default value for #KeyWord is NULL. If you change the default to '', then the problem goes away:
ALTER procedure [dbo].[usp_GetAllCustomerDetails]
(
#Keyword nvarchar(20) = ''
)
Any non-NULL customer name would then be like '%%'.
You just need to add SET #Keyword = coalesce(#Keyword,'') to your procedure like this :
ALTER procedure [dbo].[usp_GetAllCustomerDetails]
(
#Keyword nvarchar(20) = null
)
As
Begin
SET #Keyword = coalesce(#Keyword,'')
Select CustomerId,CustomerName,CustomerTypeName,CustomerCode,CategoryName,CustomerMobile,CustomerEmail,CustomerAddress,CustomerCity,CustomerState,Pincode
from tblCustomerMaster CM
inner join dbo.tblCustomerTypeMaster CTM on CTM.CustomerTypeId = CM.CustomerType
inner join dbo.tblCategoryMaster CCM on CCM.CategoryId= CM.CustomerCategory
where CustomerName like '%'+#Keyword+'%'

Like operator on input parameters in stored procedure

I've just begun to add writing stored procedures to my SQL repertoire and I'm sure this is a noob question. Can someone point me in the right direction about how to use the like operator instead of the = operator in this scenario? The object of this is to find the first 3 common numbers out of a potential 5 digit number
stored procedure:
create proc dbo.MultipleDrugs (#condition varchar(50))
as
SELECT *, 100.0 * round(SUM(numwithanxiety) OVER (partition BY sex) / cast(TotalSexCounts AS float), 4) overAllPercentByGender
FROM (SELECT x.sex, injurylevel, SUM(sexandlevelcounts) OVER (partition BY x.sex) numByInjury, sum(sexandlevelcounts) AS numWithAnxiety,
100.0 * round(cast(sexandlevelcounts AS float) / SUM(sexandlevelcounts) OVER (partition BY x.sex), 4) AS percentWith, y.TotalSexCounts
FROM (SELECT sex, injurylevel, COUNT(*) AS sexAndLevelCounts
FROM (SELECT DISTINCT m.patid, m.sex, m.injurylevel
FROM members AS m INNER JOIN
icdClm AS ic ON ic.patid = m.PATID
--*****when I leave this operator as like and use
--*****equals in the exec statement it works
WHERE ic.icd LIKE #condition) t
GROUP BY sex, injurylevel) x INNER JOIN
(SELECT m.sex, COUNT(DISTINCT patid) TotalSexCounts
FROM members m
GROUP BY m.sex) y ON y.sex = x.sex
GROUP BY x.sex, x.injuryLevel, x.sexAndLevelCounts, y.TotalSexCounts) rr
go
This runs, but I cannot use the like operator
exec dbo.MultipleDrugs N'70700'
This is what I'd like to do
exec dbo.MultipleDrugs like '707%'
exec dbo.MultipleDrugs N'707%'
You don't need to provide the LIKE operator in your exec call - you've already got like in your SPROC. Consider instead a simpler case:
create proc FindObjects #Name NVARCHAR(50)
as
select *
from sys.objects
where name like #Name
And then calling this:
exec FindObjects 'sys%'
returns
sysrscols
sysrowsets
sysallocunits
sysfiles1
syspriorities
sysfgfrag
etc.
Change your SP so that the following occurs:
LIKE '%' + #condition + '%'
You Can also use like this in the procedure .
set #SearchString='%'+ #SearchString + '%'

Executing a WHERE clause conditionally in SQL

I have an application on a SQL Server 2008 database. This database has a stored procedure that queries one of the tables. This stored procedure takes two parameters: userName and ID
The userName parameter will always be passed. However, the ID field will either be NULL or an actual value. If the value is something other than NULL, I need to consider it in the WHERE clause of my query. Unfortunately, I'm not positive how to do this. Currently, I'm trying
SELECT
*
FROM
TaskTicket t
WHERE
t.[UserName]=#userName AND
-- This is where I am stumped
Thank you for your help!
SELECT
*
FROM
TaskTicket t
WHERE
t.[UserName]=#userName
AND (#ID IS NULL OR t.[ID] = #ID)
Try this:
SELECT
*
FROM
TaskTicket t
WHERE
t.[UserName]=#userName AND
(#ID is null
or -- replace this comment with your logic
)
Group the conditionals together
select *
from TaskTicket t
Where t.[UserName]=#userName AND
((t.Id is null and (conditions_when_id_is_null))
or
(t.Id is not null and (conditions_when_id_is_not_null)))
SELECT
<column list>
FROM
TaskTicket T
WHERE
T.[UserName] = #username AND
(T.id = #id OR #id IS NULL)
Just be aware that this may cause a non-optimal query plan in some cases. That's probably not a big deal in this case unless your table is huge and you don't have an index on UserName and ID.
Hopefully more efficient than using an OR condition:
SELECT
*
FROM
TaskTicket t
WHERE
t.[UserName]=#userName AND
t.[ID] LIKE COALESCE(#ID,'%')
NB: will only work if ID is a non-NULLable, character field. (You can use CAST and COALESCE on t.[ID] otherwise, but then it's unlikely to be more efficient than an OR condition.)
Alternatively, use dynamic SQL in your stored procedure to completely omit the t.[ID] condition, if #ID is NULL.
declare #SQL nvarchar(max)
declare #WHERE_ID nvarchar(20)
set #WHERE_ID =
(
CASE
WHEN #ID is null THEN ''
ELSE ' AND ID = ' + CAST(#ID as nvarchar(10))
END
)
set #SQL = 'SELECT * FROM TaskTicket WHERE UserName = ' + #userName + #WHERE_ID
EXEC #SQL
Create procedure Procedure1
(
#Param1 nvarchar(100)=null,
)
AS
BEGIN
SELECT
ColumnName1,ColumneName2
FROM TableName
WHERE
(#Param1 IS NULL OR ColumnName1=#Param1)
END