Apply IF conditional at the end of the query - sql

I'm new in sql server and I have WHERE clause like this:
WHERE[D].[IsLocked] = 0
AND(#StartDate IS NULL OR ISNULL([TA].[ModifiedDate], [TA].[CreationDate]) >= #StartDate)
AND(#EndDate IS NULL OR ISNULL([TA].[ModifiedDate], [TA].[CreationDate]) <= #EndDate)
AND((CASE WHEN[T].[TaskStatusId] = '09E02513-00AD-49E3-B442-A9ED2833FB25'
THEN 1 ELSE 0 END) = #Completed)
AND((#FilterEmpKey IS NULL AND[TA].[EmpKey] = #CurrentEmpKey)
OR (ISNULL([TA].[ModifiedAssignedBy], [TA].[AssignatedBy]) = #FilterEmpKey
AND[TA].[EmpKey] = #CurrentEmpKey))
But now I want to add if conditional in order to add more filters at the end of query like:
IF(#FilterEmpGuid IS NOT NULL)
AND[TA].[EmpKey] = #CurrentEmpKey
AND[TA].[AssignatedBy] = #CurrentEmpKey
AND[TA].[EmpKey] = #FilterEmpKey
But I get:
The multi-part identifier [TA].[EmpKey] could not be bound
What am I doing wrong?

IF conditionals are only for use outside sql queries, such as in procedures etc.
In a query itself you are limited to AND, OR and CASE statements, so you will need to rewrite your IF conditional for this:
AND (#FilterEmpGuid IS NULL
OR (
[TA].[EmpKey] = #CurrentEmpKey
AND[TA].[AssignatedBy] = #CurrentEmpKey
AND[TA].[EmpKey] = #FilterEmpKey
))

You could move the additional filter options into a scalar function.
If you know the additional fields that may be filtered, you may be able to get away with something like:
CREATE FUNCTION dbo.ExtendFilter(
#column_value VARCHAR(50), #param_value VARCHAR(50)
)
RETURNS BIT
AS
BEGIN
DECLARE #return BIT = 1; -- default RETURN to 1 ( include ).
IF ( NULLIF( #param_value, '' ) IS NOT NULL )
BEGIN
-- compare the column's value to the param value
IF ( #column_value <> #param_value )
SET #return = 0; -- don't include this record.
END
RETURN #return;
END
GO
And then use it like:
WHERE
{ other WHERE stuff }
AND dbo.ExtendFilter( [TA].[EmpKey], #CurrentEmpKey ) = 1
AND dbo.ExtendFilter( [TA].[AssignatedBy], #CurrentEmpKey ) = 1
AND dbo.ExtendFilter( [TA].[EmpKey], #FilterEmpKey ) = 1
Mind you this is just an example. You'd want to check #pram_value for NULL, etc...

Related

SQL Server - CASE on where clause

I'm working on a stored procedure that is a select query. Under the WHERE clause I am filtering the return results to return only if there is a PageTitle= 'STA'
Here is am example of my query :
#InputCountryId INT,
#InputIndustryId INT
AS
BEGIN
SELECT
r.IdCountry,
r.IdIndustry,
r.PageTitle,
r.IndustryName
From dbo.Reports r
WHERE
r.IdCountry = #InputCountryId
r.IdIndustry = #InputIndustryId
r.PageTitle = 'STA'
END
The ending condition r.PageTitle I would like it to be applied ONLY IF InputCountry = 1 if not; do not include the filter.
I've attempted this by including a CASE. I am having a syntax error any time I try and introduce this case. Is this something that is possible? Am I implementing it incorrectly?
Here is an example of the stored proc with the CASE included.
#InputCountryId INT,
#InputIndustryId INT
AS
BEGIN
SELECT
r.IdCountry,
r.IdIndustry,
r.PageTitle,
r.IndustryName
From dbo.Reports r
WHERE
r.IdCountry = #InputCountryId
r.IdIndustry = #InputIndustryId
CASE WHEN #InputCountryId = 1 THEN
r.PageTitle = 'STA'
END
END
Try it this way:
WHERE
r.IdCountry = #InputCountryId and
r.IdIndustry = #InputIndustryId and
(#InputCountryId <> 1 or r.PageTitle = 'STA')
You dont need case statement. You can use OR clause
WHERE
r.IdCountry = #InputCountryId
r.IdIndustry = #InputIndustryId
(#InputCountryId != 1 OR r.PageTitle = 'STA')
this only filters PageTitle with STA when InputCountry is 1
I can't test with your data, but here is a CASE in a WHERE clause that works.
DECLARE #Variable INT = 3
SELECT GETDATE()
WHERE 1 =
CASE
WHEN #Variable = 1 THEN 1
WHEN #Variable = 3 THEN 1
WHEN #Variable = 5 THEN 1
ELSE 0
END

Reusing Value of a subquery in Else clause

is there any way i can use the value of X in the if clause in the else clause
if #bid_value>(SELECT MAX(bid_value) AS X FROM dbo.auctionDetails WHERE status = 0 AND vehicle_id=#vid GROUP BY vehicle_id)
BEGIN
//some code
END
ELSE IF X=NULL
BEGIN
//some code
END
Why don't you create a var for the value?
DECLARE #maxValue INT
SELECT #maxValue = MAX(bid_value)
FROM dbo.auctionDetails
WHERE status = 0 AND vehicle_id = #vid
IF (#bid_value > #maxValue)
BEGIN
// some code
END
ELSE IF (#maxValue IS NULL)
BEGIN
// some code
END
A comment about how you are getting the MAX value: As you are filtering by vehicle_id = #vid, you don't need GROUP BY clause since you will get results for only one value of vahicle_id
You would typically assign the results of the query to a variable.
If you are running SQL Server:
DECLARE #max_bid_value INT;
SELECT #max_bid_value = MAX(bid_value)
FROM dbo.auctionDetails
WHERE status = 0 AND vehicle_id = #vid;
IF #bid_value > #max_bid_value
BEGIN
//some code
END
...
Note that I removed the GROUP BY clause from the original query - I think that this makes it clearer that it should always return a scalar value.
Note that if you want to check if a variable is null, you need #bid is null rather than #bid = null.
Your query should be like below :
DECLARE #X INT
SET #X = (SELECT MAX(bid_value) AS X FROM dbo.auctionDetails WHERE status = 0 AND vehicle_id=#vid);
IF #bid_value>#MAX
BEGIN
//some code
END
ELSE IF X=NULL
BEGIN
//some code
END

Optional where clause depending on parameter value

I want the where statement for this query to be optional depending on what the value of parameter #RetrieveAll is. If #RetrieveAll is false/null the where statement is used, if it is true it should be ignored.
#IncludeErrors bit = 1,
#IncludeAccess bit = 1,
#IncludeLogins bit = 1,
#RetrieveAll bit = NULL
SELECT
//...
FROM
(
) AS a
WHERE
a.RowNumber BETWEEN #ItemCountStart AND #ItemCountEnd
Is there way to do this?
SELECT
//...
FROM
(
) AS a
WHERE
(a.RowNumber BETWEEN #ItemCountStart AND #ItemCountEnd AND #RetrieveAll IS NULL)
OR
#RetrieveAll IS NOT NULL
You should try this,
Select * from Tablename a
Where
1 = case when isnull(#RetriveAll,0) == 0 then
case when a.RowNumber BETWEEN #ItemCountStart AND #ItemCountEnd then 1 else 0 end
else 1 end

If Else not working in TSQL

If is never working. Always falling in else condition. I have debugged and checked #nextapprover is not null.
IF (#nextApprover != NULL)
BEGIN
UPDATE CallWatching
SET EmployeeNo = #employeeNo
WHERE #SRFID = MasterCode;
INSERT INTO CallForwarding (
MasterCode
,EmployeeNo
,ApproverNo
,IsForwarded
,ForwardBy
)
VALUES (
#SRFID
,#EmployeeNo
,#nextApprover
,0
,#EmployeeNo
)
END
ELSE
BEGIN
UPDATE CallWatching
SET STATUS = 1
WHERE #SRFID = MasterCode;
END
Use IS NOT NULL
i.e. Change: if(#nextApprover!=null)
to IF(#nextApprover IS NOT NULL)
Additionally you should <> instead of != as it is ANSI compliant

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^