SQL LIKE with int - sql

Is there anything equivalent to the LIKE we use with varchar that can be used with int?
I want to filter with three parameters, two of them are varchar so I can use LIKE and in case I get an empty string I still can retrieve all records. But how can I achieve similar thing with an int
I want to retrieve even if fkProductTypeID doesn't exist:
This is my query:
select * from Product
where Code like '%'+ #code +'%' AND name LIKE '%'+ #name +'%'
AND fkProductTypeID = #ptype
I want it to be able to retrieve results even when I supply an ID that doesn't exist. From front-end, if I pass ' ' in #code,' ' in #name and 0 in #ptype I want it to retrieve all records

You could use this:
select * from Product
where Code like '%'+ #code +'%' AND name LIKE '%'+ #name +'%'
AND (#ptype IS NULL OR fkProductTypeID = #ptype)
if it's in a stored-procedure you should use an IF ... ELSE:
CREATE PROCEDURE dbo.SP_Name(#ptype int, #code varchar(1000), #name varchar(1000))
AS
BEGIN
IF #ptype IS NULL
BEGIN
select * from Product
where Code like '%'+ #code +'%' AND name LIKE '%'+ #name +'%'
END
ELSE
BEGIN
select * from Product
where Code like '%'+ #code +'%' AND name LIKE '%'+ #name +'%'
AND fkProductTypeID = #ptype
END
END

Is this what you want?
select *
from Product
where Code like '%'+ #code +'%' AND name LIKE '%'+ #name +'%' AND
(fkProductTypeID = #ptype or #ptype is null);
The value '' doesn't make sense for an integer. And, don't mix types for comparisons. Just use NULL for this purpose.

Its possible in this way
select * from Product
where CASE WHEN #code>0 THEN Code ELSE 0 END like '%'+ #code +'%'
AND name LIKE '%'+ #name +'%'
AND fkProductTypeID = #ptype

Related

Using of CASE in WHERE clause to evaluate empty parameters

Is there a better way to obtain the following?
DECLARE #Desc VARCHAR(200) = ''
SELECT [id],
[Desc],
[Col1],
[Col2]
FROM [dbo].[tbl]
WHERE [Desc] LIKE CASE
WHEN #Desc LIKE ''
THEN [Desc]
ELSE '%'+ #Desc +'%'
END
This allows to return all values if the parameter is not defined (#Desc='') or return a subset of values (#Desc='test').
Use OR Operator instead of Case
DECLARE #Desc VARCHAR(200) = ''
SELECT [id],
[Desc],
[Col1],
[Col2]
FROM [dbo].[tbl]
WHERE
(
ISNULL(#Desc,'')=''
)
OR
(
ISNULL(#Desc,'')<>''
AND
[Desc] LIKE '%'+ #Desc +'%'
)
Execution Plan Difference using Both Logics
Using Case
Using Or
It's better for the execution engine to do as much parameter handling prior to the query.
DECLARE #Desc VARCHAR(200) = '';
DECLARE #SelectAll bit;
SET #SelectAll = CASE WHEN #Desc = '' THEN 1 ELSE 0 END;
SET #Desc = CASE WHEN #Desc = '' THEN #Desc ELSE ('%' + #Desc + '%') END;
SELECT [id],
[Desc],
[Col1],
[Col2]
FROM [dbo].[tbl]
WHERE
(#SelectAll = 1)
OR
(#SelectAll = 0 AND [Desc] LIKE #Desc);
If you don't mind code duplication, you can take it even further and do two separate queries split by IF / ELSE.
If you use null you save some steps
declare #userId int = null;
SELECT TOP 1000 [AuctionId]
,[UserId]
,[BiddingPrice]
,[DateTime]
FROM [Test].[dbo].[Bid]
WHERE isnull(#userId, [UserId]) = [UserId];
Well, As Aaron Bertrand commented, your current query can be written simply like this:
DECLARE #Desc VARCHAR(200) = ''
SELECT [id],
[Desc],
[Col1],
[Col2]
FROM [dbo].[tbl]
WHERE [Desc] LIKE '%'+ #Desc +'%'
Since if #Desc contains an empty string, it will result with [Desc] LIKE '%%' -so all records where [Desc] is not null will be returned anyway.
If #Desc can be passed as null, use Coalesce to convert null to an empty string:
...WHERE [Desc] LIKE '%'+ COALESCE(#Desc, '') +'%'
Please note that in both questions, records where the Desc column contains null will not be returned. If that is a nullable column and you want to also return the records where it's null and the #Desc parameter is also null or empty, then you should use OR:
SELECT [id],
[Desc],
[Col1],
[Col2]
FROM [dbo].[tbl]
WHERE [Desc] LIKE '%'+ #Desc +'%'
OR (COALESCE(#Desc, '') = '' AND [Desc] IS NULL)
Also, please note that this is only because of your use of LIKE - Should you try to evaluate conditions using a different operator (such as =, <, >etc') you should use the OR syntax like in the other answers.

How to use dynamic filter in sql procedure?

I want use Dynamic filter in sql Procedure
,like this
Select * from Table Where #Filter
Can I Write Like That Or Was Diffrent Ways to Use
I must Use this Syntax because I Want Remove Select in Application and Use Procedure.
CREATE PROCEDURE SP_DynamicFilter
(
-- Optional Filters for Dynamic Search
#COLUMN1 INT = NULL,
#COLUMN2 NVARCHAR(50) = NULL,
#COLUMN3 NVARCHAR(50) = NULL,
#COLUMN4 NVARCHAR(50) = NULL
)
AS
BEGIN
SELECT *
FROM TableName
WHERE
(#COLUMN1 IS NULL OR Column1 = #COLUMN1)
AND (#COLUMN2 IS NULL OR Column2 LIKE '%' + #COLUMN2 + '%')
AND (#COLUMN3 IS NULL OR Column3 LIKE '%' + #COLUMN3 + '%')
AND (#COLUMN4 IS NULL OR Column4 LIKE '%' + #COLUMN4 + '%')
END
CREATE PROCEDURE spProcedurName
#Filter datatype
AS
BEGIN
SELECT *
FROM Table
WHERE columnName= #Filter
END
You can paramater like that.
#Query='
Select * from table' + #Filter
exec #Query

SQL syntax error

Im using Microsoft SQL Server which I think is T-SQL or ANSI SQL.
I want to search a database with a string. The matches that fit the begging of the string should come first then sort alphabetically.
I.e. If the table contains FOO, BAR and RAP
a search for the string 'R' should yield:
RAP
BAR
In that order.
Here is my attempt:
SELECT Name
FROM MyTable
WHERE (Name LIKE '%' + #name + '%')
ORDER BY (IF(Name LIKE #name + '%',1,0))
The error message is: "must declare scalar variable #name"
declare #name varchar(10)
set #name='R'
SELECT Name
FROM (select 'foo' as name union select 'RAP' union select 'BAR') MyTable
WHERE (Name LIKE '%' + #name + '%')
ORDER BY charindex(#name ,name)
.
DECLARE #name VARCHAR(MAX);
SET #name = 'foo';
SELECT Name
FROM MyTable
WHERE Name LIKE '%' + #name + '%'
ORDER BY CASE WHEN Name LIKE #name + '%' THEN 1 ELSE 0 END;
Other solutions seem to miss the "sort alphabetically" part:
DECLARE #Search VARCHAR(MAX)
SET #Search = 'R'
SELECT 0, Name
FROM MyTable
WHERE Name LIKE #Search + '%'
UNION ALL
SELECT 1, Name
FROM MyTable
WHERE Name like '%_' + #Search + '%'
ORDER BY 1, 2
Seems that you missed variable declaration:
DECALRE #name varchar(50) -- adjust type and length of variable
SET #name = 'phrase' -- for MSSQL 2008 you can do it in one line

How to adjust SQL LIKE function?

I want to make this kind of query:
create procedure something
#name varchar(13)
as
begin
select *
from WORKER
where NAME LIKE "%#name%"
end
For input #name=ho, I want output every row that contains NAME which sounds ho,
for example HOuse, soHO, broHOw...
Select * from WORKER where Name Like '%' + #name + '%'
create procedure something
#name varchar(13)
as
begin
select * from WORKER
where NAME LIKE '%' + #name + '%'
end

Stored Procedure WHERE LIKE ID or NAME

Group,
I am trying to create a stored procedure using one variable #Customer. What I want to do is put something in my WHERE clause that says if it is a number search the CustomerID field where the number entered is LIKE CustomerID... If a char is entered search the CustomerName field where the text entered is LIKE CustomerName. Below is an example of what I am trying to do:
CREATE PROCEDURE [dbo].[uspGetCustomer] (#Customer VARCHAR(100))
AS
SET NOCOUNT ON
SELECT *
FROM dbo.Customers
WHERE CASE WHEN ISNUMERIC(#Customer) THEN CustomerID LIKE #Customer + '%'
ELSE CustomerName LIKE #Customer + '%' END
Any suggestions?
I'd do it using an IF statement, since putting that logic in the WHERE makes it kind of hard to read later on:
DECLARE #match = #CustomerID + '%'
IF ISNUMERIC(#CustomerID) = 1
BEGIN
SELECT * FROM CUSTOMERS WHERE CustomerID LIKE #match
END ELSE BEGIN
SELECT * FROM CUSTOMERS WHERE CustomerNAME LIKE #match
END
update:
I'm wondering if the CustomerID field is an INT. If so then I'd change the query like so (and get rid of the #match variable):
... WHERE CustomerID = Cast(#CustomerID as INT) --if numeric
... WHERE CustomerNAME = #CustomerID + '%' --if not numeric
However, if it's some weird VARCHAR field that starts with a number and ends with other data, like '11_blah', then the LIKE plus wildcard works fine
Doing a single SQL statement that tries to solve both conditions will result in worst execution plan. Remeber that SQL has to generate one single plan to satisfy any value of the #variable. In your case when #customerID is numeric the proper plan would be to use an index on CustomerID. But when #customerID is a name the proper access would be an index on CustomerName. Given this dillema the optimizer will likely pick a plan that does a full scan, ie. not optimized in neither case.
The proper thing to do is to determine in your application if is an ID or a name and call two separate stored procedures, uspGetCustomerByID and uspGetCustomerByName, according to the value entered. If you must do this via one 'magic' API entry point (the all-powerful uspGetCustomer), then you already got seveal good answers.
It could just be me, but using a single variable to represent two different fields gives me the bad-practice willies. I would rewrite this stored procedure to take in two different, nullable variables (one int, CustomerID, and one varchar, CustomerName). It would look like this:
CREATE PROCEDURE [dbo].[uspGetCustomer] (
#CustomerID int = null,
#CustomerName VARCHAR(100) = null)
AS
IF #CustomerID IS NOT NULL BEGIN
SELECT * FROM Customers WHERE CustomerID = #CustomerID
END ELSE IF #CustomerName IS NOT NULL BEGIN
SELECT * FROM Customers WHERE CustomerName LIKE #CustomerName
END ELSE
--error handling, return empty set maybe?
END
If this simply isn't an option, then you could still use:
CREATE PROCEDURE [dbo].[uspGetCustomer] (#Customer VARCHAR(100))
AS
DECLARE #NameMatch;
IF ISNUMERIC(#Customer) = 1 BEGIN
SELECT * FROM Customers WHERE CustomerID = CAST (#Customer AS int)
END ELSE BEGIN
SET #NameMatch = '%' + #Customer + '%'
SELECT * FROM Customers WHERE CustomerName LIKE #NameMatch
END
Use:
CREATE PROCEDURE [dbo].[uspGetCustomer] (#Customer VARCHAR(100))
AS
BEGIN
IF ISNUMERIC(#Customer) = 1
BEGIN
SELECT *
FROM dbo.CUSTOMERS
WHERE customerid LIKE #Customer + '%'
END
ELSE
BEGIN
SELECT *
FROM dbo.CUSTOMERS
WHERE customername LIKE #Customer + '%'
END
END
Do something like this:
CREATE PROCEDURE [dbo].[uspGetCustomer] (
#CustomerID INT = NULL
#Customer VARCHAR(100) = NULL
)
AS
SET NOCOUNT ON
IF #CustomerID is not null
BEGIN
SELECT * FROM dbo.Customers
WHERE CustomerID = #CustomerID
END
ELSE
BEGIN
SELECT * FROM dbo.Customers
WHERE CustomerName LIKE #CustomerID + '%'
END
SET NOCOUNT OFF
I'd keep it simple and assume that customer names are never numeric:
SELECT *
FROM dbo.Customers
WHERE CustomerID LIKE #Customer + '%'
OR CustomerName LIKE #Customer + '%'
Alternatively, if you really don't want to match a numeric customer against its name, you can check like:
WHERE (IsNumeric(#Customer) = 1 AND CustomerID LIKE #Customer + '%')
OR (IsNumeric(#Customer) = 0 AND CustomerName LIKE #Customer + '%')
But then, how would you search for a customer with a numeric name? And by the way... a search like this will find customer 121 if you search for 12.
SELECT *
FROM dbo.Customers
WHERE ISNUMERIC(#Customer) = 1
AND CustomerID = CAST(#Customer AS INTEGER)
UNION ALL
SELECT *
FROM dbo.Customers
WHERE NOT ISNUMERIC(#Customer) = 1
AND CustomerName LIKE #Customer + '%'
This will use the approproate indexes on CustomerID and CustomerName
Oh just do it this way....
IF ISNUMERIC(#Customer) THEN
SELECT * FROM .... CustomerID = #Customer
ELSE
SELECT * FROM ... CustomerName LIKE #Customer
But you would want it more maintainable I suppose...
declare #basequery NVARCHAR(4000)
declare #params NVARCHAR(4000)
set #base_query = 'select * from dbo.Customers where '
IF ISNUMERIC(#Customer) THEN
SET #base_query = #base_query + 'customerid = #xCustomer'
SET #params = '#xCustomer int'
END
ELSE
SET #base_query = #base_query + 'customerName LIKE #xCustomer + ''%'' '
SET #params = '#xCustomer nvarchar(1000)'
END
exec sp_execuresql #base_query, #params, #Customer
Of course I would only recommend this kind of dynamic sql for more complex kinds of filtering.
I believe this will do it:
WHERE CustomerID LIKE
CASE WHEN IsNumeric(#Customer) = 1 THEN
CustomerID
ELSE
CustomerName + '%'
END
Keep it simple, have an index on each, determine on the front-end which one it is and set the correct parameter.
CREATE PROCEDURE dbo.getCustomer
(#CustomerID int = null,
#CustomerName VARCHAR(100) = null)
AS
SET NOCOUNT ON
SELECT *
FROM Customers
WHERE CustomerID = #CustomerID
or CustomerName like #CustomerName + '%'