In Firebird, how do I write multiple if statements in a procedure?

随声附和 提交于 2019-12-11 08:42:42

问题


I'm writing an sql script in Firebird for an assignment. First, I have to create a 2 column table and add some values (the values aren't supposed to do anything yet)

--Create the table
create table salary_class (
class varchar(5),
occurrence int ) ;

commit work;

--Add Values to our table
insert into salary_class (class, occurrence)
values ('ELITE', 0);
insert into salary_class (class, occurrence)
values ('HIGH', 0);
insert into salary_class (class, occurrence)
values ('MID', 0);
insert into salary_class (class, occurrence)
values ('LOW', 0);

commit work;

After that worked is committed, I create a procedure. It is supposed to return a certain string based on the number that is passed into it.

--Create f_class procedure
set term # ;
create procedure f_class(salary SALARY)

returns (lv VARCHAR(10)) as
begin
    --If statements for each occurrence level
    if (salary <= 39999) then
    lv = 'LOW';
    suspend;

    if (salary <= 67999) then
    lv = 'MID';
    suspend;

    if (salary <= 99999) then
    lv = 'HIGH';
    suspend;

    if (salary >= 100000) then
    lv = 'ELITE';
    suspend;

end#

set term ; #

--Demonstrate that f_class function works correctly
  select lv from f_class(20000);
  select lv from f_class(67999);
  select lv from f_class(68000);
  select lv from f_class(120000);

Calling the function gives me

LV
null
null
null
ELITE

But it's supposed to give me

LV
LOW
MID
HIGH
ELITE

If anyone could shine some light on this, it would be much appreciated. Been pulling my hair out over the Firebird manual the past 2 days.


回答1:


You have multiple problems in your code. The first problem is that you use suspend unconditionally, which means that each invocation of the stored procedure returns 4 rows, which depending on the condition may contain a null value, or a previous value.

This doesn't seem what you expect, as the expected output of your question seems to match the expectation for each individual salary, while the actual output is the output of the last statement (select lv from f_class(120000);).

The second problem is that you use individual if statements, which leads to multiple conditions being evaluated (eg value 1 will returnlow, mid and high (2x), and value 67999 will return null, mid and high (2x), etc).

To solve your problems there are a few solutions:

  1. Use a chained if .. then .. else:

    if (salary <= 39999) then
        lv = 'LOW';
    else if (salary <= 67999) then
        lv = 'MID';
    else if (salary <= 99999) then
        lv = 'HIGH';
    else if (salary >= 100000) then
        lv = 'ELITE';
    
    suspend;
    

    The single suspend will also prevent the output of multiple rows.

  2. Replace the if-statements with a searched case:

    lv = case 
            when salary <= 39999 then 'LOW'
            when salary <= 67999 then 'MID'
            when salary <= 99999 then 'HIGH'
            when salary >= 100000 then 'ELITE'
         end;
    
    suspend;
    

    You can also replace the last when salary >= 100000 then 'ELITE' with else 'ELITE'

However you describing this as a function in your question makes me think that this might be the wrong solution altogether. Stored procedures are not functions, they are procedures that optionally return values or - with suspend - produce dynamic 'tables' (a result set). If you need a real function, and you are using Firebird 3, then use stored functions:

create function f_class(salary SALARY) returns varchar(10)
as
begin
    return case 
        when salary <= 39999 then 'LOW'
        when salary <= 67999 then 'MID'
        when salary <= 99999 then 'HIGH'
        when salary >= 100000 then 'ELITE'
    end;
end

You can then use it like

select f_class(120000) from rdb$database;

The use of rdb$database is purely for illustration here, a stored function can be used anywhere a normal SQL function can be used.



来源:https://stackoverflow.com/questions/49962078/in-firebird-how-do-i-write-multiple-if-statements-in-a-procedure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!