본문 바로가기
프로그래밍/delphi

odac, Object-type변수를 이용한 데이터 저장(oracle, procedure, delphi)

by 메르세데쓰 2022. 8. 25.
반응형

안녕하세요? 이번에는 오라클의 Object-type변수를 이용하여 델파이에서 프로시저로의 데이터 처리 방법을 알아보겠습니다.

 

Object-type변수는 정말 편리합니다. 

 

저 같은 경우 oracle-procedure의 parameter 변수의 개수가 많이 필요한 경우 사용하게 되면 정말 유용합니다. 게다가 프로그램 수정으로 인하여 입력값을 늘려주어야 하는 경우라면 프로시저의 입력 파라미터의 수정이 불필요할 수 있어 정말 유용합니다.

 

테스트를 위해 아래와 같이 oracle-type 변수를 선언하였습니다. 200개의 varchar2(4000)의 공간을 같는 변수입니다.

 

하나의 변수명 안에 원하는 형태의 변수를 선언할 수 있습니다. date, varchar , number , clob, blob ..

 

create or replace Type Ty_200_OBJ as Object
(
       -- 200개 오브젝트
       o_D001 VARCHAR2(4000)
      ,o_D002 VARCHAR2(4000)
      ,o_D003 VARCHAR2(4000)
      ,o_D004 VARCHAR2(4000)
      ,o_D005 VARCHAR2(4000)
      ,o_D006 VARCHAR2(4000)
      ,o_D007 VARCHAR2(4000)
      ,o_D008 DATE
      ,o_D009 CLOB
      ,o_D010 NUMBER
      ... (생략) ... 
);

 

 

지난 시간 table-type 할 때 간단한 소스를 준비했는데 그걸 가져다 조금만 수정해서 해보겠습니다.

 

 

데이터 타입을 이렇게 Object로 변경하면 됩니다.

OraStoredProc1.ParamByName('I_Ty_200_OBJ' ).DataType := ftObject;

 

 

 

선언한 object-type변수 내의 객체명과 같은 이름으로 지정하여 값을 대입해 주면 되겠습니다.

 

AttrAsString['o_D001'] := '99999';

 

 

아래는 버튼 클릭 시 풀 소스입니다. 

 

ODAC의 버전에 따라 LOB-TYPE 변수의 데이터 처리가 안될 수 있습니다. 참고해주세요! 테스트가 필요합니다.

 

procedure TForm1.Button4Click(Sender: TObject);
var
    OraSession1: TOraSession;
    OraStoredProc1: TOraStoredProc;

    i : integer;
begin

         try

              OraSession1               := TOraSession.Create(nil);
              OraStoredProc1            := TOraStoredProc.Create(nil);

              OraSession1.ConnectString := '계정/비번@서버:포트/SERVICENAME';
              OraSession1.Options.Direct:= true;
              OraSession1.AutoCommit    := false;  //기본은 true임..

              OraSession1.Pooling       := false;
              OraSession1.Connect;

              OraStoredProc1.Session    := OraSession1;

              OraStoredProc1.StoredProcName := 'pc_test_procedure';
              OraStoredProc1.PrepareSQL;

              OraStoredProc1.ParamByName('I_GBN' ).AsString := 'TEST_INSERT_OBJECT_TYPE';


              //object-type
              OraStoredProc1.ParamByName('I_Ty_200_OBJ' ).DataType := ftObject; //ftTable;
              OraStoredProc1.ParamByName('I_Ty_200_OBJ' ).AsObject.AllocObject(OraStoredProc1.Session.OCISvcCtx, 'Ty_200_OBJ');
              with OraStoredProc1.ParamByName('I_Ty_200_OBJ' ).AsObject do
              begin
                   AttrAsString['o_D001'] := '99999';
                   AttrAsString['o_D002'] := '테스트';
                   AttrAsString['o_D003'] := 'STAT';
                   AttrAsString['o_D004'] := 'GRP';
                   AttrAsString['o_D005'] := '9';
              end;

              OraStoredProc1.Execute;


              showmessage(
                  OraStoredProc1.ParamByName('O_RSLT_MSG_DT').AsString
              );


         finally

              OraSession1.Disconnect;
              OraStoredProc1.Free;
              OraSession1.Free;
         end;

end;

 

 

오라클 프로시저의 관련 오브젝트 타입의 저장과 관련된 부분입니다.

 

하나의 입력 변수 안에 여러 객체를 보관할 수 있다 보니 정말 편리합니다.

 

Procedure pc_test_procedure
 (
      I_GBN     IN VARCHAR2
     
     ,I_Ty_200_OBJ         IN Ty_200_OBJ
    
     ,O_RSLT_MSG_DT        OUT NOCOPY VARCHAR2
 )
 

   AUTHID CURRENT_USER as
    
begin         

   
    if I_GBN = 'TEST_INSERT_OBJECT_TYPE' then           
         begin
                  insert into test1 ( WKPERS,NM,STAT,WK_DTE,GRP,DUTY )
                             values ( I_Ty_200_OBJ.o_D001
                                     ,I_Ty_200_OBJ.o_D002
                                     ,I_Ty_200_OBJ.o_D003
                                     ,sysdate
                                     ,I_Ty_200_OBJ.o_D004
                                     ,I_Ty_200_OBJ.o_D005
                                     );   

              
         exception
              when others then  
                   O_RSLT_MSG_DT := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE || DBMS_UTILITY.FORMAT_ERROR_STACK || ' ' || DBMS_UTILITY.FORMAT_CALL_STACK;  --|| SQLCODE || ' ' ||SQLERRM;
                   rollback;   ---- insrt rollback..  
                   return;     ---- 여기 까지만 실행하고.. 프로시저를 끝내버림...
              
         end;
         
         O_RSLT_MSG_DT := '성공!';
         commit;         
         
                
   end if;

 

준비가 다 되었습니다! 컴파일을 하고 프로그램을 실행시키면 아래처럼 결과를 얻을 수 있습니다.

 

oracle-object-type procedure save

 

에러 처리 시 다음과 같은 결과를 넘겨받으면 oracle-procedure 소스코드의 몇 번째 줄 어디에서 어떠한 문제로 발생했는지를 확인할 수 있어 디버깅 시 큰 도움을 받을 수 있습니다.

 

DBMS_UTILITY.FORMAT_ERROR_BACKTRACE || DBMS_UTILITY.FORMAT_ERROR_STACK || ' ' || DBMS_UTILITY.FORMAT_CALL_STACK;

 

버튼을 한 번 더 누르면 입력값이 같으니 table의 pk에러가 나게 되겠죠? 아래처럼 친절한 안내를 받을 수 있어 운영시 정말 유용합니다!

 

oracle procedure error

 

이상으로 object 타입 변수를 이용한 오라클 프로시저 데이터 처리 방법을 알아봤습니다. 감사합니다!

 

반응형

댓글