함수로 인식되지 않는 PL/SQL 변수로 인해 발생한 문제에 대한 답을 얻었을 때 누군가 내 솔루션이 왜 작동하는지 설명 할 수 있기를 바랬습니다. 그리고 "후드 아래에서"무슨 일이 일어나고 있는지.ORACLE PL/SQL 변수 함수 범위 - 필요 설명
배경 최적화 프로젝트의 일환으로
, 내가 저장 프로 시저 내의 개별 SQL 스크립트에 대한 통계를 수집하기 위해 노력하고 있습니다.
CREATE OR REPLACE myStoredProc (DATE_IN DATE, ERROR_OUT OUT VARCHAR2)
IS
BEGIN
--Truncate Temp Tables
--6 Individual SQL Scripts
EXCEPTION
--Error Handling
END;
난 그냥에 각 SQL 문을 드롭하기로 결정, 개별적으로 각 스크립트를 실행하려면 : 나는 해부 오전 저장된 프로 시저 내가 각각의 SQL 스크립트를 실행하기 위해 정의 할 필요가에서 형 날짜 매개 변수가
이러한 접근 방식을 t 언급 된 쿼리의 몇 괜찮 았는데 문제를
DECLARE
DATE_IN DATE := TO_DATE('16-JUL-2014','DD-MON-RR');
BEGIN
--Place individual script here
END;
하십시오 PL/SQL 블록과는 변수로의 DATE_IN
매개 변수를 공급 그의 DATE_IN
변수하지만, 매개 변수가 ORA-00904 오류 던지기 시작으로 DATE_IN
소요 외부 기능에 대한 참조를 하나 개의 쿼리 : 다른 개발자의 조언에
DECLARE
DATE_IN DATE := TO_DATE('16-JUL-2014','DD-MON-RR');
BEGIN
insert into temp_table
SELECT table1.field1,
table1.field2,
table2.fieldA,
MyFunction(table1.field1, DATE_IN) --This was the problem line
FROM
table1,
table2
WHERE EXISTS (inner query)
AND table1.keys = table2.keys
AND table2.date <= DATE_IN
END;
솔루션
을, 나는이었다 문제가되는 줄이 MyFunction(table1.field1, :DATE_IN)
이되도록 함수에 전달한 변수 인 DATE_IN
앞에 콜론 (:)을 추가하여이 오류를 해결할 수있었습니다. 내가 그 일을하자마자, 나의 실수가 사라졌고 문제없이 질의를 할 수 있었다.
결과에 만족했지만 다른 개발자는 PL/SQL 문에서 함수 나 다른 저장된 procs를 호출해야한다는 이유 만 설명 할 수 없었습니다. 나는 이것이 범위와 관련이 있다고 가정하지만이 콜론이 변수를보기 위해 함수에 필요한 이유에 대해 더 자세히 설명하고 싶습니다.
질문
나는 매개 변수, variables, binding/declaring 및 constants에 Oracle 설명서를 통해 찾고 조금 연구를 시도했지만 내 연구는 나에게 더 많은 질문 주신 : 읽은 후
- 을 변수에, 내가 지금 사용하고있는 올바른 용어인지 질문한다 (실제로 변수 명령을 사용하지 않았고 날짜를 전달하고 있기 때문에 허용되는 데이터 유형이 아님). 내
DATE_IN DATE :=
문이 변수가 아니면 무엇입니까? DATE_IN
에 대한 내 참조가 컴파일러에 의해 인식되었지만 값을 함수에 전달하는 것이 범위를 벗어난 이유는 무엇입니까?- 정확히 여기서 콜론 (:)이 무엇입니까? 이것이 바인드 변수로 바뀌 었습니까?
미리 감사드립니다. 당신이 제공 할 수있는 모든 지침에 감사드립니다!
---------------------------------- EDIT ---------- ----------------------------
추가 정보를 제공하도록 요청 받았습니다. 내 DB 버전은 11G, 11.2.0.2.0입니다. 이 오류를 재현 할 수 있었던 쿼리는 다음과 같습니다.
DECLARE
EXTRACT_DT_IN DATE := TO_DATE('16-JUL-2014','DD-MON-RR');
BEGIN
--This begins the pre-optimized query that I'm testing
insert into AELI_COV_TMP_2_OPT
SELECT /*+ ordered use_nl(CM MAMT) INDEX (CM CSMB_CSMB2_UK) INDEX (MAMT (MBAM_CSMB_FK_I) */
CM.CASE_MBR_KEY
,CM.pyrl_no
,MAMT.AMT
,MAMT.FREQ_CD
,MAMT.HOURS
,aeli$cov_pdtodt(CM.CASE_MBR_KEY, EXTRACT_DT_IN)
FROM
CASE_MEMBERS CM
,MEMBER_AMOUNTS MAMT
WHERE EXISTS (select /*+ INDEX(SDEF SLRY_BCAT_FK_I) */
'x'
from SALARY_DEF SDEF
where SDEF.CASE_KEY = CM.CASE_KEY
AND SDEF.TYP_CD = '04'
AND SDEF.SLRY_KEY = MAMT.SLRY_KEY)
AND CM.CASE_MBR_KEY = MAMT.CASE_MBR_KEY
AND MAMT.STAT_CD = '00'
AND (MAMT.xpir_dt is null or MAMT.xpir_dt > EXTRACT_DT_IN)
AND MAMT.eff_dt <= EXTRACT_DT_IN;
--This ends the pre-optimized query that I'm testing
END;
다음은이 명령문에서 Explain Plan을 실행하려고 할 때 발생하는 오류입니다. 내가 라인 13에 대한 참조를 제거하거나 해당 라인의 EXTRACT_DT_IN
에 콜론 (:)을 추가하면이 오류를 지나칠 수 있습니다.
---------------------- 수정 2 ---------------- ---
다음은 aeli $ .cov_pdtodt의 함수 서명입니다. (보안상의 이유로 소유자를 교체했습니다).
끝에 삽입 할 때 세미콜론이 있다고 가정하면 작업해야합니다. ': date_in'에 대한 참조를 만들지 않았다면 오류 (또는 프롬프트)가 표시됩니다. 변수와 함께. 11gR2에서 잘 작동하는 것 같습니다. 어떤 버전을 사용하고 있으며 어떤 클라이언트 (및 버전)를 사용하고 있습니까? 하위 블록이나 반복되는 이름이 없으므로 왜 범위 문제라고 생각하는지 확신 할 수 없습니다. –
OP의 최소 예가 문제를 설명하지 못하는 것 같습니다. [최소한의 완전하고 검증 가능한 예제를 만드는 방법] (http://stackoverflow.com/help/mcve)를 참조하십시오. – user272735
10.2.0.5 (SQL * Plus), [11.2.0.2 (SQL Fiddle)] (http://sqlfiddle.com/#!4/711af0/1) 또는 11.2.0.3 (SQL * Plus)에서이 동작을 다시 만들 수 없습니다. SQL 개발자). 당신이 말하는 것은 실제로 이해가되지 않습니다. 재현 가능한 예제를 만들 수 없다면 우리가 설명하려고하는 것이 무엇인지 분명하지 않습니다 –