나는 당신이하고있는 것처럼 "밀기"보다는 항상 데이터를 전송하기 위해 "끌어 당깁니다". 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;
질문을 편집하고 사용중인 코드를 표시하십시오. –
Oracle 날짜 필드에 MSSql datetime 값을 삽입하십시오. 성공하면 스테이징 테이블에 처음 삽입하고 스테이징 테이블에서 프로덕션 테이블에 쓰십시오. –