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 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でクエリが実行されました.

対立


前の実験を含めて、要約は次の通りです
  • カラム型の場合、検索クエリの結果は同じですが、VARCHARの場合には異なる結果が発生します.
  • SQL ServerからOracleのテーブルに接続するリンクサーバーを使用すると、クエリはSQL Serverの検索指定として実行されます.
  • SQL ServerのOracleからTableへの接続にデータベースリンクを使用すると、クエリはSQL Serverの検索指定として実行されます.
  • Oracleデータベースのリンクを使用して、Oracleのデータベースを使用してアクセスを変更することがあります.
    しかし、Oracleの実体化されたビューは単にテーブルですので、それに対するアクセスは同じです.
    したがって、結果があなたがそれを変えるならば、前の結果と異なることができます.
    (実際、私はこの問題に取り組んでいました.これらの記事を書いた動機です)