ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [펌] pro*c에서 varchar와 char의 사용
    DBMS/Oracle 2008. 4. 11. 14:11
    BULLETIN CATEGORY BULLETIN TOPIC : PRO*C     
    : PRO*C V2.x에서 CHAR와 VARCHAR의 처리방법 

    pro*c v2.x에서 character array와 string 의 처리는 dbms precompile option에 따라 결정된다. 

    1.CHAR HANDLING       

    1)Input인 경우       

    a)character array       

    dbms=v6_char(혹은 v6)인 경우 host variable character array는 반드시 blank-pad가 되어야 하는 대신 null-terminate는 할 필요가 없다. 예를 들어 emp table의 ename column이 char(10)일때     

              char emp_name[10];       
              strcpy(emp_name,"miller");       
              exec sql insert into emp (empno, ename, deptno) values       
                              (1234, :emp_name, 20);        

    으로 하였다면 table에서는 4개의 null byte가 붙어서 <miller\0\0\0\0>로 insert가 된다. 따라서 이 value는        

              select .... where ename='miller';        

    라는 search 조건을 만족시키지 못한다. 위의 character array를 insert 하려면       

              strcpy(emp_name, "miller ", 10)       

    처럼 4개의 blank를 덧붙여야 한다.       

    dbms=v7인 경우는 blank-pad는 자동적으로 되며, table의 char 길이보다 1 byte 길게 잡아서 null-terminate시켜주어야 한다.       

              char emp_name[11];       
              strcpy(emp_name, "miller");       
              exec sql insert into emp (empno, ename, deptno) values       
                              (1234, :emp_name, 20);       

    b)character pointer인 경우       

    pointer는 input data를 가질 수 있을 만큼의 충분한 길이를 미리 buffer에 allocate 시킨 다음 input statement를 처리해야 한다.       

    2)output인 경우       

    a)character array       

              char name1[10];       
              exec sql select ename into :name1       
              from emp;       

    일때 dbms=v6_char ( 혹은 v6 )인 경우는 name1[10]에 10자리에 맞게 출력이 된다. 예를 들면 table에 "miller"가 있다면 "miller####"로 정상적으로 display가 된다. (#은 blank를 의미). dbms=v7이면 마지막에 null-terminate가 되므로 마지막 자리에 null-terminator가 들어간다. 위의 예라면 "miller###\0"가 display된다. 따라서 host variable은 11자리로 정의하는 것이 바람직하다.        

    b)character pointer       

    character data를 출력시 pointer host variable을 사용하면 dbms option은 아무런 영향을 미치지 않는다. 단 null terminator를 위한 1 byte를 더 buffer에 잡아야 한다. 그리고 data를 fetch하기 전에 어떤 값을 입력하여 null-terminate를 시켜 놓는다.       

              char *name1;        
              name1 = (char *) malloc(11);       
              strcpy(name1," ");       
              exec sql select ename into :name1 from emp;       

    수행결과는 "miller####\0"이 name1에 입력된다.       

    2.VARCHAR HANDLING       

    1)input인 경우       

    a)varchar variable       

    blank-pad나 null-terminate를 시킬 필요가 없다. 예를 들어 emp table의 ename column이 varchar2(10)일 때       

              varchar emp_name[10];       
              strcpy(emp_name1.arr, "van horn");       
              emp_name1.len = strlen(emp_name1.arr);        

    이면 자동적으로 8byte만 ORACLE로 보내진다.        

    b)varchar pointer       

    declaration시에 array member와 length member를 위한 충분한 memory를 allocate 시켜야 한다.        

              varchar *emp_name2;       
              emp_name2 = (varchar *) malloc(sizeof(short) + 10);       
              strcpy(emp_name2->arr, "miller");       
              emp_name2->len = strlen(emp_name2->arr);        

    2)output인 경우       

    a)varchar variable       

    varchar variable을 output host variable로 사용할 경우 length member는 자동적으로 setting이 되나 array member에 null-terminate는 되지 않는다. 따라서 printf()나 strlen()같은 function를 사용하기 전에 arr member에 null-terminate를 시켜야 한다.       

              emp_name1.arr[emp_name1.len] = '\0';       
              printf("%s", emp_name1.arr);       

    (이 경우는 host variable의 length가 1byte 더 길어야 한다.)       

    혹은 string을 print하는데 limit를 주기 위해 length member를 사용한다.       

              printf("%.*s", emp_name1.len, emp_name1.arr);       

    (이 경우 host variable length가 table의 column length와 같아도 된다)       

    b)varchar pointer       

    fetch 하기 전에 variable의 maximum length 를 length member에setting해야 한다.       

              emp_name2->len = 10;       
              exec sql select ename into :emp_name2        
                    from emp       
                 where empno=7934;       
              printf("%d characters returned to emp_name2",  
                                emp_name2->len);        
      


    Oracle Korea Customer Support Technical Bulletins
Designed by Tistory.