시스템 중 하나에서 SP의 유지 보수성을 향상시키려는 동안 루프를 사용하는 것이 값 배열 (이 경우 테이블 이름)을 하드 코딩 된 것보다 더 좋다고 결정했습니다. 그에 따라 코드를 다시 고려하여 시스템에 테이블을 추가하거나 제거하면 어레이를 편집 할 필요가 없었습니다. 잠깐 동안의 헛소리와 루프의 위치를 떠나서 (나는 그들에 대한 논쟁을 잘 알고있다.) 아무도 무슨 일이 일어 났는지 설명 할 수 있을까?루프를 사용하지 않는 저장 프로 시저의 Oracle For 루프
SourceUser와 DestUser가 같은 데이터베이스에 있고 두 테이블이 동일한 테이블 스페이스에있는 사용자를 상상해보십시오. SourceUser의 많은 저장 프로 시저가보고를 위해 SourceUser에서 DestUser로 데이터를 채 웁니다. 이 작업의 일부로 실행되는 첫 번째 프로시 저는 DestUser의 모든 테이블을 삭제하고 다시 만듭니다. 다시 말하면, 여기에서 그렇게하는 것의 상대적인 장점을 논하는 것이 아닙니다.
SourceUser는 DestUser에 대해 모든 테이블 삭제 및 모든 테이블 생성 권한을 갖습니다. DestUser에는 유지하려는 테이블이 하나 있습니다. sTarget_DB이 DestUser로 설정이 경우
Begin
For T In (SELECT TABLE_NAME FROM all_tables WHERE TABLE_NAME != 'MIDBLOG' AND OWNER = sTarget_DB) Loop
Begin
Execute Immediate('Drop Table ' || sTarget_DB || '.' || T.TABLE_NAME);
Exception
When Others Then
--Don't care if we get an exception here as most likely the table wasn't there to be dropped in the first place.
NULL;
End;
End Loop;
End;
을,이 코드는 SOURCEUSER에 대해 실행되는 : 그래서,이 과정에서 구축 된 SQL은 다음과 같습니다.
프로 시저가 실행될 때 테이블이 삭제되지 않았 음을 알았습니다. (시작하기 전에 MIDBLOG라는 이름의 테이블이 몇 개 있다는 것을 확인했습니다). 나는 SQL Developer 디버그 모드에서 실행했고 실행은 루프의 내부에 도달하지 못했다. 처리 할 행이 없다고 생각되는 것처럼 보이지만 select 문이 몇 개의 테이블 이름을 반환한다는 것을 확실히 알고있다.
다음 나는이에 개정 :
Begin
For T In (SELECT TABLE_NAME FROM all_tables WHERE OWNER = sTarget_DB) Loop
Begin
If T.TABLE_NAME != 'MIDBLOG' THEN
Execute Immediate('Drop Table ' || sTarget_DB || '.' || T.TABLE_NAME);
End If;
Exception
When Others Then
--Don't care if we get an exception here as most likely the table wasn't there to be dropped in the first place.
NULL;
End;
End Loop;
End;
내가 제거 싶지 않았다 매우 하나 제거이 유일한 테이블을 실행 한 후! 더 이상한 점은 select 쿼리가 한 행만 반환하는 것처럼 루프가 한 번만 실행된다는 것입니다. SQL Developer 3.2에서 디버그 절차를 실행하면 문제가 발생할 수 있습니다. 우리는 SQL Developer (아마도 3.1)의 동료 PC에서 동일한 작업을 수행했으며 루프는 한 번만 실행되었지만 이번에는 테이블 MIDBLOG를 삭제하지 않고 다른 모든 작업을 혼자 남겨두기로 결정했습니다.
SQL Developer에서 위의 예제 중 하나를 익명 블록으로 실행하면 예상대로 수행됩니다. 좀 더 자세한 명시 적 커서 선언을 시도하고 이전과 같은 결과를 얻었습니다. 아무런 예외도 없었습니다.
모두 Oracle 10g Enterprise Edition 릴리스 10.2.0.4.0 (64 비트)이었습니다. 오라클 11g Enterprise Edition Release 11.2.0.1.0 (64bit)에서 사용하자마자 잘 작동했습니다. 왜 이런 기본적인 요구 사항이 두 버전에서 거칠게 다른 행동을 보여야합니까? 동일한 코드 비트를 사용하여 두 버전 모두에서 원하는대로 작동 할 수 있습니까?
'others' 예외와 그에 따른 주석에 관해서는'drop table' 명령이 존재하지 않는 테이블 이외의 다른 명령을 내릴 수있는 몇 가지 이유가 있습니다. -942 예외를 명시 적으로 처리하고 다른 예외를 올바르게 처리하는 것이 좋습니다. –
사실입니다 만 실제 예외는 내가 생각한 시나리오에서 관심이 없었습니다. 3 1/2 년 전이었습니다! –