2010-04-05 4 views
3

이 질문은 StackOverflow에서 발견 된 몇 가지 다른 질문과 비슷하지만 새로운 질문을하기에 충분할만큼 중요한 차이점이 있으므로 여기에오라클의 동적 SQL에서 결과를 얻는 중

Oracle의 동적 SQL에서 결과 집합을 가져 와서 동적 SQL 문을 직접 실행 한 것처럼 결과 집합을 SqlDeveloper와 같은 도구로 표시하려고합니다.

EXEC sp_executesql N'select * from countries' 

이상 제대로 :

DECLARE @stmt nvarchar(100) 
SET @stmt = N'select * from countries' 
EXEC sp_executesql @stmt 
이 너무 구체적으로, SQL Server의 간단, 여기에 SQL Server 관리 Studio 또는 쿼리 Explorer에서 결과 집합을 반환하는 SQL Server의 예입니다

질문 "How to return a resultset/cursor from a Oracle PL/SQL anonymous block that executes Dynamic SQL?"은 동적 SQL을 커서로 실행하여 문제의 첫 번째 문제를 해결합니다. 질문 "How to make Oracle procedure return result sets"도 비슷한 대답을 제공합니다. 웹 검색은 똑같은 주제의 많은 변형을 보여주었습니다. 모두 내 질문의 첫 번째 부분 만 다루었습니다. SqlDeveloper에서 수행하는 방법을 설명하는 this post이 발견되었지만 SqlDeveloper의 기능 중 일부를 사용합니다. 실제로 SQL 코드에 자체 포함 된 솔루션을 필요로하는 사용자 지정 쿼리 도구를 사용하고 있습니다. 이 사용자 지정 쿼리 도구는 비슷하게 print (dbms_output.put_line) 문 출력을 표시하는 기능이 없습니다. 결과 세트 만 표시합니다. 여기에 '012 즉시 실행 ... 대량 수집'을 사용하는 one more possible avenue이지만이 예제는 결과를 dbms_output.put_line 문의 루프로 다시 렌더링합니다. This link은 주제를 다루려고 시도하지만 그 질문은 결코 거기에 대답하지 못했습니다.

이것이 가능하다고 가정하면 하나 이상의 조건을 추가 할 것입니다. 제한된 DB 권한으로 인해 함수 또는 프로 시저를 정의하지 않고이 작업을 수행하고 싶습니다. 즉, 동적 SQL을 포함하는 자체 포함 된 PL/SQL 블록을 실행하고 SqlDeveloper 또는 이와 유사한 도구에서 결과 집합을 반환하고자합니다.


그래서 요약 :

  • 내가 임의의 SQL 문 (따라서 동적 SQL)를 실행합니다.
  • 플랫폼은 Oracle입니다.
  • 솔루션은 프로 시저 또는 기능이없는 PL/SQL 블록이어야합니다.
  • 결과는 표준 결과 집합으로 생성되어야합니다. 인쇄 문이 없습니다.
  • SqlDeveloper 특수 기능을 사용하지 않고 출력을 SqlDeveloper에서 결과 집합으로 렌더링해야합니다.

의견이 있으십니까?

답변

0

미확인 구조의 결과 집합을 반환하는 임의의 쿼리를 취하는 PL/SQL 코드를 요청하는 것처럼 보입니다. 어떤 식 으로든 결과 집합이 쉽게 포워딩 될 수 있습니다. "사용자 정의 GUI 도구".

그렇다면 DBMS_SQL에서 동적 SQL을 찾으십시오. 동적 SELECT 문에서 열을 반환하는 DESCRIBE_COLUMNS 프로 시저가 있습니다. 당신이해야하는 단계는

  1. 각 행을 가져 오기
  2. (열 이름과 데이터 유형을) 결과 집합을 설명 문
  3. 구문 분석,하고, 각 열에 대해 것을 반환 할 데이터 유형에 의존 함수를 호출 정의 된 구조로 그 지역 변수 호출 환경으로 복귀하는 로컬 변수
  4. 제자리 값 (아마 [예로서 컬럼 col_1, col_2에는] 예 일관된 열 이름 VARCHAR2 모두)

또는 XMLFOREST 문에 쿼리를 작성하고 XML에서 결과를 구문 분석 할 수 있습니다.


추가 : SQL 서버, 달리는 오라클 PL/SQL 호출 '자연스럽게'하나의 결과 집합을 반환하지 않습니다. 하나 이상의 참조 커서를 열어 클라이언트에 다시 전달할 수 있습니다. 그런 다음 해당 참조 커서에서 레코드 및 열을 가져 오는 클라이언트의 책임이됩니다. 클라이언트가 처리 할 수 ​​없거나 처리 할 수없는 경우 PL/SQL 호출을 사용할 수 없습니다. 저장된 함수는 미리 정의 된 컬렉션 형식을 반환 할 수 있으므로 "select * from table (func_name ('select * from countries'))"과 같은 작업을 수행 할 수 있습니다. 그러나 함수는 DML (업데이트/삭제/삽입/병합)을 수행 할 수 없습니다. 이는 해당 쿼리에 대한 일관성 개념을 없애 버리기 때문입니다.

select * from table(func_name('select * from countries')) 

select * from table(func_name('select * from persons')) 

그것은 그러한위한 DBMS_SQL 또는 XMLFOREST를 이용하여, 가능한 한 열 (컬럼 이름 및 데이터 유형)의 동일한 세트를 반환해야되도록 플러스 반환 구조는 고정되고 함수는 동적 쿼리를 가져 와서 미리 정의 된 열 집합 (col_1, col_2 등)으로 다시 구성하여 일관된 방식으로 반환 할 수 있습니다. 그러나 나는 그것이 무엇의 요점인지 알 수 없다.

+0

게리에게 감사드립니다. DBMS_SQL 또는 XMLFOREST에 익숙하지 않아 두 가지를 모두 읽습니다. 아마 나는 무언가를 놓치고있다. 그러나 나는 어떤 기술이 내가 구하는 것을하지 않는다고 믿는다. DBMS_SQL 제안에 대해서는 2 가지 문제점이 있습니다. 첫째, 목표 명세서에있는 내용에 대한 사전 지식이 필요합니다. 둘째, SQL Server 예제와 같은 단순한 결과 집합으로 연결되지는 않습니다.한 가지 설명 : 예, 맞춤 GUI 도구를 사용하고 있지만 솔루션은 먼저 PL/SQL 코드를 사용하여 SqlDeveloper에서 작동해야하며 두 기법 중 어떤 방식으로 수행 할 수 있는지는 알 수 없습니다. –

0

시도해보십시오.

DECLARE 
    TYPE EmpCurTyp IS REF CURSOR; 
    v_emp_cursor EmpCurTyp; 
    emp_record  employees%ROWTYPE; 
    v_stmt_str  VARCHAR2(200); 
    v_e_job   employees.job%TYPE; 
BEGIN 
    -- Dynamic SQL statement with placeholder: 
    v_stmt_str := 'SELECT * FROM employees WHERE job_id = :j'; 

    -- Open cursor & specify bind argument in USING clause: 
    OPEN v_emp_cursor FOR v_stmt_str USING 'MANAGER'; 

    -- Fetch rows from result set one at a time: 
    LOOP 
    FETCH v_emp_cursor INTO emp_record; 
    EXIT WHEN v_emp_cursor%NOTFOUND; 
    END LOOP; 

    -- Close cursor: 
    CLOSE v_emp_cursor; 
END; 


declare 
    v_rc sys_refcursor; 
begin 
    v_rc := get_dept_emps(10); -- This returns an open cursor 
    dbms_output.put_line('Rows: '||v_rc%ROWCOUNT); 
    close v_rc; 
end; 

여기에서 더 많은 예제를 찾으십시오. http://forums.oracle.com/forums/thread.jspa?threadID=886365&tstart=0

+0

감사합니다. 그러나이 제안 된 솔루션은 요약 (인쇄 문 없음) 및 5 번 항목을 위반합니다.이 두 가지 모두 필자의 결과를보기 위해 사용자 지정 GUI 도구를 사용하기 때문에 필요합니다. 아주 기본적인 SqlDeveloper 응용 프로그램). –

0

TOAD에서 아래 스크립트를 실행하면 v_result 유형을 묻는 메시지가 표시됩니다. 유형 선택 목록의 선택 목록에서 결과가 Toad의 데이터 표에 표시됩니다 (결과와 같은 Excel 스프레드 시트). 즉, 커서로 작업 할 때 항상 두 개의 프로그램 (클라이언트와 서버)을 작성해야합니다. 이 경우 'TOAD'가 클라이언트가됩니다.

DECLARE 
    v_result  sys_refcursor; 
    v_dynamic_sql VARCHAR2 (4000); 
BEGIN 
    v_dynamic_sql := 'SELECT * FROM user_objects where ' || ' 1 = 1'; 

    OPEN :v_result FOR (v_dynamic_sql); 
END; 

오라클 SQL Developer에도 바인딩 메커니즘을 요구하는 메커니즘이있을 수 있습니다.

+0

내 질문에 링크로 표시 한 것과 비슷한 메커니즘이 있지만이 제안은 내 요약 (특수 SqlDeveloper 기능 없음 - 코드 블록을 완전히 자체 포함해야 함)에서 포인트 5를 위반합니다. –

관련 문제