我在Firebird中编写了一个sql脚本来进行分配。首先,我必须创建一个2列表并添加一些值(这些值不应该做任何事情)
--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;
在提交工作之后,我创建了一个程序。它应该根据传递给它的数字返回某个字符串。
--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);
调用该函数给我
LV
null
null
null
ELITE
但它应该给我
LV
LOW
MID
HIGH
ELITE
如果有人能够对此有所启发,我们将不胜感激。在过去的两天里,我一直把头发拉过Firebird手册。
答案 0 :(得分:2)
您的代码中存在多个问题。第一个问题是您无条件地使用suspend
,这意味着每次调用存储过程都会返回4行,这取决于条件可能包含null
值或先前的值。
这似乎不是您所期望的,因为您的问题的预期输出似乎与每个单独薪水的期望相匹配,而实际输出是最后一个语句的输出(select lv from f_class(120000);
)。
第二个问题是您使用单独的if
语句,这会导致评估多个条件(例如,值1将返回low
,mid
和high
(2x ),值67999将返回null
,mid
和high
(2x)等。
为了解决您的问题,有一些解决方案:
使用链式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;
单suspend
也会阻止输出多行。
将if
- 语句替换为搜索到的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;
您还可以将最后when salary >= 100000 then 'ELITE'
替换为else 'ELITE'
但是,您在问题中将其描述为函数让我觉得这可能是完全错误的解决方案。存储过程不是函数,它们是可选地返回值的过程,或者 - suspend
- 生成动态“表”(结果集)。如果您需要真正的功能,并且您正在使用Firebird 3,请使用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
然后您可以像
一样使用它select f_class(120000) from rdb$database;
rdb$database
的使用纯粹是为了说明,可以在任何可以使用普通SQL函数的地方使用存储函数。