change conditions when parameter is null - sql

I have a stored procedure like this
CREATE PROCEDURE Table_Search
#param1 VARCHAR(100) = NULL,
#param2 VARCHAR(100) = NULL,
#param3 VARCHAR(100) = NULL
AS
SELECT * FROM Table1
WHERE
column1 LIKE '%' + #param1 + '%'
AND
column2
IN
(
SELECT * FROM Table2
WHERE
CONTAINS(column3,#param2)
AND
column4
IN
(
SELECT * FROM
fn_SplitWords(#param3,',')
)
)
what i want to happen is when #param1 IS NOT NULL #param2 IS NULL AND #param3 IS NULL, the stored procedure will be like:
CREATE PROCEDURE Table_Search
#param1 VARCHAR(100) = NULL,
#param2 VARCHAR(100) = NULL,
#param3 VARCHAR(100) = NULL
AS
SELECT * FROM Table1
WHERE
column1 LIKE '%' + #param1 + '%'
and when #param2 IS NOT NULL AND #param3 IS NULL, the stored procedure will be like this:
CREATE PROCEDURE Table_Search
#param1 VARCHAR(100) = NULL,
#param2 VARCHAR(100) = NULL,
#param3 VARCHAR(100) = NULL
AS
SELECT * FROM Table1
WHERE
column1 LIKE '%' + #param1 + '%'
AND
column2
IN
(
SELECT * FROM Table2
WHERE
CONTAINS(column3,#param2)
)
I already visited
WHERE IS NULL, IS NOT NULL or NO WHERE clause depending on SQL Server parameter value
and Stored procedure to handle null parameter
but I believe that this is a different case.
What might be the possible approach for this?

You can do something like this:
SELECT * FROM Table1
WHERE
column1 LIKE '%' + ISNULL(#param1, column1) + '%' AND
column2 LIKE '%' + ISNULL(#param2, column2) + '%' AND
...
This filters on every field if the parameter is set.

You can dynamically build your sql statement and then executesql proc to execute your query something like this...
DECLARE #Sql NVARCHAR(MAX);
SET #Sql = N'SELECT * FROM Table1
WHERE 1 = 1 '
IF (#param1 IS NOT NULL)
BEGIN
SET #Sql = #Sql + N' AND column1 LIKE ''%#param1%'''
END
IF (#param2 IS NOT NULL)
BEGIN
SET #Sql = #Sql + N' AND column2 IN (
SELECT * FROM Table2
WHERE
CONTAINS(column3,#param2)
)'
END
IF (#param3 IS NOT NULL)
BEGIN
SET #Sql = #Sql + N' AND column4
IN
(
SELECT * FROM
fn_SplitWords(#param3,'','')
)
'
END
EXECUTE sp_executesql #Sql
, N'#param1 VARCHAR(100),#param2 VARCHAR(100),#param3 VARCHAR(100)'
, #param1, #param2, #param3

Related

T-SQL function in Select to Only Return Columns with Values

I have a query that will return only columns with values. How do I add that to a function so I can use that with any query? Would it be a function in the where clause.
create table test1
(
s_no int not null,
name varchar(10) not null,
address varchar(10) null,
emailid varchar(100) null
)
insert into test1 (s_no, name)
values (1,'A'),(2,'B'),(3,'C')
declare #column_list varchar(8000),
#counter int
set #column_list = ''
set #counter = 0
while (Select max(colid) from syscolumns where id = object_id('test1') and isnullable= 0) > #counter
begin
select #counter = min(colid)
from syscolumns
where id = object_id('test1')
and isnullable = 0
and colid > #counter
select #column_list = #column_list + ',' + (Select name from syscolumns where id = object_id('test1') and isnullable= 0 and colid = #counter)
end
select #column_list = SUBSTRING(#column_list, 2, len(#column_list))
declare #sql varchar(8000)
select #sql = 'select ' + #column_list + ' from test1'
print #sql
exec (#sql)
SELECT * FROM [dbo].[test1]
I guess you could make a stored procedure where you provide the table name as parameter, and then build your query like you are doing already
create procedure ShowOnlyFilledColumns (#tablename varchar(100)) as
begin
set nocount on
declare #column_list varchar(8000),
#counter int
set #column_list = ''
set #counter = 0
while (Select max(colid) from syscolumns where id = object_id(#tablename) and isnullable= 0) > #counter
begin
select #counter = min(colid) from syscolumns where id = object_id(#tablename) and isnullable= 0 and colid > #counter
select #column_list = #column_list + ',' + (Select name from syscolumns where id = object_id(#tablename) and isnullable= 0 and colid = #counter)
end
select #column_list = SUBSTRING(#column_list,2,len(#column_list))
declare #sql varchar(8000)
select #sql = 'select ' + #column_list + ' from ' + #tablename
--print #sql
exec (#sql)
end
and use it like this
exec ShowOnlyFilledColumns 'test1'
See the complete example in this DBFiddle
EDIT: The OP asked how he can add joins on this
There are a few tricks to join with a stored procedure, for example in these answers
However, this won't work on this solution, because it requires to create a temp table to store the result of the procedure.
The trick looks like this
-- create a temporary table to store the results of the procedure
CREATE TABLE #Temp (
s_no int not null,
name varchar(10) not null,
address varchar(10) null,
emailid varchar(100) null
)
-- call the procedure and store the result in the temporary table
INSERT INTO #Temp
exec ShowOnlyFilledColumns 'test1'
-- now I can query the temp table, and join on it and write a where clause, and I can do whatever I want
select * from #Temp
Now, this won't work in this case, because the stored procedure can return different columns every time you run it, and to make the insert into #Temp exec ShowOnlyFilledColumns 'test1' work, the table #Temp must have the same number and type of columns as the procedure returns. And you just don't know that.

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

Writing a Stored procedure to search for matching values in columns with optional Input parameters

Requirement: To write stored Procedure(s) such that the values passed in stored procedures are matched against the values in columns in the table and then arranged with highest to lowest matching number of attributes.Then are inserted in a dynamically created temporary table inside the stored procedure.
Problem:
I have say 15-20 attributes that are matched against to confirm the suggestions made in response to record search. Basically, There is a table that stores Patients information and multiple parameters may be passed into the stored procedure to search through so that a Temporary table is created that suggests records in decreasing order of matching attributes.
To frame the basic structure, I tried with 3 attributes and respective stored procedures to match them which in turn are collectively called from a calling procedure based on the input parameter list which in turn creates the required temporary table.
Here is the SQL code(Just to give the gist of what I have tried so far):
But as a matter of fact it is, I realize this is way too naive to be used in a real time application which may require 80-90% of accuracy.So, what exactly can replace this technique for better efficiency?
Create Procedure NameMatch
(
#Name nvarchar(20),
#PercentContribution nvarchar(4) OUT, #PatientName nvarchar(20) out
)
As
declare #temp int
DECLARE #Query nvarchar(500)
if Exists(select Name from dbo.PatientDetails where Name = #Name)
Begin
set #PatientName = #Name
set #query = 'select * from dbo.PatientDetails where Name =' + #Name
set #temp = 0.1*100
set #PercentContribution = #temp + '%'
Execute(#query)
Return
End
Create Procedure AgeMatch
(
#Name nvarchar(20),
#Age int,
#PercentContribution nvarchar(4) OUT, #PatientName nvarchar(20) out
)
As
declare #temp int
DECLARE #Query nvarchar(500)
if Exists(select Name from dbo.PatientDetails where Name =#Name and Age = + #Age)
Begin
set #PatientName = #Name
set #query = 'select * from dbo.PatientDetails where Name = ' + #Name + ' and Age = '+ #Age
set #temp = 0.2*100
set #PercentContribution = #temp + '%'
Execute(#query)
Return
End
Create Procedure Nationality
(
#Name nvarchar(20),
#Age int,
#Nation nvarchar(10),
#PercentContribution nvarchar(4) OUT, #PatientName nvarchar(20) out
)
As
declare #temp int
DECLARE #Query nvarchar(500)
if Exists(select Name from dbo.PatientDetails where Name = #Name and Age = #Age and Nationality = #Nation )
Begin
set #PatientName = #Name
set #query = 'select * from dbo.PatientDetails where Name = ' + #Name + ' and Age = '+ #Age + ' and Nationality = ' + #Nation
set #temp = 0.3*100
set #PercentContribution = #temp + '%'
Execute(#query)
Return
End
create procedure CallingProcedure
(
#Name nvarchar(20),
#Age int = null,
#Nation nvarchar(10)= null
)
As
declare #PercentMatch nvarchar(4)
Begin
create table #results(PatientName nvarchar(30), PercentMatch nvarchar(4))
if(#Nation IS NOT NULL)
Insert into #results exec Nationality #Nation, #Name output, #PercentMatch output
else if(#Age is not Null)
Insert into #results exec AgeMatch #Age, #Name output, #PercentMatch output
else
Insert into #results exec NameMatch #Name, #Name output, #PercentMatch output
End
Setting aside nuances of stored procedure syntax, given parameters 1-n that if not null should match columns 1-n and the results sorted by highest number of matches first, a dynamic query is not needed - plain SQL can do it.
select *
from patient
where #param1 is null or column1 = #param1
or #param2 is null or column2 = #param2
...
or #paramN is null or columnN = #paramN
order by if(column1 = #param1, 1, 0)
+ if(column2 = #param2, 1, 0)
...
+ if(columnN = #paramN, 1, 0) desc

search in sql with 2 input parameter

i have 2 input parameter and i want search with These
CREATE TABLE dbo.tbl_answer
(
an_del INT,
u_username NVARCHAR(50),
u_name NVARCHAR(50) null
)
INSERT dbo.tbl_answer
VALUES(1, 'mohammad', null), (1, 'A13A6C533AF77160FBF2862953FA4530', 'GCV'), (1, 'C', 'GG'), (0, 'AB', 'BB'), (1, 'AC', 'K')
GO
CREATE PROC dbo.SearchAnswers
#Username nvarchar(20),
#Name nvarchar(20)
AS
SELECT *
FROM dbo.tbl_answer
WHERE an_del = 1 AND u_username LIKE ISNULL('%' + #Username + '%', u_username)
and u_name LIKE ISNULL('%' + #Name + '%', u_name)
and i run this command EXEC dbo.SearchAnswers 'moha', null but return any data
look at this
Try this :
CREATE PROC dbo.Answers
#Username nvarchar(20),
#Name nvarchar(20)
AS
declare #Name2 nvarchar(20)
set #Name2 = ISNULL(#Name, '00')
SELECT *
FROM dbo.tbl_answer
WHERE an_del = 1 AND ( u_username LIKE ISNULL('%' + #Username + '%', u_username)
AND
ISNULL(u_name,'00') LIKE '%' + #Name2 + '%' )
Your problem is that you aren't allowing for u_name to be null in your table. Which it is, on the only record with a u_username containing "moha"
CREATE PROCEDURE dbo.SearchAnswers
#Username nvarchar(20),
#Name nvarchar(20)
AS
SELECT *
FROM dbo.tbl_answer
WHERE an_del = 1
AND u_username LIKE ISNULL('%' + #Username + '%', u_username)
AND ISNULL(u_name,'') LIKE ISNULL('%' + #Name + '%', u_name)
You could also have the third conditional explicity test for NULL.
AND ( (u_name is null) or (u_name LIKE ISNULL('%' + #Name + '%', u_name) )
Here you are searching for 2 fields username and name and input parameter is null. Like will not work for null so you have to check for null independently or put some supplementary for that...
CREATE PROC dbo.SearchAnswers
#Username nvarchar(20),
#Name nvarchar(20)
AS
declare #Name2 nvarchar(20)
set #Name2 = ISNULL(#Name, '00')
SELECT *
FROM dbo.tbl_answer
WHERE an_del = 1 AND ( u_username LIKE ISNULL('%' + #Username + '%', u_username)
AND
ISNULL(u_name,'00') LIKE '%' + #Name2 + '%' )
SQL Fiddle

Using Like on a Parameter Variable?

Select Column1 From Table Where #Variable Like '%' + Column2 + '%'
Doesn't seem to work how I thought it would. Any suggestions?
(vague question)
Have you got Category and #Variable round the wrong way: sqlFiddle
create table the_table
(
category varchar(10),
[Date] datetime,
Amount decimal(12, 2)
)
insert into the_table
values
( 'X', '2012-1-1', 10),
( 'X', '2012-1-3', 10),
( 'Y', '2012-1-3', 20),
( 'Y', '2012-1-5', 10)
declare #Variable varchar(10)
set #Variable = 'Y'
Select *
From the_table
--Where #Variable Like '%' + category + '%'
Where category Like '%' + #Variable + '%'
If you have a limited number of columns, you can use case:
where case
when #Variable = 'col1' then col1
when #Variable = 'col2' then col2
when #Variable = 'col3' then col3
...
end like '%' + Column2 + '%'
Another option is dynamic SQL:
declare #sql nvarchar(max)
set #sql = 'Select Column1 From Table Where ' + #Variable +
' Like ''%'' + Column2 + ''%'''
exec (#sql)