Oracle과 SQL Server의 공간 처리 차이(서로 다른 DBMS를 연동하는 경우)
이번에는 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에서 쿼리가 실행되었습니다.
결론
이전 실험을 포함하여 요약하면 다음과 같습니다.
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
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
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
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
쿼리 성능을 향상시키기 위해 Oracle Database 링크를 사용하여 Oracle Materialized View를 사용하도록 액세스를 변경하는 경우가 있다고 생각합니다.
그러나 Oracle Materialized View는 단순히 테이블이므로 이를 사용한 액세스는 .
따라서 결과를 변경하면 이전 결과와 다를 수 있습니다.
(실제로 작업을 하면서 이 문제에 부딪혔습니다. 이 글을 쓰게 된 동기이기도 합니다...)
Reference
이 문제에 관하여(Oracle과 SQL Server의 공간 처리 차이(서로 다른 DBMS를 연동하는 경우)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/em8215/the-difference-in-the-handling-of-the-spaces-between-oracle-and-sql-serverin-the-event-of-linking-different-dbms-4l66텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)