OracleとSQL Server間のスペースの扱いの違い(異なるDBMSをリンクする場合)
この記事は続きです.
今回はOracleとSQL Serverをリンクするときにスペースを処理する実験をしました.
実験
カラム型の場合、検索クエリの結果は同じですが、VARCHARの場合には異なる結果が発生します. SQL ServerからOracleのテーブルに接続するリンクサーバーを使用すると、クエリはSQL Serverの検索指定として実行されます. SQL ServerのOracleからTableへの接続にデータベースリンクを使用すると、クエリはSQL Serverの検索指定として実行されます. Oracleデータベースのリンクを使用して、Oracleのデータベースを使用してアクセスを変更することがあります.
しかし、Oracleの実体化されたビューは単にテーブルですので、それに対するアクセスは同じです.
したがって、結果があなたがそれを変えるならば、前の結果と異なることができます.
(実際、私はこの問題に取り組んでいました.これらの記事を書いた動機です)
今回は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 Serverのリンクサーバを使用すると、Oracleのテーブルがアクセスされます。)
リンクサーバーの名前は“Oracle”として作成されます.
Oracleのテーブルは“TestConeユーザー”スキーマです.
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を使用すると、結果は. NET Frameworkと同じです.
Oracle => SQL Server ( Oracleのデータベースリンクを使用して、SQL Serverのテーブルがアクセスされます)
データベースリンクの名前は"sqlrest 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サーバの結果と同じです.
SQLサーバでクエリが実行されたのでしょうか.
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の実体化されたビューは単にテーブルですので、それに対するアクセスは同じです.
したがって、結果があなたがそれを変えるならば、前の結果と異なることができます.
(実際、私はこの問題に取り組んでいました.これらの記事を書いた動機です)
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