在ORACLE存储过程或函数中,若含有以下语句SELECT xxx INTO xxx FROM XXX where 时,若SELECT出来没有记录时,将产生NO_DATA_FOUND错误,因为该句带WHERE 条件,很有可能SELECT 出来是没有记录的,有什么好办法避免NO_DATA_FOUND错误呢?以下有两种方法,但我觉得不好
方法一:
先SELECT 一将,判断有没记录。这样将会SELECT 两次,如果是复杂的SELECT 语句,如SELECT ....FROM A INNER JOIN b ........LEFT JOIN Z ON..... WHERE .......一大堆的那种,这会严重影响效率。方法二:(我暂时用的)
SELECT A.xxx INTO xxx
FROM DUAL LEFT JOIN(
SELECT xxx
FROM xxx
WHERE xxxxxxxxx) A ON 1 = 1;
但LEFT JOIN后面很复杂或SELECT 字段比较多且复杂的话,好像比较麻烦。请教高手还有其它好办法吗?
方法一:
先SELECT 一将,判断有没记录。这样将会SELECT 两次,如果是复杂的SELECT 语句,如SELECT ....FROM A INNER JOIN b ........LEFT JOIN Z ON..... WHERE .......一大堆的那种,这会严重影响效率。方法二:(我暂时用的)
SELECT A.xxx INTO xxx
FROM DUAL LEFT JOIN(
SELECT xxx
FROM xxx
WHERE xxxxxxxxx) A ON 1 = 1;
但LEFT JOIN后面很复杂或SELECT 字段比较多且复杂的话,好像比较麻烦。请教高手还有其它好办法吗?
解决方案 »
- Oracle新手问题
- 查找数据
- [200分]在oracle中,如何把表结构和表数据生成xml格式!
- 如何把数据表导成excel文件,又如何把excel文件的内容导入到数据表中,在导入时excel文件需要什么要求?
- oracle中创建视图force的作用是什么?
- 方法怎么返回一个字符串数组
- 求助:简单问题_____SQL中的IDENTITY(1,1)在ORACLE的SQL中应该改成什么?
- 请问如何判断存储过程是否创建成功?
- 基于solaris8安装oracle817的问题
- 执行存储过程总是出现未响应(原来是正常的),与系统表空间满了有无关系?
- DOS下連接Oracle數據庫--在綫等--急
- 一个用户在另一个用户下创建表的 权限问题
/* Oracle settings */
set pagesize 0
set feedback off
...
/*DECLARE variables*/
...
begin
LOOP
UTL_FILE.GET_LINE(V_INPUT_HANDLE,V_LINE);
--get input file line by line
V_POS_1 := INSTR(V_LINE, ',', 1,1);
V_RGISNO := SUBSTR(V_LINE,0, V_POS_1-1);
--get first filed of line
SELECT ACCOUNT_NO INTO V_ARBOR_ACCT_NO FROM CUSTOMER_ID_ACCT_MAP@arbor1
WHERE external_id = V_RGISNO
AND EXTERNAL_ID_TYPE IN ( 2, 3, 5, 6, 7, 13, 16, 530, 531, 532, 533, 534, 535 )
AND INACTIVE_DATE IS NULL; IF V_IGNORE != 1 THEN
SELECT CUSTOMERID INTO V_TALLYMAN_CUS_NO FROM RL_CUSTOMERS
WHERE TMC_CMF_11 = V_ARBOR_ACCT_NO;
IF V_IGNORE != 1 THEN
SELECT ID INTO V_TALLYMAN_ACCT_NO FROM ACCOUNTS
WHERE CUSTOMERID = V_TALLYMAN_CUS_NO
AND LEADER = 'Y';
UTL_FILE.PUT_LINE(V_ACTLOG_HANDLE,'V_TALLYMAN_ACCT_NO=' || V_TALLYMAN_ACCT_NO);
END IF;/*UPDATE TABLE ADN INSERT TABLE */
...
...
EXCEPTION
WHEN NO_DATA_FOUND THEN V_IGNORE := 1;
V_NOUPDATE_COUNTER := V_NOUPDATE_COUNTER + 1;
UTL_FILE.PUT_LINE(V_ERROR_HANDLE, V_LINE);
WHEN OTHERS THEN
...
END;
我之前已经提到,对于简单语句,可先查记录数,再发出SQL语句。若是复杂语句,会严重影响效率,因为有些存储过程的SQL语句非常复杂(逻辑很多,整个存储过程有1K多行),执行一次需要花费大量时间。而且,发生NO_DATA_FOUND时,我并不想终止程序执行,下面还有一堆SQL语句要执行,所以未用EXCEPTION。在MSSQL里,若SELECT没有数据,会自动赋NULL值给变量。不知道哪位高人还有更好的建议
-- Local variables here
i INT;
b INT:=5;
c INT:=0;
d INT:=0;
BEGIN
FOR i IN 1.. 10 LOOP
dbms_output.put_line('the number is '||i);
begin
IF i>5 THEN
d:=b/c;
END IF;
exception
--异常在内部处理了。
when others then
Dbms_Output.put_line('------Divided by Zero');
end;
END LOOP;
exception
WHEN OTHERS THEN
BEGIN
dbms_output.put_line('OtherError');
END;end;
我的异常全部抛出,暂不讨论异常问题,主题问题有何高见。。
你们一般是如何处理这类情况的呢?
when no_data_found then
...oracle 自带的no_data_found 异常抛出不可以处理么
select ... into ............;
的地方改写成:
begin
select ... into ............;
exception
when no_data_found then
.......
end;
看看怎么样???还有一种方法是利用游标处理
select ... into ............;
这样的语句。比较麻烦,主要是利用游标可以返回%notfound的特性。以上两种方法在实际开发过程中都用到过。可以参考一下。
FETCH m_Pjer1401_Cursor
INTO m_recordTemp;
EXIT WHEN m_Pjer1401_Cursor%NOTFOUND;
看错了dobetterthatnthink(饥不择食) 后面的例子。我想你那种方法应该可以的。不过还没试。定义游标方式也可以,但感觉比较麻烦。要滚动,浪费资源比较多(估计,呵呵)。xiaoxiao1984(潇潇) 说的方式也是指饥不择食的那种处理方式吧。