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

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^

Related

SQL Stored Procedure Parameter set to Uppercase

I want to force a user's string input in a stored procedure to uppercase. I tried writing UPPER prior to the #parameterName but I got a syntax error. Is this possible? Would be it be better suited to convert the string to uppercase in the statement itself? Here's the code to my SP where I was attempting to use UPPER in the parameter definition.
ALTER PROCEDURE [dbo].[UpdateEntries]
UPPER #ENTRY_TYPE NVARCHAR(20) = '',
UPPER #ENTRY_NAME NVARCHAR(50),
#CLASS_TYPE_ID INT,
#ENTRY_PRICE DEC(4,2),
#ENTRY_DESCRIPT NVARCHAR(max),
#PET_FRIENDLY BIT,
#AGE_RESTRICTION BIT,
#PRICE_RANGE_ID INT,
#RESTAURANT_TYPE_ID INT NULL
AS
BEGIN
SET NOCOUNT ON;
IF #ENTRY_TYPE = 'ACTIVITY'
BEGIN
UPDATE ACTIVITY_DETAIL
SET ACT_NAME = #ENTRY_NAME,
ACT_PRICE = #ENTRY_PRICE,
ACT_DESCRIPT = #ENTRY_DESCRIPT,
ACT_DOG_FRIENDLY = #PET_FRIENDLY,
ACT_AGE_RESTRICTION = #AGE_RESTRICTION,
ACT_PRICE_RANGE_ID = #PRICE_RANGE_ID
WHERE NOT EXISTS (SELECT 1 FROM dbo.[ACTIVITY_DETAIL] WHERE ACT_NAME = #ENTRY_NAME);
END
IF #ENTRY_TYPE = 'BUSINESS'
BEGIN
UPDATE BUSINESS_DETAIL
SET BUSINESS_NAME = #ENTRY_NAME,
BUSINESS_PRICE = #ENTRY_PRICE,
BUSINESS_DESCRIPT = #ENTRY_DESCRIPT,
BUSINESS_DOG_FRIENDLY = #PET_FRIENDLY,
BUSINESS_PRICE_RANGE_ID = #PRICE_RANGE_ID
WHERE NOT EXISTS (SELECT 1 FROM dbo.[BUSINESS_DETAIL] WHERE BUSINESS_NAME = #ENTRY_NAME);
END
IF #ENTRY_TYPE = 'HOTEL'
BEGIN
UPDATE HOTEL_DETAIL
SET HOTEL_NAME = #ENTRY_NAME,
HOTEL_PRICE = #ENTRY_PRICE,
HOTEL_DESCRIPT = #ENTRY_DESCRIPT,
HOTEL_PET_FRIENDLY = #PET_FRIENDLY,
HOTEL_PRICE_RANGE_ID = #PRICE_RANGE_ID
WHERE NOT EXISTS (SELECT 1 FROM dbo.[HOTEL_DETAIL] WHERE HOTEL_NAME = #ENTRY_NAME);
END
IF #ENTRY_TYPE = 'RESTAURANT'
BEGIN
UPDATE RESTAURANT_DETAIL
SET RESTAURANT_NAME = #ENTRY_NAME,
RESTAURANT_PRICE_AVG = #ENTRY_PRICE,
RESTAURANT_DESCRIPT = #ENTRY_DESCRIPT,
RESTAURANT_DOG_FRIENDLY = #PET_FRIENDLY,
RESTAURANT_PRICE_RANGE_ID = #PRICE_RANGE_ID
WHERE NOT EXISTS (SELECT 1 FROM dbo.[RESTAURANT_DETAIL] WHERE RESTAURANT_NAME = #ENTRY_NAME);
END
END
UPPER #ENTRY_TYPE NVARCHAR(20) = '',
UPPER #ENTRY_NAME NVARCHAR(50),
These are wrong. No such usage.
#ENTRY_TYPE NVARCHAR(20) = '',
#ENTRY_NAME NVARCHAR(50),
SELECT #ENTRY_TYPE = UPPER(#ENTRY_TYPE);
SELECT #ENTRY_NAME = UPPER(#ENTITY_NAME);

Apply IF conditional at the end of the query

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...

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

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.

An object or column name is missing or empty

I am getting the following error
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Add a name or single space as the alias name.
for the query show below:
CREATE PROC [dbo].[Sp_Table1] #ctlg_ipt_event_id int
AS
SET NOCOUNT ON
DECLARE #current_status NCHAR(1), #ready_status_code NCHAR(1)
DECLARE #current_action NCHAR(1), #ready_action_code NCHAR(1), #done_action_code NCHAR(1)
DECLARE #pst_user_id int
SELECT #current_status = status_code
,#current_action = action_code
,#pst_user_id = last_mod_user_id
FROM merch_ctlg_ipt_event
WHERE ctlg_ipt_event_id = #ctlg_ipt_event_id
Select #ready_status_code = 'o'
, #ready_action_code = 'a'
, #done_action_code = 'b'
IF #current_status <> #ready_status_code OR #current_action <> #ready_action_code
BEGIN
RETURN
END
BEGIN TRAN
declare #rows int
,#err int
,#i int
,#name nvarchar(50) --COLLATE SQL_AltDiction_Pref_CP850_CI_AS
,#resolved_View_Name_category_id int
,#xref_value int
,#availability_start_date datetime
,#availability_end_date datetime
,#status_code int
,#last_mod_user_id int
,#CT datetime
,#supplier_id int
,#View_Name_id int
select #i = 1
,#CT = current_timestamp
Select Distinct mc.name,
mc.resolved_View_Name_category_id,
mc.xref_value,
mc.availability_start_date,
mc.availability_end_date,
mc.status_code,
CASE WHEN mc.last_mod_user_id = 42
THEN #pst_user_id
ELSE mc.last_mod_user_id
END as last_mod_user_id,
CURRENT_tsp
,IDENTITY(int,1,1) as rn
,si.supplier_id
,si.View_Name_id
into #temp
FROM View_Name AS si
JOIN merch_ctlg_ipt_View_Name AS mc
ON mc.supplier_id = si.supplier_id
AND mc.resolved_View_Name_id = si.View_Name_id
AND mc.cat_imp_event_id = #ctlg_ipt_event_id
AND mc.accept_flag = 'y'
WHERE si.shipper_flag = 'n'
select #rows=##ROWCOUNT,#err=##error
if #rows > 0 and #err=0
Begin
While #i <=#rows
begin
SElect #name = name,
#resolved_View_Name_category_id = resolved_View_Name_category_id,
#xref_value = xref_value,
#availability_start_date = availability_start_date,
#availability_end_date = availability_end_date,
#status_code = mc.status_code,
#last_mod_user_id =last_mod_user_id ,
,#i=#i+1
,#supplier_id=supplier_id
,#View_Name_id=View_Name_id
from #temp
Where rn=#i
UPDATE View_Name
SET name = #name,
View_Name_category_id = #resolved_View_Name_category_id,
xref_value = #xref_value,
availability_start_date = #availability_start_date,
availability_end_date = #availability_end_date,
status_code = #status_code,
last_mod_user_id = #last_mod_user_id ,
last_mod_timestamp = #CT
Where #sup_id = supplier_id
AND #View_Name_id = View_Name_id
AND shipper_flag = 'n'
IF ##ERROR > 0
BEGIN
ROLLBACK TRAN
RETURN
END
End
End
UPDATE
merch_ctlg_ipt_event
SET action_code = #done_action_code,
last_mod_timestamp = #CT
WHERE ctlg_ipt_event_id = #ctlg_ipt_event_id
IF ##ERROR > 0
BEGIN
ROLLBACK TRAN
RETURN
END
COMMIT TRAN
Return
go
Could you please help ?
You have 2 commas in a row here
#last_mod_user_id =last_mod_user_id ,
,#i=#i+1
Also probably not relevant to the error message but you have a line
Where #sup_id = supplier_id
but the declared variable is #supplier_id