오라클 성능 트러블슈팅의 기초 (2012년)
치환변수 0 0 20,363

by 구루비스터디 SQL Plus ACCEPT 치환변수 [2023.09.06]


  1. SQL*Plus를 가장 기본적이면서도 누구나 배워야 할 툴이라고 믿는 이유
  2. 치환변수
    1. :치환변수 기본
    2. :파라미터
    3. :ACCEPT명령
    4. :COLUMN NEW_VALUE 명령
    5. :치환변수를 이용한 조건부 쿼리 구현

질문

오라클 성능 트러블슈팅 에서 가장 기본적인 툴(Tool)은 무엇일까?
필자의 정답은 SQL*Plus 이다.


SQL*Plus를 가장 기본적이면서도 누구나 배워야 할 툴이라고 믿는 이유
  • SQL*Plus가 제공하는 스크립팅 능력은 단순하면서도 강력해서 많은 작업을 자동화 할 수 있으며, 스크립팅 기능을 잘 활용하여 성능 트러블슈팅 과정을 잘할수 있음
  • SQL*Plus는 모든 사용자가 공유할 수 있는 유일한 툴임
    서로 다른 환경에서 작업하는 사용자들끼리 테스트 결과를 서로 주고 받을 때 SQL*Plus에서 실행 가능한 스크립트와 스풀 결과를 이용하는것이 가장 합리적임


성능 트러블슈팅 자료작성시 주의사항

간혹 특정 GUI툴이 출력한 화면의 결과를 캡처해서 테스트 결과를 공개하는 경우가 있는데 좋지 않는 습관임


치환변수

  • 치환변수란 말 그래로 특정 상수 값으로 치환되는 변수를 의미이며, SQL*Plus 에서는 & 문자를 이용해서 치환변수를 사용함
  • SQL*Plus가 제공하는 스크립팅 기능의 핵심은 치환변수(Substitution Variable)를 효과적으로 사용하는 것임


:치환변수 기본

치환변수의 사용법을 설명하는 간단한 예제


-- Note: 다음과 같이 치환변수 &SID 를 선언하고 그 값을 12로 지정함

SQL> define sid = 12

SQL> select sid, event
  2  from   v$session
  3  where  sid = &sid;
  
구   3: where  sid = &sid
신   3: where  sid = 12

       SID EVENT
---------- ----------------------------------------------------------------
        12 SQL*Net message from client


  • 치환 변수의 가장 큰 장점은 너무 단순해서 SQL문내의 어디에서나 제약없이 사용할 수 있다는 것임


SELECT문의 컬럼 리스트를 치환 변수로 정의하는 예제


SQL> define columns = "sid, event, p1";

SQL> select &columns
  2  from   v$session
  3  where  sid = &sid;
  
구   1: select &columns
신   1: select sid, event, p1
구   3: where  sid = &sid
신   3: where  sid = 12

       SID EVENT                                                            P1
---------- ---------------------------------------------------------------- ----------
        12 SQL*Net message from client                                      1111838976


  • 위와 같은 기법을 잘 활용하면 복잡한 PL/SQL 프로그래밍 없이도 동적인 SQL문을 자유롭게 구사할수 있음


:파라미터

  • SQL*Plus를 통해서 파일을 호출할 때 파라미터를 줄 수 있음
  • 만일 세 개의 파라미터를 사용했다면, 첫번째 파라미터는 치환변수 &1을 통해 사용할 수 있음 두번째 파라미터는 치환변수 &2, 세번째 파라미터는 치환변수 &3을 통해 사용함


파라미터의 사용법을 설명하는 간단한 예제


/**
 -- STEP1. 아래와 같이 SESSION.SQL 파일을 정의함
 --        1) 첫번째 파라미터(&1)의 값을 다시 치환변수 &SID 저장함
 --        2) 그리고 그 값을 이용해서 V$SESSION 뷰를 검색함
 **/

SQL> --ed session.sql
SQL> /*
SQL> define sid = &1
SQL>
SQL> select sid, event
SQL> from   v$session
SQL> where  sid = &sid;
SQL> */



-- STEP2. SESSION.SQL 파일을 호출하면서(@ 명령), 12라는 값을 첫번째 파라미터로 사용함

SQL> @session 12



-- STEP3. 아래와 같이 12의 값이 사용되어 원하는 결과를 얻게됨

SQL> define sid = &1
SQL>
SQL> select sid, event
  2  from   v$session
  3  where  sid = &sid;
구   3: where  sid = &sid
신   3: where  sid = 12

       SID EVENT
---------- ----------------------------------------------------------------
        12 SQL*Net message from client


:ACCEPT명령

  • ACCEPT명령은 사용자에게 값을 입력받는 용도로 사용됨
  • ACCEPT명령을 DEFAULT옵션과 함께 사용하면 디폴트 값을 지정할 수 있기 때문에 사용 편의성을 극대화할 수 있음
  • 디폴트 값이 있는 경우에는 값을 입력할 필요가 없이 엔터(Enter) 키를 입력하는 것만으로 값을 지정할 수 있기 때문임


ACCEPT 명령을 설명하는 간단한 예제


/**
 -- STEP1. 아래와 같이 SESSION2.SQL 파일을 정의함
 --        1) ACCEPT SID2 DEFAULT &SID 명령에 의해 치환변수 &SID에 의해 지정된 디폴트 값을 사용할 수 있도록 함
 **/

SQL> /*
SQL> define sid = &1
SQL> accept sid2 number default &sid prompt 'sid to monitor[&sid]: '
SQL>
SQL> select sid, event
SQL> from   v$session
SQL> where  sid = &sid2;
SQL> */



-- STEP2. 그리고 SESSION2.SQL 파일을 호출하면서 12라는 값을 첫번째 파라미터로 사용함

SQL> @session2 12



-- STEP3. 그러면 다음과 같이 디폴트 값이 12로 지정된 상태로 ACCEPT 명령이 수행됨

SQL> define sid = &1
SQL> accept sid2 number default &sid prompt 'sid to monitor[&sid]: '
sid to monitor[12]:
SQL> select sid, event
  2  from   v$session
  3  where  sid = &sid2;
구   3: where  sid = &sid2
신   3: where  sid =         12

       SID EVENT
---------- ----------------------------------------------------------------
        12 SQL*Net message from client


  • ACCEPT명령은 사용자 대화형 스크립트(대화방식으로 동작)를 작성할 때 유용하게 사용할 수 있지만 자동화된 실행이 어려움
  • 그래서 필자는 ACCEPT 명령보다는 파라미터를 직접지정하는 방식을 더 선호함


:COLUMN NEW_VALUE 명령

  • COLUMN 명령을 NEW_VALUE 옵션과 함께 사용하면 SELECT에 의해 얻어진 특정 컬럼의 값을 치환변수로 저장할수 있음


COLUMN NEW_VALUE 명령을 설명하는 간단한 예제


-- STEP1. 아래와 같이 COLUMN 명령을 실행하면 SID라는 컬럼의 결과 값을 SID 라는 치환변수에 저장하라는 의미가됨

SQL> -- "column new_value" command
SQL> col sid new_value sid



-- STEP2. 아래와 같은 쿼리를 수행하면 치환변수 &SID에 135의 값이 저장됨

SQL> select sid from v$session where client_info = 'session1';

       SID
----------
        12



-- STEP3. 저장된 치환변수는 아래와 같이 사용하면 됨
SQL> select sid, event
  2  from   v$session
  3  where  sid = &sid;
구   3: where  sid = &sid
신   3: where  sid =         12

       SID EVENT
---------- ----------------------------------------------------------------
        12 SQL*Net message from client


:치환변수를 이용한 조건부 쿼리 구현

오라클 버전에 따라 동적으로 컬럼을 추가하거나 빼는 기능, 즉 조건부 쿼리를 구현하고자함
  • V$SESSION 뷰에서 SID, EVENT, SQL_ID를 컬럼을 읽음
  • 단, Oracle 11g일 경우에는 SQL_EXEC_START 컬럼을 이용해서 쿼리 소요 시간(Elasped Time)을 구함
  • 보통 이런 요구사항을 접하면 PL/SQL을 이용해 동적인 SQL문을 생성하는 방법을 떠올리지만, SQL*Plus 의 치환변수 기능을 이용하면 어렵지 않게 이런 조건부 쿼리를 생성할수 있음


치환 변수를 이용하여 조건부 쿼리를 구현하는 예제


-- STEP1. 아래와 같이 COLUMN .. NEW_VALUE 명령을 이용해서 치환변수 _IS_11G 와 _IS_10G를 선언함

SQL> -- conditional logic using substitution variable
SQL> col is_11g new_value _IS_11G format a10
SQL> col is_10g new_value _IS_10G format a10



-- STEP2. 그리고 V$VERSION 뷰에서 버전 값을 읽어서 IS_11G 컬럼과 IS_10G 컬럼이 11g이상일 경우 에는 " "과 "--" , 10g 이하일 경우에는 각각 "--" , " "의 값을 지니도록함

SQL> with v as (
  2    select to_number(substr(banner, instr(banner, 'Release ')+8
  3          ,instr(banner, '.') - instr(banner,'Release ')-8)) as version
  4    from   v$version
  5    where  rownum = 1
  6  ) select case when version >= 11 then '' else '--' end as is_11g
  7          ,case when version <= 10 then '' else '--' end as is_10g
  8    from   v;

IS_11G     IS_10G
---------- ----------
           --


/**
 -- STEP3. "--" 값은 SQL*Plus에서는 주석을 나타내는 문자임
 --        따라서 10g 이하일 경우에는 치환변수 _IS_11G 의 값이 "--"이 되어 주석으로 처리되게 할수 있으며, 이 원리를 이용해서 다음과 같이 쿼리를 작성함
 **/

SQL> select sid, event, sql_id &_IS_11G , (sysdate - sql_exec_start)*24*60*60 as elapsed
  2  from   v$session
  3  where  sid = &sid;
구   1: select sid, event, sql_id &_IS_11G , (sysdate - sql_exec_start)*24*60*60 as elapsed
신   1: select sid, event, sql_id  , (sysdate - sql_exec_start)*24*60*60 as elapsed
구   3: where  sid = &sid
신   3: where  sid =         12

       SID EVENT                                                              SQL_ID           ELAPSED
---------- ---------------------------------------------------------------- ------------- ----------
        12 SQL*Net message from client                                      9tz4qu4rj9rdp



-- STEP4. 즉 11g 이상일 경우에만 SQL_EXEC_START 컬럼의 값을 사용하게끔 조건부 쿼리를 구현한것임 



  • 위의 기능을 PL/SQL을 이용해서 구현할 수 있겠지만 SQL*Plus의 치환변수를 잘 이용하는 것이 더 직관적이고 더 사용하기 편함
"데이터베이스 스터디모임" 에서 2012년에 "오라클 성능 트러블슈팅의 기초 " 도서를 스터디하면서 정리한 내용 입니다.

- 강좌 URL : http://www.gurubee.net/lecture/4291

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입