레이블이 SGA 튜닝인 게시물을 표시합니다. 모든 게시물 표시
레이블이 SGA 튜닝인 게시물을 표시합니다. 모든 게시물 표시

2013년 10월 23일 수요일

[ORACLE 외부파일 BFILE 강좌]BFILE을 이용하여 이미지를 DB에 저장/저장된 BFILE을 이용하여 새로운 이미지 생성

 [ORACLE 외부파일 BFILE 강좌]BFILE을 이용하여 이미지를 DB에 저장/저장된 BFILE을 이용하여 새로운 이미지 생성



BFILE을 이용하여 이미지를 DB에 저장/저장된 BFILE을 이용하여 새로운 이미지 생성

아래의 두 PL/SQL 프로시저는 OS의 binary file을 DB의 BFILE 컬럼과 연계하여 작업을 하는 예제 입니다.

Load_BFILE_FROM_Image 프로시저

이 프로시저는 디스크 상의 이미지 파일을 BFILE 컬럼에 저장하는 역할을 합니다. 이 프로시저는 SQL문장안에서 BFILENAME 함수를 사용 하여 BFILE 컬럼을 UPDATE 합니다. 여기서 주의 할 점은 이미지가 디스크 상에 존재 할 뿐 DB에는 저장 되지 않는 다는 것을 명심해야 합니다. 즉 BFILE 컬럼은 OS상의 파일에 대한 포인터를 저장 한다고 보면 됩니다.


Write_BFILE_To_File 프로시저

이 프러시저는 그래픽 파일 등을 내용을 기 저장된 BFILE 참조를 이용하여 어떻게 다시 디스크에 쓰는지에 대해 예를 들고 있습니다. 이때 UTL_FILE.PUT_RAW 프로시저를 이용하여 BFILE 컬럼의 포인터를 읽어 하나씩 디스크에 기록 하게 됩니다.

또한 DBMS_LOB.READ 함수를 이용하여 BFILE 참조로부터 낱낱이 읽어 들여 이를PL/SQL RAW 변수에 넣습니다.

아래의 예를 참고 합니다.

1.        테스트를 위한 테이블, 디렉토리를 만듭니다.

SQL> CREATE TABLE test_bfile (
  2        id          NUMBER(15)
  3      , file_name    VARCHAR2(1000)
  4      , image        BFILE
  5      , timestamp    DATE
  6  )
  7  /

테이블이 생성되었습니다.

SQL> CREATE OR REPLACE DIRECTORY
  2      EXAMPLE_LOB_DIR
  3      AS
  4  'd:\LOBs'
  5  /

디렉토리가 생성되었습니다.


2.        Load_BFILE_From_Image 프러시저를 만듭니다.
(d:\LOBs 폴더에 oraclejava_logo.gif 파일을 복사해 둡니다. 파일 이름은 적절히 수정 하시면 됩니다)

CREATE OR REPLACE PROCEDURE Load_BFILE_From_Image
IS
BEGIN
    DBMS_OUTPUT.ENABLE(100000);
    INSERT INTO test_bfile (id, file_name, image, timestamp)
        VALUES (1001, 'oracle9i_logo.gif', null, sysdate);
    UPDATE test_bfile
        SET image = BFILENAME('EXAMPLE_LOB_DIR', 'oraclejava_logo.gif')
        WHERE id = 1001;
END;


3.        Write_BFILE_To_File 프러시저를 만듭니다.


  CREATE OR REPLACE PROCEDURE Write_BFILE_To_File
  IS
    source_pic      BFILE;
    buffer          RAW(32767);
    buffer_size    CONSTANT BINARY_INTEGER := 32767;
    amount          BINARY_INTEGER;
    offset          NUMBER(38);
    file_handle    UTL_FILE.FILE_TYPE;
    directory_name  CONSTANT VARCHAR2(80) := 'EXAMPLE_LOB_DIR';
    image_filename  CONSTANT VARCHAR2(80) := 'oraclejava_logo2.gif';
    dest_pic        BFILE;
  BEGIN
      DBMS_OUTPUT.ENABLE(100000);
      -- -----------------
      -- GET BFILE LOCATOR
      -- -----------------
      SELECT image INTO source_pic
          FROM test_bfile
          WHERE id = 1001;
      -- ---------------------------------------
      -- OPEN ORIGINAL BFILE IMAGE USING LOCATOR
      -- ---------------------------------------
      DBMS_LOB.FILEOPEN(
          file_loc  => source_pic,
          open_mode  => DBMS_LOB.FILE_READONLY);
      -- ---------------------------------
      -- OPEN NEW IMAGE FILE IN WRITE MODE
      -- ---------------------------------
      file_handle := UTL_FILE.FOPEN(
          location    => directory_name,
          filename    => image_filename,
          open_mode    => 'w',
          max_linesize => buffer_size);
      amount := buffer_size;
      offset := 1;
      -- ---------------------------------------------------
      -- READ FROM BFILE IMAGE / WRITE OUT NEW IMAGE TO DISK
      -- ---------------------------------------------------
      WHILE amount >= buffer_size
      LOOP
          DBMS_LOB.READ(
              file_loc  => source_pic,
              amount    => amount,
              offset    => offset,
              buffer    => buffer);
          offset := offset + amount;
          UTL_FILE.PUT_RAW(
              file      => file_handle,
              buffer    => buffer,
              autoflush => false);
      END LOOP;
      UTL_FILE.FCLOSE(file => file_handle);
      DBMS_LOB.FILEOPEN(file_loc => source_pic);
      -- --------------------------------------------
      -- INSERT THE NEW IMAGE FILE AS A SECOND RECORD
      -- --------------------------------------------
      INSERT INTO test_bfile (id, file_name, image, timestamp)
          VALUES (1002, 'oraclejava_logo2.gif', null, sysdate);
      UPDATE test_bfile
          SET image = BFILENAME('EXAMPLE_LOB_DIR', 'oraclejava_logo2.gif' )
          WHERE id = 1002;
      COMMIT;
* END;
  /

프로시저가 생성되었습니다.

4.        SQL*Plus 에서 테스트 합니다.

SQL> set serveroutput on
SQL> exec Load_BFILE_From_Image

PL/SQL 처리가 정상적으로 완료되었습니다.

SQL> exec Write_BFILE_To_File

PL/SQL 처리가 정상적으로 완료되었습니다.

SQL>
SQL>
SQL> SELECT id, DBMS_LOB.GETLENGTH(image) Length FROM test_bfile;

        ID    LENGTH
---------- ----------
      1001        910
      1002        916

참고) 이제 탐색기에서 보면 oraclejava_logo2.gif가 생겨 났음을 확인 할 수 있습니다. 그런데 이 파일은 원래의 oraclejava_logo.gif 보다 사이즈가 조금 큰데 그 이유는 UTL_FILE.PUT_RAW 프러시저에서 CR/LF가 추가 되어서 그러합니다.

오라클자바커뮤니티에서 설립한 개발자교육6년차 오엔제이프로그래밍 실무교육센터(오라클SQL,튜닝,힌트,자바프레임워크,안드로이드,아이폰,닷넷 실무개발강의)  


[기타 다른 강좌는 아래 해당 카테고리를 클릭해주세요]

2013년 8월 8일 목요일

(오라클자바커뮤니티jquery 강좌)jQuery를 통한 키보드 이벤트, keydown, keyup, keypress , ORACLEJAVA CONNUNITY

jQuery를 통한 키보드 이벤트


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  



keydown : 키 눌러질때,   keypress:글자가입력될때
keyup : 키보드가 떨어질 때

<script type="text/javascript">
$(document).ready(function() {
//keydown 이벤트가발생한순간에는글자가입력되어있지않음
//입력한글자수를표시해야하므로keyup 이벤트사용
$("textarea").keyup(function () {
//남은 글자수 구합니다.
var inputLength = $(this).val().length;
var remain = 50 ? inputLength;
//남은 글자수 display
$("h1").html(remain);
//문서객체 색상 변경
if (remain >= 0) {
$("h1").css("color","Blue");
} else {
$("h1").css("color","red")
}
});
});
</script>
<body><div>
<p>지금 내 생각을</p>
<h1>50</h1>
<textarea cols="40" rows="5"></textarea>
</div>
</body>

2013년 8월 6일 화요일

[ORACLE SGA TUNING, 오라클교육,자바교육, 오라클자바]Literal SQL & Bind Variable

Literal SQL Statement와  Bind Variable 


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  




 Literal SQL문을 많이 사용하면 Hard Parsing의 빈도를 높이게 되어 Library Cache내에서 Cache되는 SQL문들이 자주 age out 하게 되므로 주기를 빠르게 하고 Dictionary Cache의 사용율을 높이게 됩니다. 이러한 이유로 OLTP DB환경에서는 Shared SQL문중에서 Literal SQL 문들을 찾아내어 Bind Variable을 이용한 방법을 사용하도록 해야 합니다. 즉 OLTP 환경에서 가급적 Literal SQL Statement의 사용은 줄이라는 이야깁니다.

아래의 내용을 참고 하시구요…

Eg 1: SELECT * FROM emp WHERE ename='CLARK';

 is used by the application instead of SELECT * FROM emp WHERE ename=:bind1;

Eg 2: SELECT sysdate FROM dual;

does not use bind variables but would not be considered as a literal SQL statement for this article as it can be shared.

Eg 3: SELECT version FROM app_version WHERE version>2.0;

If this same statement was used for checking the 'version' throughout the application then the literal value '2.0' is always the same so this statement can be considered sharable.

자 그럼 이젠 Hard Parsing과 Soft Parsing에 대해 정리 해보도록 하겠습니다.

Hard Parse

하드파싱이란 새 SQL문장이 실행 되는 경우엔 Shared Pool에는 없으므로 완전히 전부 새로 파싱을 한다는 의미 입니다. 오라클은 Shared Pool에 새로운 SQL문장을 할당 하며 SQL 문장이 문법은 맞는지등을 검사 하게 됩니다. 이 경우 CPU 사용이 매우 많아 지게 되는거죠, 물론 Latch의 사용도 증가 하게 됩니다.

Soft Parse

소프트 파싱이란 스행하고자 하는 SQL 문장이 이미 Shared Pool에 있어 이미 존재하는 SQL에 관련된 정보를 그대로 이용하는 겁니다.

그럼 Soft Parse가 되기 위해서는 가능 하면 동일한 SQL 문장을 구사해야 하겠죠? (당근이죠^^)

동일한 SQL 문장이란 무엇인지 알아 보도록 하겠습니다. 우선 하드 파싱의 대상에는 어떤 것이 있는지 알아 보기로 하겠습니다.

우선 같은 테이블을 질의 하더라도 사용자 계정이 다른 경우 동일한 SQL 문장으로 간주 되지 않으므로, 또 SQL문장의 공백이 다른 경우, (select * from emp와 select    *    from    emp는 다릅니다.) 음 그리고 Bind Variable을 사용하는 경우 변수명 이나 타입이 다른 경우에도 그렇구요, 동일한 질의라도 SQL문장의 대소문자 역시 다르면 이것 역시 하드 파싱의 대상이므로 삼가 해야 합니다. 마지막으로 SQL문장의 라인이 달라두 역시..
같은 SQL 문장을 한라인에 쓰는 경우와 여러 라인에 나누어 쓰는 것은 다르게 인식 되는 것 입니다.

select substr(sql_text,1,40) "SQL", count(*),
      sum(executions) "총 실행 횟수"
from v$sqlarea
group by substr(sql_text,1,40)
having count(*) > 5
order by 2;

다음의 예문을 잘 이해하도록 하자구요~

SQL> conn / as sysdba
연결되었습니다.

공유 영역을 클리어 합니다.
SQL> alter system flush shared_pool;

시스템이 변경되었습니다.

SQL> conn scott/tiger
연결되었습니다.
SQL> select count(*) from emp;

  COUNT(*)
----------
        14

Emp 테이블의 개수를 얻기 위한걸 한번 수행 했습니다.

그런 다은 v$SQLAREA 뷰에서 확인 해 봅니다.
SQL> conn / as sysdba

SQL> select substr(sql_text,1,40) "SQL", count(*),
  2        sum(executions) "총 실행 횟수"
  3  from v$sqlarea
  4  where sql_text like '%emp%'
  5  group by substr(sql_text,1,40)
  6  having count(*) > 0
  7  order by 2;


 SQL                    COUNT(*)      총 실행 횟수
---------- ----------------------------------
select count(*) from emp        1            1
이하 생략

SQL> conn scott/tiger
연결되었습니다.
SQL> select count(*) from emp;

  COUNT(*)
----------
        14

SQL> select count(*) from emp;

  COUNT(*)
----------
        14

그런 다음 다시 v$SQLAREA에서 확인 하죠^^

SQL> select substr(sql_text,1,40) "SQL", count(*),
  2        sum(executions) "총 실행 횟수"
  3  from v$sqlarea
  4  where sql_text like '%emp%'
  5  group by substr(sql_text,1,40)
  6  having count(*) > 0
  7  order by 2;

SQL
---------------------------------------------------------------------

  SQL                    COUNT(*)  총 실행 횟수
---------- -----------------------------
select count(*) from emp        1            3

자 그럼 이번에는 동일한 SQL 문장인데 공백을 더 넣어서 Hard Parsing이 일어나게 해 볼까요…

SQL> conn scott/tiger
연결되었습니다.
SQL> select count(*) from    emp;

  COUNT(*)
----------
        14

V$sqlarea를 조회해 보죠…

SQL> select substr(sql_text,1,40) "SQL", count(*),
  2        sum(executions) "총 실행 횟수"
  3  from v$sqlarea
  4  where sql_text like '%emp%'
  5  group by substr(sql_text,1,40)
  6  having count(*) > 0
  7  order by 2;

SQL                            COUNT(*)    총 실행 횟수
---------- ---------------------------------------
select count(*) from    emp        1            1
select count(*) from emp              1            3

이해 되시죠… 공백 뿐 아니라 대소문자등도 주의 해야 합니다.