Using Stored Procedure variable in Like statement - sql

I can't seem to properly use the LIKE statement using a variable from a stored procedure. I want to find all the rows from a table that start with the variable passed.
I am currently using the following query where #id is the value passed to the stored procedure as nvarchar(20). This works fine when the IDs completely match, but does not properly use the '%' appended. What is the proper way to complete this task?
SELECT * FROM Table WHERE id LIKE #id + '%'

This works for me:
declare #id nvarchar(20)
select #id = '1'
SELECT * FROM tab WHERE id LIKE #id + '%'
Sql Fiddle DEMO

The query doesn't work if #id is null. So what you can do is set it to empty string if #id is null. Please try the following:
begin
declare #id nvarchar(20)
set #id = isnull(#id, '')
select * from table where id like #id + '%'
end
So in your procedure, adding the following line should work for your query:
set #id = isnull(#id, '')

Simple solution:
$search_q = '%' . $this_search_q. '%';
$stmt = $db->prepare("SELECT * FROM tbl_tablename WHERE tablecollumn LIKE :id");
$stmt ->bindParam(":id", $search_q );
$stmt->execute();
OR
$search_q = '%' . $this_search_q. '%';
$stmt = $db->prepare("SELECT * FROM tbl_tablename WHERE tablecollumn LIKE $search_q");
$stmt->execute();

CREATE PROCEDURE `SP_GENRE_SELECT`(
IN _Id INTEGER,
IN _Name VARCHAR(50),
IN _account VARCHAR (50),
IN _Password VARCHAR (50),
IN _LastConnexionDate DATETIME,
IN _CreatedDate DATETIME,
IN _UpdatedDate DATETIME,
IN _CreatedUserId INTEGER,
IN _UpdatedUserId INTEGER,
IN _Status TINYINT
)
BEGIN
SELECT *
FROM user
WHERE Id LIKE _id IS NULL + '%',CAST(_Id AS VARCHAR)
AND
WHERE Name LIKE _Name IS NULL + '%' ,'%',CONCAT('%',_Name,'%')
AND
WHERE Account LIKE _Account IS NULL + '%' ,'%',CONCAT('%',_Account,'%')
AND
WHERE LastConnexionDate LIKE _LastConnexionDate IS NULL + '%' ,'%',CONCAT('%',CAST(LastConnexionDate AS VARCHAR(50),'%'))
AND
WHERE CreatedDate LIKE _CreatedDate IS NULL + '%' ,'%',CONCAT('%',CAST(_CreatedDate AS VARCHAR(50),'%'))
AND
WHERE UpdatedDate LIKE _UpdatedDate IS NULL + '%' ,'%',CONCAT('%',CAST(_UpdatedDate AS VARCHAR(50),'%'))
AND
WHERE CreatedUserID LIKE _CreatedUserID IS NULL +'%' ,'%',CONCAT('%',CAST(_CreatedUserID AS VARCHAR(50),'%'))
AND
WHERE UpdatedUserID LIKE _UpdatedUserID IS NULL +'%' ,'%',CONCAT('%',CAST(_UpdatedUserID AS VARCHAR(50),'%'))
AND
WHERE Status LIKE _Status IS NULL + '%' ,'%',CAST(_Status AS VARCHAR(50),'%');
END

Related

Stored procedure ignoring Nulls and fetch result for only entered parameters

I am creating a stored procedure to do a search through a table. I have many different search columns, all of which are optional. Is there a way to create a stored procedure that will handle this? Let's say I have a table with four columns ID, N1, N2 and N3. I could do something like this:
Table:
INSERT INTO [dbo].[Sample]
VALUES ('1', 'A,B,C', 'A,B,C', 'A,B,C'),
('2', 'B,D,N', 'B,D,N', 'B,D,N'),
('3', 'A,N,S', 'A,N,S', 'A,N,S'),
('4', 'S,F,G', 'S,F,G', 'S,F,G'),
('5', 'D,F,K', 'D,F,K', 'D,F,K'),
('6', 'S,H,Y', 'S,H,Y', 'S,H,Y'),
('7', 'Z,B,C', 'Z,B,C', 'Z,B,C')
Stored procedure:
CREATE PROCEDURE dbo.Sample2
#n11 varchar(max) = null,
#n12 varchar(max) = null,
#n21 varchar(max) = null,
#n22 varchar(max) = null,
#n31 varchar(max) = null,
#n32 varchar(max) = null
AS
BEGIN
SELECT COUNT(*)
FROM Sample
WHERE
(#n11 IS NULL OR Sample.N1 LIKE '%' + #n11 + '%'
OR #n12 IS NULL OR Sample.N1 LIKE '%' + #n12 + '%')
AND (#n21 IS NULL OR Sample.N2 LIKE '%' + #n21 + '%'
OR #n22 IS NULL OR Sample.N2 LIKE '%' + #n22 + '%')
AND (#n31 IS NULL OR Sample.N3 LIKE '%' + #n31 + '%'
OR #n32 IS NULL OR Sample.N3 LIKE '%' + #n32 + '%')
END
If user enters #n11 as A and leave the rest, since N1 contains A in 2 rows, output should be 2 but above query is providing 7. If a parameter is not specified, I need that to be ignored and pass the rest to where condition.
I think you need to AND every separate input condition e.g.
SELECT count(*)
FROM [Sample] S
WHERE (#n11 IS NULL OR S.N1 LIKE '%'+#n11+'%')
AND (#n12 IS NULL OR S.N1 LIKE '%'+#n12+'%')
AND (#n21 IS NULL OR S.N2 LIKE '%'+#n21+'%')
AND (#n22 IS NULL OR S.N2 LIKE '%'+#n22+'%')
AND (#n31 IS NULL OR S.N3 LIKE '%'+#n31+'%')
AND (#n32 IS NULL OR S.N3 LIKE '%'+#n32+'%')
Note the alias, which is the best practice way to avoid having to repeat a long table name all over the query.
Try to remove the next conditions from your stored procedure query:
#n12 IS NULL
#n22 IS NULL
#n32 IS NULL
As the above conditions are returning always true while there were sent when calling the procedure.
Stored procedure code after modified:
Alter Procedure dbo.Sample2
#n11 varchar(max) = null,
#n12 varchar(max) = null,
#n21 varchar(max) = null,
#n22 varchar(max) = null,
#n31 varchar(max) = null,
#n32 varchar(max) = null
AS
BEGIN
select count(*)
from Sample
where (#n11 IS NULL OR Sample.N1 LIKE '%'+#n11+'%' OR Sample.N1 LIKE '%'+#n12+'%')
AND (#n21 IS NULL OR Sample.N2 LIKE '%'+#n21+'%' OR Sample.N2 LIKE '%'+#n22+'%')
AND (#n31 IS NULL OR Sample.N3 LIKE '%'+#n31+'%' OR Sample.N3 LIKE '%'+#n32+'%')
END
Now while executing exec dbo.Sample2 #n11 = 'A' the output will be 2 instead of 7
select
sum(iif(N1 like '%'+#N11+'%',1,0)
+ iif(N1 like '%'+#N12+'%',1,0)
+ iif(N2 like '%'+#N21+'%',1,0)
+ iif(N2 like '%'+#N22+'%',1,0)
+ iif(N3 like '%'+#N31+'%',1,0)
+ iif(N3 like '%'+#N32+'%',1,0)
)
from Sample
Any NULL variables will be ignored.

how to take all values from sql table column on condition?

I want to select all column values irrespective of NULL as column value
my problem is when i try to select values using IS NULL i'm getting such records also thise having NULL as a value :(
declare #status varchar(50)=NULL
declare #path varchar(50)= 'India'
select
*
from [vwMYDATA]
where
Path like '%' + #path + '%' and
(Status = #status or #status IS NULL)
vwMYDATA
path status
INDIA1 NULL
INDIA2 close
INDIA3 open
If i execute above query i'm getting all records whose status column has NULL value
expected is if no status value specified show all status records
path status
INDIA1 NULL
INDIA2 close
INDIA3 open
it is showing
path status
INDIA1 NULL
I'm passing these 2 parameters to stored procedure which is having this select statment.
please help me to filtered out and show all the records if status is not given as input
select
*
from [vwMYDATA]
where
Path like '%' + #path + '%' and
((#status IS NULL )OR (Status = #status or status IS NULL))
You need to change the WHERE clause to a Case statement if you want different actions based on whether the #status varchar is NULL.
Select *
From [vwMYDATA]
Where
Path Like Concat('%', #path, '%') And
1 = (
Case When #status Is Null Then 1
When Status = #status Then 1
Else 0
)
This might be inefficient and nonperformant. For performance, it would be better to have a completely different query that matches based on NULL or not, so that proper indexing can be applied.
If you're happy to always filter out records with a null status (which it seems you are) then this should work:
declare #status varchar(50)=NULL
declare #path varchar(50)= 'India'
select
*
from [vwMYDATA]
where
Path like '%' + #path + '%' and
(Status = #status or #status IS NULL)
AND Status IS NOT NULL
Just try remove or #status IS NULL condition
select
*
from [vwMYDATA]
where
Path like '%' + #path + '%' and
(Status = #status)
You need to change your condition like below:
declare #status varchar(50)=NULL
declare #path varchar(50)= 'India'
select
*
from [vwMYDATA]
where
Path like '%' + #path + '%' and
(#status IS NULL OR Status = #status)
you just need to change the place of condition because the conditions check from first, so now if the #status will be null, query don't check next condition.
Get NUll Value Records on Status
select * from vwMYDATA where status is null
Get Not NUll Value Records on Status
select * from vwMYDATA where status is not null

Filter table data using select sql statement

I want to filter table data using select statement, I have four columns, and I have also four text boxes to enable search in each column,and I can enter value in any box(es), when I enter value in text box(es) I want to return the record(s) that match the value(s) I have entered, how can I do that?
ALTER PROCEDURE dbo.test_search
(
#ID int,
#FirstName nvarchar(50),
#MiddleName nvarchar(50),
#LastName nvarchar(50)
)
AS
SELECT ID, FirstName, MiddleName, LastName
FROM StudentsInformation
WHERE (#ID IS NULL OR StudentsInformation.ID = #ID) AND
(#FirstName IS NULL OR StudentsInformation.FirstName = #FirstName )AND
(#MiddleName IS NULL OR StudentsInformation.MiddleName = #MiddleName )AND
(#LastName IS NULL OR StudentsInformation.LastName = #LastName )
RETURN
EDIT:
SELECT
id
, firstname
, middlename
, lastname
FROM studentsinformation
WHERE id = #id
OR firstname LIKE '%' + #firstname + '%'
OR middlename LIKE '%' + #middlename + '%'
OR lastname LIKE '%' + #lastname + '%'
You can swap OR for AND if you want to select records that are true for all the checkboxes.
Syntax Depends upon programming language which you use.
But generally:
string sql="select * from tableName where"
if((txt1.Text!="")&&(sql=="select * from tableName where")
sql=sql+"colName like % #txt1 %"
else
sql=sql+" and colName like % #txt1 %"
if((txt2.Text!="")&&(sql=="select * from tableName where")
sql=sql+"colName like % #txt2 %"
else
sql=sql+" and colName like % #txt2 %"
if((txt3.Text!="")&&(sql=="select * from tableName where")
sql=sql+"colName like % #txt3 %"
else
sql=sql+" and colName like % #txt3 %"
Do like this.
I hope this will work:
Select * from <table-name>
where
<Column-name1> Like 'TextBox1%'
or
<Column-name2> Like 'TextBox2%'
or
<Column-name3> Like 'TextBox2%'
or
<Column-name4> Like 'TextBox4%'
Firstly you need to find text-box in which search string is passed.
Depending on text-box the query could be written on the related the column.
select * from table_name where column like '%text-box value%'
Edit
SELECT ID,FirstName,MiddleName,LastName
FROM StudentsInformation
WHERE 1=1
ID=(case when #ID <>0 AND #ID IS NOT NULL then #ID else ID end)
and FirstName=(case when #FirstName<>'' and #FirstName IS NULL then #FirstName
else FirstName)
and MiddleName=(case when #MiddleName<>'' and #MiddleName IS NULL then #MiddleName
else MiddleName)
and LastName=(case when #LastName<>'' and #LastName IS NULL then #LastName
else LastName)

SQL, how to use Dynamic Condition logics?

When you need Dynamic WHERE Clause I can use;
CREATE PROCEDURE [dbo].[sp_sel_Articles]
#articleId INT = NULL
, #title NVARCHAR(250) = NULL
, #accessLevelId INT = NULL
AS
BEGIN
SELECT *
FROM table_Articles Art
WHERE
(Art.ArticleId = #articleId OR #articleId IS NULL)
AND (Art.Title LIKE '%' + #title + '%' OR #title IS NULL)
AND (Art.AccessLevelId = #accessLevelId OR #accessLevelId IS NULL)
END
So, I am able to invoke this procedure -for example- ONLY by ArticleId
EXEC [sp_sel_Articles] #articleId = 3
But, sometimes I'll need to invoke by AccessLevelId and sometimes NOT by an EXACT VALUE. For example, I'll need MORE THAN the given accesslevelId or LESS THAN.
Current procedure can ONLY handle the EXACT value by using
Art.AccessLevelId = #accessLevelId
Could also be possible to give the CONDITION type as well as the value into the procedure? It may seem very odd in this example but please just bear with me:
CREATE PROCEDURE [dbo].[sp_sel_Articles]
#articleId INT = NULL
, #title NVARCHAR(250) = NULL
, #accessLevelId INT = NULL
, **#accessLevelIdCondition**
AS
BEGIN
SELECT *
FROM table_Articles Art
WHERE
(Art.ArticleId = #articleId OR #articleId IS NULL)
AND (Art.Title LIKE '%' + #title + '%' OR #title IS NULL)
AND (Art.AccessLevelId **#accessLevelIdCondition** #accessLevelId OR #accessLevelId IS NULL)
END
Perhaps an Function can be used, I don't know. Since, there will be at least 20 Procedure that will require this flexibility, I'll need a better, more global solution as much as possible rather than writing IF ELSE condition in every procedure.
Thanks in advance,
You'd probably need to use dynamic SQL to pass in the operator. Or you could pass in two values, e.g.
#MinAccessLevelID INT,
#MaxAccessLevelID INT
...
WHERE (
(#MinAccessLevelID IS NULL AND #MaxAccessLevelID IS NULL)
OR
(AccessLevelID >= #MinAccessLevelID AND AccessLevelID <= #MaxAccessLevelID)
)
When you want exact (e.g. only 3), just pass 3 into both values. When you want anything above 3, pass 20000000000 into the #Max param, or 0 if you want everything below 3.
But you'll find as these permutations get more complex, you are going to be better off just using dynamic SQL (and with optimize for ad hoc workloads set, this will be better for plan cache reuse and thwarting parameter sniffing as well).
Read this www.sommarskog.se/dynamic_sql.html before applying
CREATE PROCEDURE [dbo].[sp_sel_Articles]
#articleId INT = NULL
, #title NVARCHAR(250) = NULL
, #accessLevelId INT = NULL
, #accessLevelIdCondition varchar(100)
AS
BEGIN
DECLARE #SQL varchar(8000)
SET #SQL='
SELECT *
FROM table_Articles Art
WHERE
(Art.ArticleId = '+cast(#articleId as varchar(100))+' OR '+cast(#articleId as varchar(100))+'IS NULL)
AND (Art.Title LIKE ''%'' + #title + ''%'' OR #title IS NULL)
AND (Art.AccessLevelId '+#accessLevelIdCondition+ cast(#accessLevelId as varchar(100))+' OR '+cast(#accessLevelId as varchar(100))+' IS NULL) '
EXEC(#sql)
END
You can always make a dynamic query with just making a querystring
execute ('select count(*) from table' )
So with the params entered in your stored procedure, you can also form up a querystring which you can execute.
You could use a case statement - it can look a little funny if not formatted correctly but you can try something like:
SELECT Columns FROM SomeTable
WHERE 1 = CASE
WHEN #SomeOption = '<>' AND SomeValue >= #SomeMinParam AND SomeValue <= SomeMaxParam THEN 1
WHEN #SomeOption '=' AND SomeValue = #SomeMinParam THEN 1
ELSE 0
END
(though as Aaron pointed out - the <> you pass in doesn't really reflect the comparison operators in the statement - change this to something meaningful :))
in your case:
CREATE PROCEDURE [dbo].[sp_sel_Articles]
#articleId INT = NULL,
#title NVARCHAR(250) = NULL,
#MinaccessLevelId INT = NULL,
#MaxaccessLevelId INT = NULL,
#accessType varchar(5) = '<>'
AS
BEGIN
SELECT *
FROM table_Articles Art
WHERE
(Art.ArticleId = #articleId OR #articleId IS NULL)
AND (Art.Title LIKE '%' + #title + '%' OR #title IS NULL)
AND 1 = CASE
WHEN #accessType = '<>' AND (Art.AccessLevelId = #MinaccessLevelId OR #accessLevelId IS NULL) THEN 1
WHEN #accessType = '=' AND (Art.AccessLevelId >= #MinaccessLevelId OR Art.AccessLevelId <= #MaxaccessLevelId) THEN 1
ELSE 0
END
END
Maybe use a bit #CompareAccessLevelToMin instead of a varchar() for the #accessType param. Still has the trouble of not telling you what setting it to 'false' means though.

Simple SQL Query Help

I am building a query for a search in MS SQL 05
i have 4 things the user can select, and i want to use AND logic on it.
but i can't seem to get it to work when NULLs are being passed in.
this is what i have:
ALTER PROCEDURE [dbo].[sp_FindSource]
-- Add the parameters for the stored procedure here
#Code varchar(500),
#ssid varchar(50),
#serialNo varchar(50),
#category decimal(10,5)
as begin
SELECT *
FROM tblSource
WHERE Code IN (
SELECT Value
FROM funcListToTableInt(#Code,',')
)
and SSID LIKE '%' + #ssID + '%'
and serialNo LIKE '%' + #serialNo + '%'
and category = #category
end
NOTE: funcListToTableInt function, parses comma seporated values passed in (it works by itself, if i take the other where statements out)
The above search never returns anything, how can i ignore values if they are passed in black and only query the ones that have something in them? uuggh, it's been killing me.
You just have to wrap some OR #param IS NULL checks around your WHERE conditions:
ALTER PROCEDURE [dbo].[sp_FindSource]
-- Add the parameters for the stored procedure here
#Code varchar(500),
#ssid varchar(50),
#serialNo varchar(50),
#category decimal(10,5)
as begin
SELECT *
FROM tblSource
WHERE (Code IN (SELECT Value FROM funcListToTableInt(#Code,',')) OR #Code IS NULL)
AND (SiteSourceID LIKE '%' + #ssID + '%' OR #ssID IS NULL)
AND (serialNo LIKE '%' + #serialNo + '%' OR #serialNo IS NULL)
AND (category = #category OR #category IS NULL)
end
This looks very strange at first glance, since it is checking the parameters for IS NULL, but it works.
Try adding OR clauses for the nulls. SO for example change 'and category = #category' to 'and ((category = #category) or (category is null)).
Do this for all the items for whiuch you want to have a null imput essectially disable that particular test.
There are two ways:
Way 1, ADD OR Clause: It can kill the performance ....
SELECT *
FROM tblSource
WHERE (Code IN (
SELECT Value
FROM funcListToTableInt(#Code,',')
) OR #Code IS NULL)
and (SiteSourceID LIKE '%' + #ssID + '%' OR #SSID IS NULL)
and (serialNo LIKE '%' + #serialNo + '%' OR #serialNo IS NULL)
and (category = #category OR #category)
Way 2: Conditional logic
Considering you have 4 parameters and each may have a value or may not have a value, So you have 2*2*2*2 , 16 different cases. You can write something like:
IF (#SSID IS NULL AND #Code IS NULL AND #serialNo IS NULL AND #category IS NOT NULL) THEN
-- SEARCH only of category
ELSE IF (#SSID IS NULL AND #Code IS NULL AND #serialNo IS NOT NULL AND #category IS NULL) THEN
-- SEARCH only on Serial Number
.
.
.
.
.
As in SQL Server each If block cache its own plan, it will be more performing but based on parameter and there possible combinations this approach may or may not be desired ...