Можете ли вы заставить SQL Server отправить предложение WHERE на связанный сервер? - PullRequest
0 голосов
/ 07 марта 2020

Я пытаюсь определить, есть ли в таблице в моей базе данных SQL Server 2012 какие-либо записи, которых нет в таблице, которая находится в связанной базе данных Oracle 11g.

Я пытался сделать это следующим образом:

select 1 
from my_order_table ord 
where not exists (select 1 
                  from LINK_ORA..[SCHEMA1].[ORDERS] 
                  where doc_id = ord.document_id)
  and document_id = 'N2324JKL3511'

Проблема в том, что он никогда не завершается, потому что таблица ORDERS на связанном сервере имеет около 100 миллионов строк и согласно объяснить план на SQL сервере, он пытается получить всю таблицу ORDERS со связанного сервера, а затем применить предложение WHERE.

Согласно плану объяснения, он рассматривает удаленную таблицу как имеющую приблизительно 10000 строк - я предполагаю, что это какой-то тип по умолчанию, если он не может получить статистику ..?

Даже запустить что-то так просто:

select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511'

приводит к тому, что SQL Сервер не отправляет предложение WHERE, а запрос никогда не завершается.

Я пытался использовать OPENQUERY, однако это не позволит я добавляю doc_id для конкатенации в предложение WHERE строки запроса.

Затем я попытался создать строку выбора FROM OPENQUERY в функции, но я не могу использовать sp_executesql в функции для ее запуска.

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 07 марта 2020

Поскольку у вас есть проблема с чем-то простым, например, select 1 from LINK_ORA..[SCHEMA1].[ORDERS] where doc_id = 'N2324JKL3511', попробуйте создать на удаленном сервере таблицу, которая будет содержать doc_id, на которую вы хотите посмотреть. Таким образом, ваш SELECT будет включать таблицу, которая содержит только 1 строку. Я просто не уверен насчет INSERT, так как пока не могу его проверить. Я предполагаю, что все будет сделано на удаленном сервере.

Так что-то вроде:

CREATE TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id (
doc_id nvarchar(12));

INSERT INTO LINK_ORA..[SCHEMA1].linked_server_doc_id (doc_id)
SELECT doc_id 
FROM LINK_ORA..[SCHEMA1].[ORDERS] WHERE doc_id = 'N2324JKL3511';

select 1 
from my_order_table ord 
where not exists (select 1 
                  from LINK_ORA..[SCHEMA1].[linked_server_doc_id] 
                  where doc_id = ord.document_id)
  and document_id = 'N2324JKL3511';

DROP TABLE LINK_ORA..[SCHEMA1].linked_server_doc_id
0 голосов
/ 07 марта 2020

Я думаю, что это будет логично работать для вас, но это также может занять слишком много времени.

SELECT    sql_ord.*
FROM      my_order_table               sql_ord
LEFT JOIN LINK_ORA..[SCHEMA1].[ORDERS] ora_ord ON sql_ord.document_id = ora_ord.doc_id
WHERE     sql_ord.document_id = 'N2324JKL3511'
          AND ora_ord.doc_id IS NULL
...