Select parameters if a condition is fulfilled - sql

I want to select particular elements if my condition is fulfilled. Please, look below at my code. How can I select the data in CASE clause? My way does not work
CREATE PROCEDURE [dbo].[GetUsers]
#firstName varchar(100) = '',
#isCounterSelected int,
#countries dbo.tvp_stringArray READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT [PK_UserID] AS Id
,[UserNickName]
,[description]
,CASE
WHEN #isCounterSelected = 1 THEN (NULL AS MCount, NULL AS GCount, NULL AS CCount)
ELSE ''
END
FROM [dbo].[User_Existing]
WHERE (#firstName NOT LIKE '' AND firstName LIKE #firstName + '%')
AND Country IN (SELECT inputValue FROM #countries)

I think this would be with syntax errors fixed:
CREATE PROCEDURE [dbo].[GetUsers]
#firstName varchar(100) = '',
#isCounterSelected int,
#countries dbo.tvp_stringArray READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT [PK_UserID] AS Id
,[UserNickName]
,[description]
,CASE
WHEN #isCounterSelected = 1 THEN NULL
ELSE ''
END AS MCount
,CASE
WHEN #isCounterSelected = 1 THEN NULL
ELSE ''
END AS GCount
,CASE
WHEN #isCounterSelected = 1 THEN NULL AS CCount
ELSE ''
END AS CCount
FROM [dbo].[User_Existing]
WHERE (#firstName NOT LIKE '' AND firstName LIKE #firstName + '%')
AND Country IN (SELECT inputValue FROM #countries)
END

Related

Stored procedure with OUTPUT - Must declare the scalar variable

I'm writing a stored procedure that will be executed from C# to get data from database. Therefore I have to pass a GUID to this stored procedure and it should find data in table Contact or in the Lead table & return data back to C# app via output parameters.
When I try to execute this stored procedure in SSMS, I get a SQL exception
Must declare the scalar variable "#LastName"
Code:
ALTER PROCEDURE [api].[GetUser_NetId]
#NetId uniqueidentifier
, #LastName nvarchar(200) = '' OUTPUT
, #FirstName nvarchar(200) = '' OUTPUT
, #Country uniqueidentifier = NULL OUTPUT
, #Newsletter bit = 0 OUTPUT
AS
DECLARE
#Table SMALLINT
SET #Table = (
SELECT MIN(T.ID) FROM (
SELECT 100 AS [ID] FROM dbo.Contact WHERE Net_ID = #NetId
UNION ALL
SELECT 200 AS [ID] FROM dbo.Lead WHERE Net_ID = #NetId
) T
)
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = CONCAT(
' SELECT
#LastName = tbl.LastName,
#FirstName = tbl.FirstName,
#Country = tbl.Address1CountryId,
#Newsletter = tbl.Newsletter,
FROM
dbo.'
, CASE #Table
WHEN 100 THEN 'Contact'
WHEN 200 THEN 'Lead'
END
, ' as tbl
WHERE 1=1
AND tbl.Net_Id = '''
, #NetId
, ''''
)
EXEC(#SQL)
..a slightly simpler approach
ALTER PROCEDURE [api].[GetUser_NetId]
#NetId uniqueidentifier
, #LastName nvarchar(200) = '' OUTPUT
, #FirstName nvarchar(200) = '' OUTPUT
, #Country uniqueidentifier = NULL OUTPUT
, #Newsletter bit = 0 OUTPUT
AS
BEGIN
IF EXISTS(SELECT * FROM dbo.Contact WHERE Net_ID = #NetId)
BEGIN
SELECT
#LastName = tbl.LastName,
#FirstName = tbl.FirstName,
#Country = tbl.Address1CountryId,
#Newsletter = tbl.Newsletter
FROM dbo.Contact WHERE Net_ID = #NetId;
END
ELSE
BEGIN
SELECT
#LastName = tbl.LastName,
#FirstName = tbl.FirstName,
#Country = tbl.Address1CountryId,
#Newsletter = tbl.Newsletter
FROM dbo.Lead WHERE Net_ID = #NetId;
END
END
I am getting an error like:
Msg 137, Level 15, State 2, Line 18
Must declare the scalar variable "#CustomerKey".
Msg 137, Level 15, State 1, Line 21
Must declare the scalar variable "#FirstName".
Msg 137, Level 15, State 1, Line 30
Must declare the scalar variable "#FirstName".
IF EXISTS(SELECT * FROM VW_FactInternetSales WHERE CustomerKey = #CustomerKey)
BEGIN
SELECT
#FirstName = .FirstName,
#TaxAmt = .TaxAmt,
#Country = .Country,
#CustomerKey = .CustomerKey
FROM DimCustomer WHERE CustomerKey = #CustomerKey
END
ELSE
BEGIN
SELECT
#FirstName = .FirstName,
#TaxAmt = .TaxAmt,
#Country = .Country,
#CustomerKey = .CustomerKey
FROM VW_FactInternetSales WHERE CustomerKey = #CustomerKey
END
END
I cant add my table in this line
#FirstName = .FirstName,
#TaxAmt = .TaxAmt,
#Country = .Country,
#CustomerKey = .CustomerKey

SQL Server Dynamic where clause query

I am trying to create a dynamic query I just to do with linq
from a in Customers
where (string.IsNullOrEmpty(name)? true : a.FirstName == name) && (string.IsNullOrEmpty(last)? true : a.LastName == last)
select a;
but now I need to do in on Stored Procedure and I don't want to concatenate for security reason and performance. The most close example I found is this query
declare #Name as varchar(100)
declare #GroupName as varchar(100)
set #Name = ''
set #GroupName = 'Manufacturing'
SELECT TOP (1000) [DepartmentID]
,[Name]
,[GroupName]
,[ModifiedDate]
FROM [AdventureWorks2017].[HumanResources].[Department]
where ([Name] = case
when #Name is null or #Name = '' then null
else #Name
end
)
and
(
[GroupName] = case
when #GroupName is null or #GroupName = '' then null
else #GroupName
end
)
This almost works. I think this should be the answer but the where clause fails for obvious reason.
I would like the where clause could produce '1=1' if the param "Name" or "GroupName" is null
example
#Name = "Somename"
#GroupName = null
where (Name = #Name) and (1 = 1)
--or
#Name = null
#GroupName = "Somegruopname"
where (1 = 1) and (GroupName = #GroupName)
--
#Name = null
#GroupName = null
where (1 = 1) and (1 = 1)
You want it to succeed if the variable is null or empty or a match, so I would just write that in your stored procedure.
WHERE (#FirstName is null OR #FirstName = '' OR [FirstName] = #FirstName)
AND (#LastName is null OR #LastName = '' OR [LastName] = #LastName)
Please try this:
declare #Name as varchar(100)
declare #GroupName as varchar(100) = 'Manufacturing'
set #Name = LTRIM(RTRIM(#Name))
set #GroupName = 'Manufacturing'
SELECT TOP (1000) [DepartmentID]
,[Name]
,[GroupName]
,[ModifiedDate]
FROM [AdventureWorks2017].[HumanResources].[Department]
where ([Name] = coalesce(#Name,'') = '' OR [Name] = #Name)
and
([GroupName] = coalesce(#GroupName, '') = '' OR [GroupName] = #GroupName)

Append string in where clause in SQL

I have a function in SQL that returns where clause result like this
CREATE FUNCTION dwd.GetSearchCriteria
(
#pValue NVARCHAR(50),
#pCriteriaOption NVARCHAR(3)
)
RETURNS varchar(30)
AS
BEGIN
declare
#WHERE varchar(2000)
IF(#pValue IS NOT NULL)
BEGIN
SET #WHERE = CASE WHEN #pCriteriaOption = 'ST' THEN ' like ''' + #pValue + '%'''
WHEN #pCriteriaOption = 'ET' THEN ' like ''' + '%' + #pValue + ''''
WHEN #pCriteriaOption = 'CT' THEN ' like ' + '''%' + #pValue + '%'''
ELSE ''
END
END
ELSE
BEGIN
SET #WHERE = '= NULL';
END
RETURN #WHERE
END
I have a query that like this which calls this function
declare
#WHERE varchar(2000)
SET #WHERE=dwd.GetSearchCriteria ('A','ET')
SELECT FirstName FROM dwd.[User] WHERE FirstName + #WHERE
My function returns suppose { like %A% } . I need to append it to first name .
It returns this error
An expression of non-boolean type specified in a context where a
condition is expected, near '#WHERE'.
I have along SP like this
ALTER PROCEDURE [dwd].[ADMIN_USER_DETAIL]
(
#pApplicationClientID bigint,
#pUserID bigint,
/* Optional Filters for Dynamic Search*/
#pFirstName nvarchar(50) = NULL,
#pLastName nvarchar(50) = NULL,
#pEmail nvarchar(255) = NULL,
#pLocation nchar(10) = NULL,
#pPhoneNumber nvarchar(50) = NULL,
#pPseudoName nvarchar(500) = NULL,
/*– Pagination Parameters */
#pPageNo INT = 1,
#pPageSize INT = 10,
/*– Sorting Parameters */
#pSortColumn nvarchar(50) = 'FirstName',
#pSortOrder nvarchar(4)='ASC',
#pTotalCount int output
)
AS
BEGIN
/*–Declaring Local Variables corresponding to parameters for modification */
DECLARE
#lFirstName nvarchar(50),
#lLastName nvarchar(50),
#lEmail nvarchar(255),
#lLocation nchar(10),
#lPhoneNumber nvarchar(50),
#lPseudoName nvarchar(500),
#lPageNbr INT,
#lPageSize INT,
#lSortCol NVARCHAR(50),
#lFirstRec INT,
#lLastRec INT,
#lTotalRows INT,
#TotalCount INT
/*Setting Local Variables*/
SET #lFirstName = LTRIM(RTRIM(#pFirstName))
SET #lLastName = LTRIM(RTRIM(#pLastName))
SET #lEmail = LTRIM(RTRIM(#pEmail))
SET #lLocation = LTRIM(RTRIM(#pLocation))
SET #lPhoneNumber = LTRIM(RTRIM(#pPhoneNumber))
SET #lPseudoName = LTRIM(RTRIM(#pPseudoName))
SET #lPageNbr = #pPageNo
SET #lPageSize = #pPageSize
SET #lSortCol = LTRIM(RTRIM(#pSortColumn))
SET #lFirstRec = ( #lPageNbr - 1 ) * #lPageSize
SET #lLastRec = ( #lPageNbr * #lPageSize + 1 )
SET #lTotalRows = #lFirstRec - #lLastRec + 1
; WITH User_Results
AS (
SELECT ROW_NUMBER() OVER (ORDER BY
CASE WHEN (#lSortCol = 'FirstName' AND #pSortOrder='ASC')
THEN U1.FirstName
END ASC,
CASE WHEN (#lSortCol = 'FirstName' AND #pSortOrder='DESC')
THEN U1.FirstName
END DESC,
CASE WHEN (#lSortCol = 'LastName' AND #pSortOrder='ASC')
THEN U1.LastName
END ASC,
CASE WHEN #lSortCol = 'LastName' AND #pSortOrder='DESC'
THEN U1.LastName
END DESC,
CASE WHEN #lSortCol = 'Email' AND #pSortOrder='ASC'
THEN U1.Email
END ASC,
CASE WHEN #lSortCol = 'Email' AND #pSortOrder='DESC'
THEN U1.Email
END DESC,
CASE WHEN #lSortCol = 'Location' AND #pSortOrder='ASC'
THEN U1.LocationID
END ASC,
CASE WHEN #lSortCol = 'Location' AND #pSortOrder='DESC'
THEN U1.LocationID
END DESC,
CASE WHEN #lSortCol = 'PhoneNumber' AND #pSortOrder='ASC'
THEN U1.PhoneNumber
END ASC,
CASE WHEN #lSortCol = 'PhoneNumber' AND #pSortOrder='DESC'
THEN U1.PhoneNumber
END DESC,
CASE WHEN #lSortCol = 'PseudoName' AND #pSortOrder='ASC'
THEN U1.PseudoName
END ASC,
CASE WHEN #lSortCol = 'PseudoName' AND #pSortOrder='DESC'
THEN U1.PseudoName
END DESC
) AS ROWNUM,
Count(*) over () AS TotalCount,
U1.ID,
U1.FirstName,
U1.LastName,
U1.Email,
DPD.Value as Location,
U1.PhoneNumber,
U2.FirstName+' '+U2.LastName as ReportTo,
U1.PseudoName,
U1.IsActive,
US.ID AS SId,
US.SkillID AS SkillId,
UR.ID AS RId,
UR.RoleID AS RoleId,
U1.Created,
U1.Deleted
FROM dwd.[User] U1 with (nolock)
INNER JOIN dwd.[User] U2 with (nolock) ON U2.ID=U1.ReportTo
INNER JOIN dwd.[DomainParameterDetail] DPD with (nolock) ON DPD.ID=U1.LocationID
INNER JOIN dwd.[UserSkill] US WITH(NOLOCK) ON U1.ID = US.UserID
INNER JOIN dwd.[UserRole] UR WITH(NOLOCK) ON U1.ID = UR.UserID
WHERE
(#lFirstName IS NULL OR U1.FirstName = #lFirstName)
AND(#lLastName IS NULL OR U1.LastName LIKE '%' + #lLastName + '%')
AND(#lEmail IS NULL OR U1.Email LIKE '%' + #lEmail + '%')
AND (#lLocation IS NULL OR U1.LocationID LIKE '%' + #lLocation + '%')
AND (#lPhoneNumber IS NULL OR U1.PhoneNumber = #lPhoneNumber)
AND (#lPseudoName IS NULL OR U1.PseudoName LIKE '%' +#lPseudoName+ '%')
AND U1.IsActive=1 AND U1.Deleted=0 AND U1.ApplicationClientID=#pApplicationClientID
AND U1.ID<>1
)
SELECT
TotalCount,
ROWNUM,
ID,
FirstName,
LastName,
Email,
Location,
PhoneNumber,
ReportTo,
PseudoName,
IsActive,
S
Id,
SkillId,
RId,
RoleId,
Created,
Deleted
FROM User_Results AS USER_GET_RESULT
WHERE
ROWNUM > #lFirstRec
AND ROWNUM < #lLastRec
ORDER BY ROWNUM ASC
Select #TotalCount = Count(*) from dwd.[User]
WHERE IsActive=1 AND Deleted=0 AND ID<>1
Set #pTotalCount = #TotalCount
END
SO I have to get this donw in where clause of SP.
This is a bit long for a comment.
You can only do what you want using dynamic SQL. But, that seems entirely unnecessary, because all the comparisons use LIKE. So, it is better to write the function as:
CREATE FUNCTION dwd.GetSearchCriteria (
#pValue NVARCHAR(50),
#pCriteriaOption NVARCHAR(3)
)
RETURNS varchar(2000)
AS
BEGIN
declare #LIKEPATTERN varchar(2000) ;
SET #LIKEPATTERN = (CASE WHEN #PValue IS NULL THEN ''''''
WHEN #pCriteriaOption = 'ST' THEN '''' + #pValue + '%'''
WHEN #pCriteriaOption = 'ET' THEN '''' + '%' + #pValue + ''''
WHEN #pCriteriaOption = 'CT' THEN '''%' + #pValue + '%'''
ELSE ''''''
END)
RETURN #LIKEPATTERN
END ;
Note: Using an IF and CASE is redundant. The logic can be combined into a single expression. I also think return types should match the type of the variable being returned.
Then you can express the call as:
DECLARE #LIKEPATTERN varchar(2000);
SET #LIKEPATTERN = dwd.GetSearchCriteria('A','ET');
SELECT FirstName FROM dwd.[User] WHERE FirstName LIKE #LIKEPATTERN;

Search filter on two fields based upon condition

Here is my table
create table Table1 (Id int, ...some fields... , CategoryId int, ProfileId int)
I want to write a SP(stored procedure) which will give me search results from the table based upon the parameters passed to the SP. Here is my procedure
Create proc Search
(
#MediaType1 varchar(1000),
#MediaType2 varchar(1000),
#MediaType3 varchar(1000)
)
as
begin
select * from table
where
case when #MediaType1 = '' then 1 else CategoryId end in
(select case when #MediaType1 = '' then 1 else Splvalue end
from dbo.Split(case #MediaType1 when '0,' then '1,2,3,4' when '' then '1,' else #MediaType1 end,','))
and
case when #MediaType2 = '' then 1 else ProfileId end in
(select case when #MediaType2 = '' then 1 else Splvalue end
from dbo.Split(case #MediaType2 when '0,' then '2,12,13' when '' then '1,' else #MediaType2 end,','))
and
case when #MediaType3 = '' then 1 else ProfileId end in
(select case when #MediaType3 = '' then 1 else Splvalue end
from dbo.Split(case #MediaType3 when '0,' then '1,14,15,16' when '' then '1,' else #MediaType3 end,','))
end
Basically, what I want to achieve is when '0' is passed in #MediaType1 variable, it should return all records which have category (1,2,3,4) else it should only that category which is passed (e.g. 3) else if its blank, it should show all records. Same way for #MediaType2 and #MediaType3 except that they should check for ProfileId. The condition is also that all three or two or one of the parameters could be blank, I need to handle those and show the filtered records.
My above query works only if one parameter is passed and rest all are blank. I also tried
where
(#MediaType1 <> '' and Category in (select Splvalue from dbo.Split(#MediaType1,',')))
or
(#MediaType2 <> '' and ProfileId in (select Splvalue from dbo.Split(#MediaType2 ,',')))
or
(#MediaType3 <> '' and ProfileId in (select Splvalue from dbo.Split(#MediaType3 ,',')))
but even this does not works. Any help would be appreciated
If I just rewrite what you said as conditions:
SELECT * FROM table
WHERE
(#MediaType1 = '' OR (#MediaType1 = 0 AND CategoryId IN (1,2,3,4))
OR #MediaType1 = CategoryId)
AND
(#MediaType2 = '' OR (#MediaType2 = 0 AND ProfileId IN (1,2,3,4))
OR #MediaType2 = ProfileId )
AND
(#MediaType3 = '' OR (#MediaType3 = 0 AND ProfileId IN (1,2,3,4))
OR #MediaType3 = ProfileId )
I just wrote the SP like this and it worked
Create proc Search
(
#MediaType1 varchar(1000),
#MediaType2 varchar(1000),
#MediaType3 varchar(1000)
)
as
begin
if (#MediaType1 = '' and #MediaType2 = '' and #MediaType3 = '')
begin
set #MediaType1 = '0,';
set #MediaType2 = '0,';
set #MediaType3 = '0,';
end
select * from table
where
((#MediaType1 = '0,' and CategoryId in (1,2,3,4)) or (CategoryId in (select Splvalue from dbo.Split(#MediaType1,','))))
or
((#MediaType2 = '0,' and ProfileId in (2,12,13)) or (ProfileId in (select Splvalue from dbo.Split(#MediaType2 ,','))))
or
((#MediaType3 = '0,' and ProfileId in (1,14,15,16)) or (ProfileId in (select Splvalue from dbo.Split(#MediaType3 ,','))))
end

Use If between the where clause

I don't know how exactly I should frame my Question as even I don't know what exactly I have to search. May be this is the best place to put my question. I want to use If condition in where clause this can be done using case but my problem is I don't want to use it after a column name instead I want to avoid entire execution of that column. You can understand it by going through my procedure in the last I have commented, So I want to achieve something like that as I want to write the same procedure again for that condition which i think can be achievable by doing something like that. I searched on internet what I got is to use case in where which doesn't satisfy my purpose. Please look the last lines to understand the problem. Thanx
USE [overseascrm]
GO
/****** Object: StoredProcedure [dbo].[candidatesearch] Script Date: 05-07-2014 00:48:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[candidatesearch]
#candidate_id varchar(50),
#firstname varchar(50),
#lastname varchar(50),
#emailid_1 varchar(100),
#mobile_1 varchar(20),
#from varchar(50),
#to varchar(50),
#agentid varchar(50),
#passportno varchar(50),
#profession int,
#isactive bit
as
begin
DECLARE #candidateid_var varchar(50)
DECLARE #firstname_var varchar(50)
DECLARE #lastname_var varchar(50)
DECLARE #emailid1_var varchar(100)
DECLARE #mobile_1_var varchar(20)
DECLARE #agentid_var varchar(50)
IF(#agentid = '')
begin
SET #agentid_var = '%'
END ELSE BEGIN
SET #agentid_var = #agentid
END
IF (#candidate_id = '') BEGIN
SET #candidateid_var = '%'
END ELSE BEGIN
SET #candidateid_var = #candidate_id
END
IF (#firstname = '') BEGIN
SET #firstname_var = '%'
END ELSE BEGIN
SET #firstname_var = #firstname
END
IF (#lastname = '') BEGIN
SET #lastname_var = '%'
END ELSE BEGIN
SET #lastname_var = #lastname
END
IF (#emailid_1 = '') BEGIN
SET #emailid1_var = '%'
END ELSE BEGIN
SET #emailid1_var = #emailid_1
END
IF (#mobile_1 = '') BEGIN
SET #mobile_1_var = '%'
END ELSE BEGIN
SET #mobile_1_var = #mobile_1
END
IF (#from = '') BEGIN
SELECT
*
FROM candidate C
LEFT JOIN candidate_profession_map CM
ON C.candidate_id = CM.candidate_id
LEFT JOIN passport_details PD
ON C.candidate_id = PD.candidate_id
WHERE C.candidate_id LIKE '' + #candidateid_var + '%'
AND firstname LIKE '' + #firstname_var + '%'
AND lastname LIKE '' + #lastname_var + '%'
AND emailid_1 LIKE '' + #emailid1_var + '%'
AND mobile_1 LIKE '' + #mobile_1_var + '%'
AND agent_id LIKE '' + #agentid_var + '%'
AND CM.profession_id = #profession
AND C.isactive = #isactive
AND PD.passport_no = #passportno
END ELSE BEGIN
SELECT
*
FROM candidate C
LEFT JOIN candidate_profession_map CM
ON C.candidate_id = CM.candidate_id
LEFT JOIN passport_details PD
ON C.candidate_id = PD.candidate_id
WHERE C.candidate_id LIKE '' + #candidateid_var + '%'
AND firstname LIKE '' + #firstname_var + '%'
AND lastname LIKE '' + #lastname_var + '%'
AND emailid_1 LIKE '' + #emailid1_var + '%'
AND mobile_1 LIKE '' + #mobile_1_var + '%'
AND agent_id LIKE '' + #agentid_var + '%'
AND C.addedon BETWEEN CONVERT(DATETIME, #from, 103) AND CONVERT(DATETIME, #to, 103)
--IF (#profession <> 0)BEGIN
--AND CM.profession_id = #profession
--END
AND C.isactive = #isactive
OR PD.passport_no = #passportno
END
END
You could use dynamic sql execution where you create your select statement as varchar to your liking, executing it at the end using sp_executesql
http://msdn.microsoft.com/en-us/library/ms188001.aspx
ALTER procedure [dbo].[candidatesearch]
#candidate_id varchar(50),
#firstname varchar(50),
#lastname varchar(50),
#emailid_1 varchar(100),
#mobile_1 varchar(20),
#from varchar(50),
#to varchar(50),
#agentid varchar(50),
#passportno varchar(50),
#profession int,
#isactive bit
AS Begin
SELECT *
FROM candidate C
LEFT JOIN candidate_profession_map CM ON C.candidate_id = CM.candidate_id
LEFT JOIN passport_details PD ON C.candidate_id = PD.candidate_id
WHERE (#candidateid='' or C.candidate_id LIKE #candidateid + '%')
AND (#firstname = '' or firstname LIKE #firstname + '%')
AND (#lastname = '' or lastname LIKE #lastname + '%')
AND (#emailid_1='' or emailid_1 LIKE #emailid1 + '%')
AND (#mobile_1 = '' or mobile_1 LIKE #mobile_1 + '%')
AND (#agentid='' agent_id LIKE #agentid + '%')
AND C.isactive = #isactive
And ((#from=''
AND CM.profession_id = #profession
AND PD.passport_no = #passportno)
or (#from<>''
And C.addedon BETWEEN CONVERT(DATETIME, #from, 103) AND CONVERT(DATETIME, #to, 103)
OR PD.passport_no = #passportno)
End