2014-10-15 4 views
0

두 개 이상의 오류가 발견되면 나중에 내 저장 프로 시저를 체크하기 위해 별개의 ASN_NO 수를 내 쿼리에서 가져오고 싶습니다.오라클에서 변수로 선택, 오류 ORA-00947 값이 충분하지 않습니다.

커서를 열려고 시도하는 대신 (제대로하지 못하고있는) 커서를 열려고 시도하는 대신 커서를 채우는 동안 임시 테이블을 선택하여 값을 저장하는 것으로 생각할 수 있습니다. 어쩌면 이것은 가능하지 않지만 내 오류는 내게 의미가 없습니다.

여기 내 단순화 된 코드입니다. 정확한 오류 위치를 확인하기 위해 카운트 성명서를 작성했습니다.

V_ASN_COUNT   NUMBER; 

OPEN O_CURSOR FOR 
    WITH O_LIST AS(
    SELECT * 
     FROM AN_ORDER_INFO OI, AN_SHIPMENT_INFO SI 
     -- where bunch of stuff 
), 
    COUNT_ASN_NO AS (
      SELECT COUNT(DISTINCT ASN_NO) AS "ASN_COUNT" 
      FROM O_LIST 
), 
    SAVE_ASN_COUNT AS (
    SELECT ASN_COUNT 
    INTO V_ASN_COUNT 
    FROM COUNT_ASN_NO -- error on this line, not enough values, its just 1:1, i dont get it? 
) 
    SELECT * FROM O_LIST; 

IF(V_ASN_COUNT > 1) THEN 
    RAISE MULTIPLE_ASNS; 
END IF; 

아니면이 잘못 알고 제외하고 아마 난, 나중에 커서를 열고이 같은 것을 할 필요가, 내가 오류 "INTO BULK 기대"얻을 :

OPEN O_CURSOR; 
     LOOP 
      FETCH COUNT(DISTINCT ASN_NO) INTO V_ASN_COUNT; 
      EXIT WHEN ASN_NO%NOTFOUND; 
     END LOOP; 
    CLOSE O_CURSOR; 

답변

1

당신은 할 수 없습니다 커서 문 중간에 into; 그것은 예외를 던지는 것입니다. o_list CTE가 하나의 값만 선택하면이 값은 실행되지만 v_asn_count은 여전히 ​​null이됩니다. o_list에서 여러 열을 선택하면 ORA-00947이 표시됩니다. 아마도 이것은 구문 분석기 버그 일 수 있으며, 아마도 into 절이 있기 때문에 오류가 발생하거나 올바른 CTE 쿼리의 선택 목록을 사용해야합니다.

모든에서 커서를 필요로하고 코드 중복을 줄이기 위해 시도하는 경우에 정말 명확하지 않다, 그러나 당신이 정말하고 싶은 것 같습니다 :

SELECT COUNT(DISTINCT ASN_NO) 
INTO V_ASN_COUNT 
FROM AN_ORDER_INFO OI, AN_SHIPMENT_INFO SI 
-- where bunch of stuff 
; 

IF(V_ASN_COUNT > 1) THEN 
    RAISE MULTIPLE_ASNS; 
END IF; 

(당신은 아마도 조인이 포함 where bunch of stuff 조건은 아니지만 주제는 아니지만 ANSI 조인 구문 사용에 대해 생각하고 싶을 수도 있습니다.

기존 커서가 있고 커서를 실제로 소비했을 때와 이전에 구별 된 값을 계산하려는 경우 커서를 열어서 반복하여 asn_no 값을 검사 한 다음 필요한 경우 예외를 발생시킵니다. 실제 소비를 위해 커서를 닫았다가 다시 엽니 다. 그러나 그것은 여전히 ​​커서 쿼리를 두 번 실행합니다.

아니면 처리, 특히 가져 오는 경우,이를 수용 할 수있는, 기존 커서 쿼리에 분석 카운트를 추가 할 수 있습니다

COUNT(DISTINCT dummy) OVER (PARTITION BY NULL) AS ASN_COUNT 

... 당신에게 독특한 asn_no 값의 수를 가로 질러 줄 것 전체 결과는 해당 결과 세트의 모든 행에 여분의 열로 설정됩니다. 그런 다음 첫 번째 가져 오기 이후에 그 번호를 확인한 다음 다른 것을 수행하고 그 시점에서 예외를 발생시킬 수 있습니다.

이 절차에서 계산해야하지만 커서를 다른 프로 시저/호출자에게 반환해야하는 경우에는 작동하지 않습니다. 호출자는 결과를 확인하고 예외를 발생시켜야합니다. 이는 아마도이 작업을 보는 방법과 다를 수 있습니다.

+0

감사합니다. Alex, 저장 프로 시저에서 커서를 반환합니다. "o_list"는 여러 공급 업체가 동일한 ASN 번호를 보내는 경우에 실행되지 않으면 어떤 결과를 반환합니까? 그 쿼리를 두 번 수행해야합니다. 한 번 계산하려면 한 번, 내 목록을 얻으려면 한 번 수행해야합니다. 따라서 커서를 여는 것이 더 효율적이지만 구문에 문제가 있거나 적절한 리소스 예제를 찾는 것처럼 들립니다. – SomeRandomDeveloper

+1

더 효율적인 것은 아니지만 코드 중복 및 유지 관리가 줄어들고 하나의 쿼리가 변경되고 다른 쿼리가 누락 될 위험이 줄어 듭니다. –

+0

그게 바로 내가 생각하고 있었던거야. 내 현재 커서가 stumblings을 열어 내 질문을 업데이 트했습니다. 지금 당면 진짜 문제 인 것 같습니다. 아마 나는이 질문의 제목을보다 적절하게 바꾸어야한다. – SomeRandomDeveloper