흐르는 시간의 블로그...

바로 직전의 poco library의 링크 문제와 GCC5.x.x와 연관된 부분이다.

poco library를 겨우겨우 컴파일해서 넘어갔는데 이번에는 OCCI에서 문제가 다시 발생했다.


POCO Library link 이슈 - GCC 5.4.0 업버전 후 생긴 문제



이번 개발에서는 오라클과 redis를 사용한다. poco library이후 occi를 위해 두개의 패키지를 인수톨 했다.

기존에 올렸던 글을 참고해도 된다.


instant client 설치하기



설치가 완료되었고 소스에 occi 클래스를 컴파일 했다.

ubiocci.cpp:(.text+0x197e): undefined reference to `oracle::occi::Number::fromText(oracle::occi::Environment const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
ubiocci.o: In function `CUbiOcci::AddParam(unsigned long long)':


뚜둥... 어제와 같은일이 또 발생했다.

대충봐도. std::__cxx11::bast_string<...> 부분이 보인다.

문제를 해결하다가 멈췄던 그 지점으로 다시 돌아가본다.

오늘은 그래도 좀 사용자가 있는 오라클 이슈... 나름 답이 쉽게 나온다.

OCCI linkage error with gcc 5

poco library 문제를 검색했을때도 나왔던 그 문구가 다시 나온다.
-D_GLIBCXX_USE_CXX11_ABI=0


define과 관련된 내용은.. 이리로 넘어간다.

Dual ABI

Application binary interface


다 찾아서 읽어보고 이해하라고 하면 나도 안하기 때문에...

나름 이해한바를 적어보면 아래와 같다.

SW분야에서 Application binary interface는 OS나 library간의 기계어 코드레벨의 인터페이스이다. ABI는 함수가 어떻게 호출되는지 하나의 프로그램 컴포넌트에서 다른 쪽으로 binary format information이 넘어가는지를 혹은 시스템 콜에 어떻게 반응하는지를 걸정한다. ABI는 보통 컴파일러, OS나 라이브러리 제작자 혹은 여러 프로그래밍 언어를 섞어서 다른 언어의 함수를 호출하는 것을 개발하는 개발자의 몫이다. API와 유사하지만 API는 소스 코드 레벨에서 이루어지고 ABI는 프로그램 컴포넌트간의 인터페이스이다.


ABI는 아래와 같은 상세한 것들을 포함한다.(해석하기 뭣해서 걍 위키피디아 붙임)

  • the sizes, layout, and alignment of data types
  • the calling convention, which controls how functions' arguments are passed and return values retrieved; for example, whether all parameters are passed on the stack or some are passed in registers, which registers are used for which function parameters, and whether the first function parameter passed on the stack is pushed first or last onto the stack
  • how an application should make system calls to the operating system and, if the ABI specifies direct system calls rather than procedure calls to system call stubs, the system call numbers
  • and in the case of a complete operating system ABI, the binary format of object files, program libraries and so on


GCC 5.1릴리즈는 std::string과 std::list의 새로운 구현을 포함한 새로운 라이브러리 ABI를 소개했다. C++11의 표준에 따른 작업이었다. 이미 존재하는 라이브러리에 대한 역호환성을 위해 ABI를 선택할 수 있도록 했다. 이것은 링크에서 다른 이름을 가지도록 인라인으로 define함으로써 가능하다. 예를 들어 새버전의 std::lst<int>는 실제로 std::__cxx11:list<int>로 정의한다.


_GLIBCXX_USE_CXX11_ABI 매크로는 라이브러리 헤더의 어떤 ABI를 선택할지 조정할 수 있다. GCC의 기본값은 1로 새로운 ABI를 사용하는 것이다. 기존의 라이브러리를 사용할 것이라면 어떤 라이브러리 헤더를 include 하기전에 매크로를 0으로 해야 한다. -std옵션은 ABI를 선택하지 않는다. 그래서 C++03과 C++11 코드를 함께 링크 할 수 있다.


컴파일시 -Wabi-tag 옵션을 통해 알 수 있다.


위의   OCCI linkage error with gcc 5  에서 나오듯이 일부 라이브러리만 이 옵션을 적용하게 할 방법은 없어 보인다. 모든 라이브러리는 동일한 ABI로 컴파일되어야 함께 동작이 가능하다. 

따라서 occi의 소스가 나에게 없으므로 결국 poco 라이브러리를 4.x.x gcc로 컴파일한 이후 -D_GLIBCXX_USE_CXX11_ABI=0를 통해 개발을 진행할 것이다.


       


테이블 생성을 하는데 인덱스를 사용하여 PK 설정을 하는 과정에서 해당 에러가 발생 했다.

별 내용 없으니 전체 쿼리를 올린다.

CREATE TABLE UBIKHANS.TBL_ECO_FMUINFO
(
    CARNO                NUMBER(8) NOT NULL ,
    REPOTIME             NUMBER(8) NOT NULL ,
    FMU_VERSION          NUMBER(8) NULL 
)
NOLOGGING
NOCOMPRESS 
NOPARALLEL
NOMONITORING;

COMMENT ON TABLE UBIKHANS.TBL_ECO_FMUINFO IS 'FMU2의 버전 정보와 관련 정보를 저장하는 테이블이다';
COMMENT ON COLUMN UBIKHANS.TBL_ECO_FMUINFO.CARNO IS '차량 번호';
COMMENT ON COLUMN UBIKHANS.TBL_ECO_FMUINFO.FMU_VERSION IS 'FMU2의 버전 값';
COMMENT ON COLUMN UBIKHANS.TBL_ECO_FMUINFO.REPOTIME IS '보고 시각';

CREATE UNIQUE INDEX UBIKHANS.ECO_FMUINFO_IDX01 ON UBIKHANS.TBL_ECO_FMUINFO (CARNO ASC, REPOTIME ASC) NOLOGGING;
ALTER TABLE UBIKHANS.TBL_ECO_FMUINFO ADD CONSTRAINT ECO_FMUINFO_PK PRIMARY KEY (CARNO, REPOTIME) USING INDEX UBIKHANS.ECO_FMUINFO_IDX01;
ALTER TABLE UBIKHANS.TBL_ECO_FMUINFO ADD (CONSTRAINT ECO_FMUINFO_FK01 FOREIGN KEY (CARNO) REFERENCES UBIKHANS.TBL_ECO_SERVICE (CARNO) ON DELETE CASCADE);

위에서 강조한 코드에서 (CARNO ASC, REPOTIME ASC)를 사용하지 않고 (CARNO ASC, REPOTIME DESC)를 사용하면 해당 에러를 발생 시킨다.

자세한 것은 좀 더 조사해서 붙여보도록 한다.

아래의 쿼리는 전체 사용 쿼리중 일부이다.

복잡해 보이는 TRUNC 쿼리는 설정한 데이터의 STARTTIME과 ENDTIME의 시각부분만을 사용하기 위해서 진행한 부분이다.


실질적인 복합 쿼리는 그 하단부이다.

DAYOFWEEK 필드에 요일의 값이 비트마스킹 되어 들어 있다. 

7BIT를 사용한다. 

최대값은 127이다.


어제 날짜의 요일값을 구하고 그것을 숫자로 변환한다.

그것을 2의 배수로 제곱하여 DAYOFWEEK 필드와 AND를 진행하면 해당 요일 비트에 설정된 값이라면 BITAND의 결과인 DAYOFWEEKBIT 값이 0이 아니게 되며 만약 설정된 값이 없다면 BITAND결과로 "0"이 발생한다



SELECT CARNO,
                  TRUNC (SYSDATE) + (STARTTIME - TRUNC (STARTTIME)) - 1 AS ST,
                  TRUNC (SYSDATE) + (ENDTIME - TRUNC (ENDTIME)) - 1 AS ET
             FROM (SELECT CARNO,
                          STARTTIME,
                          ENDTIME,
                          BITAND (DAYOFWEEK,POWER (2,TO_NUMBER (TO_CHAR (SYSDATE - 1, 'D')) - 1)) AS DAYOFWEEKBIT
                     FROM UBIKHANS.TBL_OFFDUTY_CONFIG
                    WHERE OVERNIGHT = 1) 

WHERE DAYOFWEEKBIT <> 0



'프로그래밍??? > 오라클' 카테고리의 다른 글

Pro*C에서 Dynamic SQL에서 bind변수 사용하기  (0) 2017.08.24
ORA-14196 발생  (0) 2015.10.22
비트 연산 하기  (0) 2015.05.18
날짜에서 요일 찾기  (0) 2015.05.18
Oracle Sequence value are not ordered  (0) 2015.04.03

오라클에서 비트연산이 필요했다.


이유는 데이터 필터링시 요일을 비트마스크 방식으로 계산하여 적용하기로 한 것이다.

앞의 요일 구하는 식을 가져온 이유도 그 때문이다.

문제는 앞으로도 더 나오겠지만... 일단 비트 연산에 대해서만 적자.


여기저기 검색한 결과 AND만 제공한다


자세한 내용은 아래 출처를 확인한다.

실전 데이터 모델링(비트컬럼으로 컬럼레벨 데이터통합) 기법 및 오라클 비트연산 가이드



오라클은 BITAND() 만을 제공한다.

위의 출처에서는 BITAND를 활용하여 추가적인 함수를 제작하기도 한다.


실질적인 적용 사례는 다음 글에서 거론한다.

...