我正在尝试根据给每个用户的不同级别检查菜单中条目的两种授权级别。
但是oracle sql中没有数据异常阻止我检查第二个表是否有授权。
这是我的代码:
declare
v_count number;
v_name varchar2(255);
begin
select DASHBOARD into v_count from RCM_ADMINISTRATOR where USER_NAME = :APP_USER;
select MANAGER into v_name from RCM_ADMINISTRATION_TEAMS where MANAGER = :APP_USER;
if v_count >= 1 then
return true;
end if;
if v_name is not null then
return true;
end if;
if v_count = 0 then
return false;
end if;
EXCEPTION WHEN NO_DATA_FOUND THEN
return false;
end;
有没有办法让它如果我从第一个查询中得不到数据,我仍然可以运行第二个查询?
答案 0 :(得分:3)
这是一个非常常见的问题,有许多解决方案。
一个选项是在您尝试执行的每个SELECT INTO周围放置一个BEGIN / EXCEPTION / END块。
declare
v_count number;
v_name varchar2(255);
begin
BEGIN
select DASHBOARD into v_count from RCM_ADMINISTRATOR where USER_NAME = :APP_USER;
EXCEPTION when no_data_found THEN v_count := null;
END;
BEGIN
select MANAGER into v_name from RCM_ADMINISTRATION_TEAMS where MANAGER = :APP_USER;
EXCEPTION when no_data_found THEN v_name := null;
END;
if v_count >= 1 then
...etc...
我经常发现使用MAX更容易:
declare
v_count number;
v_name varchar2(255);
begin
select max(DASHBOARD) into v_count from RCM_ADMINISTRATOR where USER_NAME = :APP_USER;
select max(MANAGER) into v_name from RCM_ADMINISTRATION_TEAMS where MANAGER = :APP_USER;
if v_count >= 1 then
...etc...
这是一种懒惰的技术,如果你不小心,它可以掩盖ORA-01422错误(确切的提取返回超过请求的行数)。但是如果你知道你的查询只返回0或1行,那么它将正常工作。
答案 1 :(得分:1)
您的代码存在一些问题。您正在使用匿名块并返回值,这是不可能的。您可以编写一个返回BOOLEAN
值(True
或False
)的函数。但是,根据Oracle文档,它没有用处
http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/datatypes.htm#CJACJGBG
您无法将值
TRUE
和FALSE
插入数据库列。 您无法在BOOLEAN
变量中选择或获取列值。 从SQL查询调用的函数不能使用任何BOOLEAN
参数。 内置SQL函数(例如TO_CHAR
)也不能;代表 输出中的BOOLEAN
值,必须使用IF-THEN or CASE
构造 将BOOLEAN
值转换为其他类型,例如0或1,'Y'或 'N','true'或'false'等等。
因此,在代码中,VARCHAR2
用作RETURN
参数。
将APP_USER
作为函数参数传递,而不是使用绑定变量。
对于您的条件,每个查询必须执行而不管异常,您可以将它放在单独的BEGIN..END
块中。
从存储过程中使用RETURN
后,在尝试实现异常后,无法跳回到代码的其余部分。相反,如果不满足其他条件,请使用前一个exit_code
之前的代码将值存储在变量RETURN
和END
中以最终返回退出代码。
CREATE OR REPLACE FUNCTION f_test_ret(p_app_user IN VARCHAR2)
RETURN VARCHAR2
AS
v_count NUMBER;
v_name VARCHAR2(255);
exit_code VARCHAR2(6);
BEGIN
BEGIN
SELECT DASHBOARD
INTO v_count
FROM RCM_ADMINISTRATOR
WHERE USER_NAME = p_app_user;
EXCEPTION
WHEN NO_DATA_FOUND THEN
exit_code := 'FALSE';
END;
BEGIN
SELECT MANAGER
INTO v_name
FROM RCM_ADMINISTRATION_TEAMS
WHERE MANAGER = p_app_user;
EXCEPTION
WHEN NO_DATA_FOUND THEN
exit_code := 'FALSE';
END;
IF v_count >= 1 THEN
RETURN 'TRUE';
END IF;
IF v_name IS NOT NULL THEN
RETURN 'TRUE';
END IF;
IF v_count = 0 THEN
RETURN 'TRUE';
END IF;
RETURN exit_code;
END;
/