본문 바로가기

ProC

[pro*c] 오라클DB 에 이미지 넣기 예제

Pro*C에서 DB에 Image 저장하는 방법

--------------------------------------------------------------------------------
SAMPLE : DB에 IMAGE FILE을 저장
Bulletin no : 10111
--------------------------------------------------------------------------------

다음은 image file 을 insert 하는 예제입니다.
참고 하십시오.

* 이미지 화일의 Type에는 여러가지 형태가 있다.
예를 들면 BMP, PCX, TIF, ...

이 중에서도 압축 효율이 높은 File의 형태를 선택하는 것이 좋다.
가령 BMP Type보다는 PCX Format이 거의 1/4 정도로 압축을 해주므로 보다 효율
적이다.

* 일단 PC의 Windows의 PaintBrush 또는 Image 처리하는 Tool로써
이미지 화일을 적절한 형태로 처리하여 File로 만들어서 Unix Server로 올린다.

*image file을 저장하기 위해서는 image file이 저장될 column의 data type이
long raw이어야 한다.

* Long Data를 처리하기 위해서는 file size를 알아야하며,
추후 File의 Size로써 처리해야 하는 일이 있다면, Table에 File의 Size도
저장하는 것이 효율적이다.

* 아래의 프로그램은 Image File을 읽어서 Table에 저장하는 내용이다.

#include

typedef char bitmap[56262];/* file size */
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR username[20];
VARCHAR password[20];
EXEC SQLTYPE bitmap IS LONG RAW(56262) REFERENCE;
bitmapbuffer;
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE sqlca;

void sqlerror(); /* handles unrecoverable errors */
FILE *fp;
main()
{
strcpy(username.arr, "SCOTT");
username.len = strlen(username.arr);
strcpy(password.arr, "TIGER");
password.len = strlen(password.arr);

EXEC SQL WHENEVER SQLERROR DO sqlerror();
EXEC SQL CONNECT :username IDENTIFIED BY :password;
EXEC SQL WHENEVER SQLERROR DO sqlerror();

fp=fopen("xxx.bmp","r");
fread(&buffer, 1, 56262, fp);

EXEC SQL INSERT INTO IMAGE VALUES (20, :buffer);
EXEC SQL COMMIT WORK RELEASE;
}

void sqlerror()
{
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf("\nORACLE error detected:\n");
printf("\n% .70s \n", sqlca.sqlerrm.sqlerrmc);
EXEC SQL ROLLBACK WORK RELEASE;
exit(1);
}

-------------------------------------------------------------------------

Pro*C에서 EXTERNAL LOB (BFILE) 처리 예제 프로그램


EXTERNAL LOB (BFILE) 처리 예제 프로그램
Bulletin no : 11344
--------------------------------------------------------------------------------
BFILE type은 화일시스템에 존재하는 FILE을 가리키는 LOCATOR를 저장하는 데이타
타입이다. 이 LOCATOR는 디렉토리 ALIAS, FILENAME, 기타 상태 정보를 포함하고
있다. BFILE은 Directory를 통해 access될 수 있다.

디렉토리란 시스템 상의 물리적 디렉토리를 논리적으로 매핑한 alias명을 말한다.
이 오브젝트는 시스템 소유로서, 디렉토리를 생성/삭제하기 위해서는 create[drop]
any directory 권한이 있어야 한다. sys로 connect하여 grant를 실행한다.

SQL> grant create any directory to scott;

디렉토리 생성 시는 실제 디렉토리가 있는지 여부는 확인하지 않는다는 점을 주의
해야 한다. 현재 생성된 디렉토리와 관련된 정보는 all_directories,
dba_directories를 조회하면 확인 가능하다.

Bfile은 pointer 형태로 저장하기 때문에, 여러 record에서 동일한 file을 value
로 가질 수 있다. file에 대한 처리는 Read만 가능하고, 디렉토리와 마찬가지로
BFILE 컬럼에 insert 시 oracle process가 read 권한이 있는지 여부는 확인하지
않는다.
이는 insert하는 user가 미리 확인해야 한다. 하나의 세션에서 동시에 열 수 있는
file 개수는 session_max_open_files parameter에 의해 제한받는다.


1) 사전 수행 SQL 문

SQL> connect sys/manager
SQL> grant create any directory to scott;
SQL> connect scott/tiger
SQL> create or replace directory bfile_dir as '/mnt3/rctest80/';
SQL> create table image_file
2(a varchar2(10),
3 b bfile);

SQL> desc blobs
NameNull?Type
------------------------------- -------- ----
ID VARCHAR2(255)
BLOB_COL BLOB


2) 프로그램 예제

#include
#include

charusername[10] ="ejpark";
charpassword[10] ="ejpark";

chari_rep_file_dir[20];
chari_rep_file_name[20];

void sql_error();

main()
{

EXEC SQL WHENEVER SQLERROR DO sql_error("oracle error --");
EXEC SQL CONNECT :usernameIDENTIFIED BY :password;
printf(" DB connected \n");

/* bfile 컬럼을 insert */
EXEC SQL INSERT INTO image_file VALUES
('abc' ,bfilename('BFILE_DIR','a30.bmp') );
printf(" Bfile inserted \n");

EXEC SQL COMMIT ;


EXEC SQL EXECUTE
DECLARE
i_rep_file BFILE;
temp_blobBLOB;
v_rqid NUMBER;
lenNUMBER;
BEGIN
/* bfile 컬럼을 select */
SELECT b INTO i_rep_file FROM image_file WHERE a='abc';

IF i_rep_file is not null THEN
IF DBMS_LOB.fileisopen(i_rep_file) = 1THEN
DBMS_LOB.fileclose(i_rep_file);
END IF;

DBMS_LOB.FILEGETNAME(i_rep_file,:i_rep_file_dir,:i_rep_file_name);
len := DBMS_LOB.GETLENGTH(i_rep_file);

/* 해당 데이타 화일을 읽어 lob table에 insert */
INSERT INTO blobs VALUES ('abc', empty_blob())
RETURNING blob_col INTO temp_blob;
DBMS_LOB.FILEOPEN(i_rep_file, dbms_lob.file_readonly);
DBMS_LOB.LOADFROMFILE(temp_blob,i_rep_file,len);
DBMS_LOB.FILECLOSE(i_rep_file);
END IF;
COMMIT;
END;
END-EXEC;

printf("name %s %s", i_rep_file_dir,i_rep_file_name);

}


void sql_error(msg)
char* msg;
{

char err_msg[130];
int buf_len, msg_len;

EXEC SQL WHENEVER SQLERROR CONTINUE;

printf("\n%s\n",msg);
buf_len = sizeof(err_msg);
sqlglm(err_msg, &buf_len, &msg_len);
printf("%.*s\n", msg_len, err_msg);

EXEC SQL ROLLBACK RELEASE;
exit(1);

}

'ProC' 카테고리의 다른 글

Pro*C의 기초  (0) 2011.10.16
[PRO*C] 멀티 쓰레드 프로그램을 만들어서 돌리구 있씁니다.  (0) 2011.10.16
[ORACLE] pro*c makefile 만들기  (0) 2011.10.16
Make file for Pro*c  (0) 2011.10.16
Pro*c 예제, 내장함수 예제  (0) 2011.10.16