2017-10-30 9 views
0

MS SQL (AWS EC2) 테이블에서 Oracle (AWS RDS) 인스턴스로 데이터를 복제해야한다는 요구 사항이 있습니다. 몇몇 실패한 접근법 후에, 나는 Ora 데이터베이스에 연결된 서버를 SQL로 작성하고 트리거 이벤트에 새로운 데이터를 삽입하기로 결정했다. 여태까지는 그런대로 잘됐다. MS SQL에서 Oracle로 링크 된 서버. 열의 유효하지 않은 메타 데이터

지금 나는 다음과 같은 오류

를 [동일] SQL 테이블에서 하나의 Oracle 테이블에 데이터를 삽입하지만, 수신을 시도하고있다 "OLE DB 공급자" "연결된 서버"OraOLEDB.Oracle desora12는 "공급 'CREATE_DATE'열의 메타 데이터가 잘못되었습니다. 데이터 유형이 지원되지 않습니다. '

나는 insert 문에서 CREATE_DATE를 가져 왔지만 동일한 오류가 발생했습니다. 나는 또한 캐스팅하고 CreateDate를 select 문으로 변환하려고 시도했다. 같은 오류.

Oracle의 CREATE_DATE 열 유형은 TIMESTAMP (6)입니다. SQL의 해당 CreateDate 열 유형이 널입니다. DateTime

테이블에 31 개의 열이 있습니다. 여기에 삽입의 요약 버전이 있습니다.

INSERT INTO [desora12]..[DATAENTRY].[TBL_API_ITEM_TYPEID1_LBL_TEST] 
     ([SITE_ID] 
     ,[USER_ID] 
     ,[CREATE_DATE] 
     ,[TRANSFER_DATE] 
     ,[TRANSFER_STATUS]) 
SELECT TOP 1 SiteID, 
     UserID, 
     CreateDate, 
     TransferDate, 
     TransferStatus 
    FROM API.ItemDataTypeID1Label 
     WHERE TransferDate is null 
     AND TransferStatus is null 
     AND ReturnStatus=200 

도움이 필요하십니까?

+0

질문을 편집하고 사용중인 코드를 표시하십시오. –

+0

Oracle 날짜 필드에 MSSql datetime 값을 삽입하십시오. 성공하면 스테이징 테이블에 처음 삽입하고 스테이징 테이블에서 프로덕션 테이블에 쓰십시오. –

답변

1

나는 당신이하고있는 것처럼 "밀기"보다는 항상 데이터를 전송하기 위해 "끌어 당깁니다". Pull은 개발 또는 테스트 데이터베이스를 새로 고칠 때 프로덕션 데이터베이스를 손상시키지 않도록합니다. 데이트에 관한 한, 필자는 Oracle과 SQL Server 사이의 날짜 유형을 고민했습니다. 필자는 필자의 오라클 날짜를 텍스트로 변환하여 (필자가 기억하고 있습니다) SQL Server가 텍스트를 자동으로 날짜로 변환하도록 허용했습니다. 내가 Oracle 문자열을 문자열로 변환하는 아래의 bindvar 호출에서이를 볼 수 있습니다.

오라클에서 가져 오는 경우 DBMS_HS_PASSTHROUGH를 확인하십시오. 데이터베이스 링크를 통해 선택하는 것보다 몇 배 빠릅니다. 한 번에 2 백만 레코드를 가져오고 있습니다. 실행 시간은 4 1/2 시간에서 5 분으로 줄었습니다.

PROCEDURE bindvar (
     p_cursor IN INTEGER 
     , p_pos  IN INTEGER 
     , p_value IN VARCHAR2 
    ) 
    AS 
     l_routine CONSTANT oracleobj_t := 'bindvar'; 
    BEGIN 
     [email protected] (p_cursor, p_pos, p_value); 
    EXCEPTION 
     WHEN OTHERS 
     THEN 
      make_log_error_entry (
       p_routine => l_routine 
       , p_message => cealogging.activity_log_maintenance_pkg.labels (
           'p_cursor' 
           , p_cursor 
           , 'p_pos' 
           , p_pos 
           , 'p_value' 
           , p_value 
          ) 
      ); 
      RAISE; 
    END; 

-- *********************************************************************** 
    -- Fetch Interval Data 
    -- Purpose: 
    -- Retrieve interval data from SQL*Server 
    -- Arguments: 
    -- p_earliestintervaldate - earliest interval date from which data will be fetched 
    -- p_latestintervaldate - latest interval date from which data will be fetched 
    -- p_earliestlogtime  - earliest log date for which data will be fetched 
    -- p_latestlogtime  - latest log date for which data will be fetched 
    -- p_maxrecords - maximum records to fetch from SQL Server 
     -- *********************************************************************** 
    FUNCTION fetch_intervaldata (
     p_earliestintervaldate IN DATE 
     , p_latestintervaldate  IN DATE 
     , p_earliestlogdate  IN DATE 
     , p_latestlogdate   IN DATE 
     , p_meterno    IN VARCHAR2 DEFAULT NULL 
     , p_maxrecords    IN INTEGER DEFAULT NULL 
    ) 
     RETURN PLS_INTEGER 
    AS 
     l_routine CONSTANT oracleobj_t := 'fetch_intervaldata'; 
     l_format CONSTANT oracleobj_t := 'YYYYMMDD HH24:MI:SS'; 

     l_cnt    PLS_INTEGER; 
     l_cursor    INTEGER; 
     l_earliestlogdate DATE := p_earliestlogdate; 
     l_numrows   INTEGER; 
     l_row    intervaldata_load%ROWTYPE; 
     l_ret    PLS_INTEGER := 0; 
     l_sql    VARCHAR2 (200) 
      := ';select * from cea.fetchCisIntervalData( ?, ?, ?, ?, ?) where interval_read is not null'; 
     l_latestlogtimearg DATE; 
    BEGIN 

     close_databaselink (p_link => 'INTERVALDATA.WORLD'); 

     EXECUTE IMMEDIATE 'truncate table intervaldata_load'; 

     -- set l_cnt = 1 to allow the first pass to run 
     -- thereafter it is the number or records returned by the pass that will 
     -- be tested for continuation 
     l_cnt := 1; 

     WHILE l_earliestlogdate <= p_latestlogdate 
      AND l_cnt > 0 
      AND (p_maxrecords IS NULL 
      OR l_ret < p_maxrecords) 
     LOOP 
      make_log_entry (
       p_routine => l_routine 
       , p_message => 'processing starting for ' || TO_CHAR (l_earliestlogdate, c_intervaldateformat) 
      ); 

      l_cursor   := [email protected]; 
      [email protected] (l_cursor, l_sql); 
      bindvar (p_cursor => l_cursor, p_pos => 1, p_value => TO_CHAR (l_earliestlogdate, l_format)); 
      bindvar (
       p_cursor => l_cursor 
       , p_pos => 2 
       , p_value => TO_CHAR (l_earliestlogdate + INTERVAL '6' HOUR - INTERVAL '1' SECOND, l_format) 
      ); 
      bindvar (p_cursor => l_cursor, p_pos => 3, p_value => TO_CHAR (p_earliestintervaldate, l_format)); 
      bindvar (p_cursor => l_cursor, p_pos => 4, p_value => TO_CHAR (p_latestintervaldate, l_format)); 
      bindvar (p_cursor => l_cursor, p_pos => 5, p_value => p_meterno); 
      l_cnt    := 0; 

      LOOP 
       l_numrows := [email protected] (l_cursor); 
       EXIT WHEN l_numrows = 0 
         OR (p_maxrecords IS NOT NULL 
         AND l_ret >= p_maxrecords); 
       [email protected] (l_cursor, 1, l_row.meterno); 
       [email protected] (l_cursor, 2, l_row.interval_start); 
       [email protected] (l_cursor, 3, l_row.endpointid); 
       [email protected] (l_cursor, 4, l_row.logtime); 
       [email protected] (l_cursor, 5, l_row.interval_read); 
       [email protected] (l_cursor, 6, l_row.buy_back); 
       [email protected] (l_cursor, 7, l_row.phase_a); 
       [email protected] (l_cursor, 8, l_row.phase_b); 
       [email protected] (l_cursor, 9, l_row.phase_b); 
       EXIT WHEN l_row.logtime > p_latestlogdate; 

       INSERT INTO intervaldata_load 
       VALUES l_row; 

       l_cnt  := l_cnt + 1; 
       l_ret  := l_ret + 1; 

      END LOOP; 

      [email protected] (l_cursor); 

      make_log_entry (
       p_routine => l_routine 
       , p_message => LPAD (l_cnt, 10) 
          || ' records retrieved for ' 
          || TO_CHAR (l_earliestlogdate, c_intervaldateformat) 
          || ' to ' 
          || TO_CHAR (l_earliestlogdate + INTERVAL '6' HOUR, c_intervaldateformat) 
      ); 

      l_earliestlogdate := l_earliestlogdate + INTERVAL '6' HOUR; 
     END LOOP; 

     RETURN l_ret; 
    EXCEPTION 
     WHEN OTHERS 
     THEN 
      make_log_error_entry (
       p_routine => l_routine 
       , p_message => 'processing ' || TO_CHAR (l_earliestlogdate, l_format) 
      ); 
      [email protected] (l_cursor); 
      RAISE; 
    END fetch_intervaldata;