Search filter on two fields based upon condition - sql

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

Related

SQL get fields which are null/empty for each record returned

I have the below query which I'm using to retrieve records which have at least one of the following columns set as NULL or '':
MainImage
Summary
Description
DECLARE #missingFields varchar(100)
SET #missingFields = ''
SELECT
c.[UnitReference] as 'UnitRef',
t.[NodeName] as 'Property',
#missingFields as 'Field/s missing'
FROM [DetailPage] d
INNER JOIN [CRM] c
ON d.ItemID = c.ItemID
INNER JOIN
[Tree] t
ON d.[ID] = t.[ID]
WHERE (ISNULL(d.MainImage, '') = '' OR ISNULL(d.Summary,'') = '' OR ISNULL(d.[Description],'') = '')
AND c.[IsListed] = 1 AND c.[IsMarketed] = 1
This returns the data I want however I also need to build up a string which lists which of the columns is null or empty for the returned record, e.g. "Main Image is empty, Description is empty" when a record has empty MainImage and Description columns.
I've tried:
#missingFields = CASE WHEN ISNULL(MainImage, '') = '' THEN 'Main image is null' ELSE '' END -- etc...
But I can't include this with the data retrieval operations. How would I go about doing this?
SELECT c.[UnitReference] AS 'UnitRef',
t.[NodeName] AS 'Property',
( CASE
WHEN d.MainImage IS NULL
THEN 'Main Image is Null, '
WHEN d.MainImage = ''
THEN 'Main Image is Empty, '
ELSE ''
END )+
( CASE
WHEN d.Summary IS NULL
THEN 'Summary is Null, '
WHEN d.Summary = ''
THEN 'Summary is Empty, '
ELSE ''
END )+
( CASE
WHEN d.[Description] IS NULL
THEN 'Description is Null, '
WHEN d.[Description] = ''
THEN 'Description is Empty, '
ELSE ''
END ) AS MissingFields
FROM [DetailPage] d
INNER JOIN [CRM] c
ON d.ItemID = c.ItemID
INNER JOIN [Tree] t
ON d.[ID] = t.[ID]
WHERE( d.MainImage IS NULL OR d.MainImage = '' )
OR ( d.Summary IS NULL OR d.Summary = '' )
OR ( d.[Description] IS NULL OR d.[Description] = '' )
AND c.[IsListed] = 1
AND c.[IsMarketed] = 1

Select parameters if a condition is fulfilled

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

I want to create a function in SQL that by input parameter my query condition is changed

create function StudentExist(#nationalId nvarchar(10), #type as int)
returns bit
as
begin
declare #i as int
if(#type =1)
select #i = count(*) from BonyadShahidData..BonyadData where NationalCode = #nationalId and [type] = 'A'
if(#type =2)
select #i = count(*) from BonyadShahidData..BonyadData where NationalCode = #nationalId and [type] = 'B'
if(#type =3)
select #i = count(*) from BonyadShahidData..BonyadData where NationalCode = #nationalId and [type] = 'D'
if(#i > 0)
return 1
return 0
end
my answer will be as blunt as the question CASE (Transact-SQL)
create function StudentExist(#nationalId nvarchar(10), #type as int)
returns bit
as
begin
declare #i as int
if(#type =1)
select #i = count(*) from BonyadShahidData..BonyadData where NationalCode = #nationalId
and [type] = (case #type
when 1 then 'A'
when 2 then 'B'
when 3 then 'C'
end)
if(#i > 0)
return 1
return 0
end

SQL if else stored procedure

I'm writing a stored procedure and it's working for if but not for else. For if I'm getting the correct ID value but for else it's just giving me null.
SELECT #ID = ID FROM PRODUCTS WHERE SN = #SN
SELECT #Chip_ID = Chip_ID FROM PRODUCTS WHERE SN = #SN
SELECT #Power = Power From Module_Cycle WHERE ChipID = #Chip_ID
SELECT #Test_ID=Test_ID FROM TestEE_Mod WHERE ID=#ID AND #TypeID = TypeID
IF(#Test_ID IS NOT NULL)
BEGIN
IF(#TypeID = '3')
BEGIN
SELECT #Temp_TestID=TestID FROM TempCycle WHERE ChipID = #Chip_ID AND #Power = 'false'
BEGIN
UPDATE TestEE_Mod SET Temp_TestID = #Temp_TestID WHERE ID = #ID AND TypeID = #TypeID
END
END
ELSE
BEGIN
SELECT #Temp_TestID=TestID FROM TempCycle WHERE ChipID = #Chip_ID AND #Power = 'true'
BEGIN
UPDATE TestEE_Mod SET Temp_TestID = #Temp_TestID WHERE ID = #ID AND TypeID = #TypeID
END
END
END
Most likely the issue lies in the #Power variable. In your two SELECT statements, the only difference is that one includes #Power = 'false' in the WHERE clause, while the other includes #Power = 'true'.
Since #Power is a variable, not an actual column in your TempCycle table, I'm guessing you actually meant to filter by Power = #Power in both of them.

FireBird: How do you nest a select in an if?

I'm very new to FireBird, but I want to know how I can use a select statement as part of my conditional criteria. I feel like I've been to the internet in back trying to find a way to do this, but haven't come up with much. Below is my attempt at getting this to work. Thanks in advance for any help.
SET TERM ^ ;
ALTER PROCEDURE sp_test (
IPADD Varchar(32),
HN Varchar(32),
NOTE Varchar(200) )
RETURNS ( update_count integer )
AS
BEGIN
IF((SELECT COUNT(*)
FROM ADDRESSES a
WHERE a.ADDRESS_TYPE = 'Reserved'
AND a.ALIVE = 'N'
AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)) > 0)
THEN
UPDATE
ADDRESSES a
SET
a.HOST_NAME = :HN,
a.ADDRESS_TYPE = 'Assigned',
a.NOTES = :NOTE
WHERE
a.SHORT_IP_ADDRESS = :IPADD;
update_count = 1;
SUSPEND;
ELSE
update_count = 0;
SUSPEND;
END^
SET TERM ; ^
GRANT EXECUTE
ON PROCEDURE sp_test TO SYSDBA;
Using COUNT to check is there records to update is not the best way, use EXISTS instead, ie your IF would be
IF(EXISTS(SELECT 1 FROM ADDRESSES a
WHERE a.ADDRESS_TYPE = 'Reserved'
AND a.ALIVE = 'N'
AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)))
THEN
But there seems to be a problem with your return value, update_count - you return 1 if you execute the UPDATE, but the actual number of rows affected by the statement might be something else. I suggest you use ROW_COUNT context variable instead. So your procedure would be
ALTER PROCEDURE sp_test (
IPADD Varchar(32),
HN Varchar(32),
NOTE Varchar(200) )
RETURNS ( update_count integer )
AS
BEGIN
IF(EXISTS(SELECT 1 FROM ADDRESSES a
WHERE (a.ADDRESS_TYPE = 'Reserved')
AND (a.ALIVE = 'N')
AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)))
THEN BEGIN
UPDATE ADDRESSES a SET
a.HOST_NAME = :HN,
a.ADDRESS_TYPE = 'Assigned',
a.NOTES = :NOTE
WHERE a.SHORT_IP_ADDRESS = :IPADD;
update_count = ROW_COUNT;
END ELSE update_count = 0;
SUSPEND;
END^