2012-06-22 4 views
2

이것은 바보 같은 문제이지만 주변을 둘러 볼 수는 없습니다. OCI 프로그램에서 문제를 일으키는 쿼리가 있으므로 SQL * Plus에서 수동으로 실행하여 거기에 차이가 있는지 확인하려고합니다. 이 쿼리입니다 :둘 이상의 행이있는 SQL Plus에서 바인드 변수를 사용합니까?

select e.label as doc_name, 
         e.url, 
         i.item_id, 
         'multi' as form_type 
       from cr_items i, cr_extlinks e 
       where i.parent_id = :comment_id 
       and e.extlink_id = i.item_id 
       UNION 
       select null as doc_name, 
         utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
         r.item_id, 
         'single' as form_type 
       from cr_revisions r 
       where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual); 
end; 

내가 값을 3052753로 comment_id를 결합하고 싶었다, 그래서 나는 다음과 같은 한 :이 오류 제공

DECLARE 
    comment_id number := 3052753; 
    BEGIN 
    select e.label , 
          e.url, 
          i.item_id, 
          'multi' 
        from cr_items i, cr_extlinks e 
        where i.parent_id = :comment_id 
        and e.extlink_id = i.item_id 
        UNION 
        select null , 
          utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
          r.item_id, 
          'single' 
        from cr_revisions r 
        where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual); 
    END; 
/

: 이제

ORA-06550: line 4, column 1: 
PLS-00428: an INTO clause is expected in this SELECT statement 

을, 나는이 쿼리를 근본적으로 바꾸고 싶지 않기 때문에 이미 불행하다. 그러나 어쨌든 나는 이것을 위조 해 내고 (INTO와 UNION은 매우 부드럽게 어울리지 않는다.)

DECLARE 
comment_id number := 3052753; 
x_label VARCHAR2(50); 
x_url VARCHAR2(500); 
x_item number; 
x_thing VARCHAR2(50); 
BEGIN 
select label, url, item_id, thing into x_label, x_url, x_item, x_thing from (
select e.label , 
         e.url, 
         i.item_id, 
         'multi' as thing 
       from cr_items i, cr_extlinks e 
       where i.parent_id = :comment_id 
       and e.extlink_id = i.item_id 
       UNION 
       select null , 
         utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
         r.item_id, 
         'single' as thing 
       from cr_revisions r 
       where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual)) ; 
END; 
/

하지만 지금은, 물론 내가 1 개 이상의 행을 반환하는 거니까, 내가

ORA-01422: exact fetch returns more than requested number of rows 

이제 완전히 예측을 얻을, 내가 가서 등 커서를 사용하기 시작하지만, 내 작은 쿼리입니다 수 있습니다 원래의 자아에서 점점 더 왜곡되고 있습니다. 내가 원했던 것은 질의가 comment_id의 값으로 정상적으로 실행되었는지 확인하는 것이 었습니다. 물론, 나는 단지 comment_id를 쿼리에 하드 코드 할 수 있으며, 그것은 잘 동작한다. 그러나 그것은 또한 OCI에서 잘 작동하기 때문에 SQL * PLus에서 OCI 코드에서 볼 수있는 바인드 변수를 사용하여 문제를 재현 할 것입니다. 그러나 SQL * Plus에서이 작업을 수행하는 것이 왜 그렇게 어려운가? 나는 정말 명백한 것을 놓쳤는가?

데이터베이스는 오라클 10.2.0.1.0입니다 - 64 비트가 (Nahant 업데이트 8)

답변

3
글렌의 접근 @를 유사

,하지만 당신은 SQL * 플러스에서 바인드 변수를 선언하고 일반 SQL 쿼리에서 사용할 수 있습니다. 그런 다음

variable comment_id number; 

을 기본적으로 익명 블록 인 exec[ute] 명령으로 설정 : 먼저 var[iable] 명령으로 선언하지

execute :comment_id := 3052753; 

그런 다음 :comment_id 참조하여 원래의 쿼리를 실행하고, 더 BEGIN 또는 END :

select e.label as doc_name, 
         e.url, 
         i.item_id, 
         'multi' as form_type 
       from cr_items i, cr_extlinks e 
       where i.parent_id = :comment_id 
       and e.extlink_id = i.item_id 
       UNION 
       select null as doc_name, 
         utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
         r.item_id, 
         'single' as form_type 
       from cr_revisions r 
       where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual); 

많은 기능상의 차이가 있다고 생각하지 않습니다. 개인적인 취향을 뛰어 넘는 두 가지 접근 방식을 모두 수행하고 SQL Developer (스크립트로 실행)에서 모두 작동합니다. 이미 : 바인드 양식을 사용하는 Pro * C 파일에서 복사 된 SQL을 실행할 때 코드를 수정하지 않아도되므로이 작업이 더 쉽습니다.


덧붙여, 당신은 쓸 수 있습니다 :

where r.revision_id = content_item.get_latest_revision(:comment_id) 
+0

알렉스에게 감사 드려요. 이미이 문제를 시도했지만, 내 자신의 접근 방식과 같은 오류가있었습니다. PLS-00428 :이 SELECT 문에 INTO 절이 있어야합니다. – TrojanName

+1

얻을 수 없습니다. 일반 SQL 블록의 PL/SQL 오류. 당신은 * BEGIN' /'END'없이 질의 *를 돌리고있다. –

+0

니스. 그건 의미가 있습니다. – Glenn

2

레드햇 엔터프라이즈 리눅스 ES 릴리스 4에서 실행보다는 익명의 블록을 생성, 당신은 아마 SQLPLUS에서 환경 변수를 정의하려면 :

DEFINE comment_id = 3052753 

그런 다음 쿼리에서 & comment_id을 참조하십시오.

select e.label as doc_name, 
         e.url, 
         i.item_id, 
         'multi' as form_type 
       from cr_items i, cr_extlinks e 
       where i.parent_id = &comment_id 
       and e.extlink_id = i.item_id 
       UNION 
       select null as doc_name, 
         utl_raw.cast_to_varchar2(DBMS_LOB.SUBSTR(r.content, 2000, 1)) as url, 
         r.item_id, 
         'single' as form_type 
       from cr_revisions r 
       where r.revision_id = (select content_item.get_latest_revision(&comment_id) from dual); 
+0

도현, 나는 이러한 도구이야, 내가 15 년 전에 것을 알고 :로 추가 select없이

where r.revision_id = (select content_item.get_latest_revision(:comment_id) from dual) 

을! 너무 간단해서 각 단계마다 더 깊게 파고 들었습니다. 감사! :-) – TrojanName

+0

그냥 다음과 같이 읽어야합니다 : DEFINE comment_id = 3052753 – TrojanName

+0

고마워, 지금은 수정했다. (위의 익명 블록에서 잘라내어 붙여 넣기). – Glenn

관련 문제