我必须写一个pl / sql代码(实际上是一个函数),它以郊区为参数返回一个邮政编码 代码是这样的:
create or replace
FUNCTION get_postCode(p_suburb IN varchar2)
RETURN varchar2
IS
--
v_postcode varchar2;
--
CURSOR c1 IS
SELECT locality, postcode FROM table_postcode;
--
BEGIN
--
FOR r1 IN c1
loop
IF upper(r1.locality) = upper(p_suburb)
THEN
v_postcode := r1.postcode;
return v_postcode;
END IF;
exit WHEN c1%notfound;
END loop;
-- return v_postcode;
--
exception WHEN others then
v_postcode := null;
END;
table_postcode是从邮局获得的,它包含郊区(地方作为栏目中的列)和邮政编码以及与此案例无关的其他字段。
当我使用该函数时,它返回正确的值,当我将此函数用作SELECT子句的列时,如果我在FROM子句之后不添加任何其他子句,则仅返回。这对我来说很奇怪。
情况是:
select street, suburb, get_postcode(suburb) from my_table;
上面的行给出了结果,但是
select street, subur, get_postcode(suburb) from my_table order by suburb;
失败并给我以下错误消息:
ORA-06503: PL/SQL: Function returned without value
ORA-06512: at "U11254683.GET_POSTCODE", line 25
06503. 00000 - "PL/SQL: Function returned without value"
*Cause: A call to PL/SQL function completed, but no RETURN statement was
executed.
*Action: Rewrite PL/SQL function, making sure that it always returns
a value of a proper type.
如果我在一个块中调用该函数,如:
Declare
v_post varchar2(10);
Begin
v_post := get_postcode('Sydney');
DBMS_OUTPUT.PUT_LINE('The post code is '||v_post);
End;
结果是正确的,给了我2000。
答案 0 :(得分:5)
当找不到任何东西时,你应该返回一些东西。在exception
声明之前发表评论
return v_postcode;
编写例程的方式可能确实找不到任何内容,然后命中函数的末尾而不返回任何内容,因此错误"函数返回时没有值"。确实如此。
但是,通过直接在郊区选择,您可以更轻松地完成这项工作。但如果您将多个邮政编码发送到郊区(如果可能的话),您会怎么做?
create or replace FUNCTION get_postCode(i_suburb IN varchar2)
RETURN varchar2
IS
l_postcode varchar2;
BEGIN
select postcode
into l_postcode
where upper(i_suburb) = upper(locality);
--
return l_postcode;
exception
WHEN others then
return null;
END;
在这个版本中,如果一个郊区存在于多个邮政编码中,您将获得null。现在由您的设计决定如何处理这种情况。然后,您可以在异常
中处理它exception
when TOO_MANY_ROWS then
return '**Error** Several Values'; -- do something meaningful here
when NO_DATA_FOUND then
return null; -- if you want to return null on nothing found
答案 1 :(得分:0)
试试这个:
CREATE OR REPLACE FUNCTION get_postCode
(p_suburb IN varchar2)
RETURN varchar2
IS
v_postcode varchar2;
CURSOR c1 IS
SELECT locality, postcode FROM table_postcode;
BEGIN
FOR r1 IN c1 LOOP
EXIT WHEN c1%notfound;
IF upper(r1.locality) = upper(p_suburb) THEN
v_postcode := r1.postcode;
EXIT;
END IF;
END LOOP;
return v_postcode;
exception WHEN others then
return null;
END;
/
通过退出FOR
循环查找第一个帖子代码,您确保没有引发TOO_MANY_ROWS
异常。此外,通过将return
放在IF
语句之外,您确保在找不到任何内容时至少返回NULL
。