Oracle과 SQL Server의 공간 처리 차이(서로 다른 DBMS를 연동하는 경우)

12639 단어 oraclesqlserversql
이 글은 의 연속입니다.
이번에는 Oracle과 SQL Server를 연결할 때 공백을 처리하는 실험을 했습니다.

실험


테이블 및 데이터 쿼리



쿼리와 DBMS의 버전은 이전 버전과 동일합니다.

CREATE TABLE CompareTestTable
(
     Seq         NUMBER
    ,ColCHAR     CHAR(10)
    ,ColVARCHAR  VARCHAR2(10)
);

INSERT INTO CompareTestTable VALUES( 1, 'aaa',  'bbb'  );       -- No space
INSERT INTO CompareTestTable VALUES( 2, 'aaa ', 'bbb ' );       -- A space after a string
INSERT INTO CompareTestTable VALUES( 3, ' aaa', ' bbb' );       -- A space before a string
INSERT INTO CompareTestTable VALUES( 4, ' aaa ', ' bbb ' );     -- Spaces after and before a string



CREATE TABLE CompareTestTable
(
     Seq         INT
    ,ColCHAR     CHAR(10)
    ,ColVARCHAR  VARCHAR(10)
)
INSERT INTO CompareTestTable VALUES( 1, 'aaa',  'bbb'  );       -- No space
INSERT INTO CompareTestTable VALUES( 2, 'aaa ', 'bbb ' );       -- A space after a string
INSERT INTO CompareTestTable VALUES( 3, ' aaa', ' bbb' );       -- A space before a string
INSERT INTO CompareTestTable VALUES( 4, ' aaa ', ' bbb ' );     -- Spaces after and before a string


SQL Server => Oracle (SQL 서버의 Link Server를 이용하여 oracle에 있는 테이블에 접근한다.)



Link Server의 이름은 "Oracle"로 생성됩니다.
Oracle의 테이블은 "TEST_USER"스키마에 있습니다.

select * from [ORACLE]..[TEST_USER].[COMPARETESTTABLE] where ColCHAR = 'aaa';       -- Hit SEQ=1,2 records
select * from [ORACLE]..[TEST_USER].[COMPARETESTTABLE] where ColCHAR = 'aaa ';      -- Hit SEQ=1,2 records
select * from [ORACLE]..[TEST_USER].[COMPARETESTTABLE] where ColCHAR = ' aaa';      -- Hit SEQ=3,4 records
select * from [ORACLE]..[TEST_USER].[COMPARETESTTABLE] where ColCHAR = ' aaa ';     -- Hit SEQ=3,4 records

select * from [ORACLE]..[TEST_USER].[COMPARETESTTABLE] where ColVARCHAR = 'bbb';    -- Hit SEQ=1,2 records
select * from [ORACLE]..[TEST_USER].[COMPARETESTTABLE] where ColVARCHAR = 'bbb ';   -- Hit SEQ=1,2 records
select * from [ORACLE]..[TEST_USER].[COMPARETESTTABLE] where ColVARCHAR = ' bbb';   -- Hit SEQ=3,4 records
select * from [ORACLE]..[TEST_USER].[COMPARETESTTABLE] where ColVARCHAR = ' bbb ';  -- Hit SEQ=3,4 records


이 결과는 와 동일합니다.
데이터가 Oracle에서 SQL Server로 검색되면 SQL Server에서 조건이 평가되었음을 나타냅니다.

참고로 Oracle에서 쿼리를 수행하는 SQL Server의 OPENQUERY를 사용하면 .

Oracle => SQL Server (Oracle의 Database Link를 이용하여 SQL Server의 테이블에 접근한다.)



Database Link의 이름은 "SQL_SERVER"로 생성된다.

select * from COMPARETESTTABLE@SQL_SERVER where "ColCHAR" = 'aaa';       -- Hit SEQ=1,2 records
select * from COMPARETESTTABLE@SQL_SERVER where "ColCHAR" = 'aaa ';      -- Hit SEQ=1,2 records
select * from COMPARETESTTABLE@SQL_SERVER where "ColCHAR" = ' aaa';      -- Hit SEQ=3,4 records
select * from COMPARETESTTABLE@SQL_SERVER where "ColCHAR" = ' aaa ';     -- Hit SEQ=3,4 records

select * from COMPARETESTTABLE@SQL_SERVER where "ColVARCHAR" = 'bbb';    -- Hit SEQ=1,2 records
select * from COMPARETESTTABLE@SQL_SERVER where "ColVARCHAR" = 'bbb ';   -- Hit SEQ=1,2 records
select * from COMPARETESTTABLE@SQL_SERVER where "ColVARCHAR" = ' bbb';   -- Hit SEQ=3,4 records
select * from COMPARETESTTABLE@SQL_SERVER where "ColVARCHAR" = ' bbb ';  -- Hit SEQ=3,4 records


이 결과는 예상치 못한 것입니다.
결과는 와 같다고 생각하지만 실제로는 위의 SQL Server 결과와 같습니다.
쿼리가 SQL Server에서 실행되었는지 궁금합니다.

다음 쿼리로 SQL Server에서 실행 쿼리의 이력을 조사했습니다.

SELECT TOP 1000
QS.creation_time,
SUBSTRING(ST.text,(QS.statement_start_offset/2)+1,
((CASE QS.statement_end_offset WHEN -1 THEN DATALENGTH(st.text)
ELSE QS.statement_end_offset END - QS.statement_start_offset)/2) + 1
) AS statement_text,
ST.text,
QS.total_worker_time,
QS.last_worker_time,
QS.max_worker_time,
QS.min_worker_time
FROM
sys.dm_exec_query_stats QS
CROSS APPLY
sys.dm_exec_sql_text(QS.sql_handle) ST
ORDER BY
QS.creation_time DESC


예상대로 SQL Server에서 쿼리가 실행되었습니다.


결론



이전 실험을 포함하여 요약하면 다음과 같습니다.
  • 컬럼 타입이 CHAR인 경우 조회 결과는 동일하지만 VARCHAR인 경우 다른 결과가 발생한다.
  • Link Server를 사용하여 SQL Server에서 Oracle의 테이블로 연결하면 SQL Server의 검색 사양으로 쿼리가 실행됩니다.
  • 데이터베이스 링크를 사용하여 Oracle에서 SQL Server의 테이블로 연결하면 SQL Server의 검색 사양으로 쿼리가 실행됩니다.

  • 쿼리 성능을 향상시키기 위해 Oracle Database 링크를 사용하여 Oracle Materialized View를 사용하도록 액세스를 변경하는 경우가 있다고 생각합니다.
    그러나 Oracle Materialized View는 단순히 테이블이므로 이를 사용한 액세스는 .
    따라서 결과를 변경하면 이전 결과와 다를 수 있습니다.
    (실제로 작업을 하면서 이 문제에 부딪혔습니다. 이 글을 쓰게 된 동기이기도 합니다...)

    좋은 웹페이지 즐겨찾기