Принуждение SQL Remote Query к удаленной фильтрации вместо локальной

У меня есть запрос MS SQL, который извлекает данные с удаленного сервера. Данные, которые я вытаскиваю, должны быть отфильтрованы по дате, которая определяется во время выполнения. Когда я запускаю запрос следующим образом:

SELECT * FROM SERVER.Database.dbo.RemoteView
WHERE EntryDate > '1/1/2009'

затем фильтр применяется удаленно... Однако на самом деле я не хочу использовать «01.01.2009» в качестве даты — я хочу, чтобы дата была предоставлена ​​​​определяемой пользователем функцией, например:

SELECT * FROM SERVER.Database.dbo.RemoteView
WHERE EntryDate > dbo.MyCustomCLRDateFunction()

где функция является пользовательской функцией CLR со скалярным значением, которая возвращает дату и время... (Вы можете спросить, зачем мне это нужно... детали немного сложны, так что просто поверьте мне - я должен сделайте это так.)

Когда я запускаю этот запрос, удаленный запрос НЕ фильтруется удаленно — фильтрация выполняется после извлечения всех данных (400 000 строк против 100 000 строк), и это имеет существенное значение.

Есть ли способ заставить запрос выполнять фильтрацию удаленно?

Спасибо!


person Michael Bray    schedule 12.10.2009    source источник


Ответы (3)


Разве вы не можете просто отправить такой запрос, или функция clr действительно должна вызываться внутри оператора select?

Declare @datetime datetime
Set @datetime = dbo.MyCustomCLRDateFunction()

SELECT * FROM SERVER.Database.dbo.RemoteView
WHERE EntryDate > @datetime
person Gordon Tucker    schedule 12.10.2009
comment
Знаете, что смешно? Это же решение было предложено другим пользователем, но я сказал, что не могу этого сделать, потому что запрос на самом деле динамически создается слоем данных WTF, который выбирает столбцы, которые он хочет видеть, как группировать данные, как сортировать и т. д. ... Я не думал, что смогу использовать этот ответ, потому что все это выполняется как сконструированный запрос. Но, глядя на это подробнее, я думаю, что у меня едва хватает гибкости в том, как это было построено, чтобы заставить это решение работать. При тестировании это, безусловно, работает. - person Michael Bray; 13.10.2009
comment
Итак, я успешно реализовал это в среде разработки... Как я и думал, система WTF обладала достаточной гибкостью, чтобы я мог вставить этот тип кода перед выбором. Урок, извлеченный здесь, заключается в том, что не следует сразу же отбрасывать возможные решения, не подумав. Спасибо! - person Michael Bray; 13.10.2009

Вы также можете создать строку и использовать openquery...

set @sqlString =
 ' select into myTable from openquery
    (remoteServer,
        "SELECT * FROM Database.dbo.RemoteView WHERE EntryDate > %DTSTART"
    )
 '

set @sqlString  = 
    replace(@sqlString, '%DTSTART', 
                        (select cast(dbo.MyCustomCLRDateFunction() as char(8)) 
           )

EXECUTE sp_executesql @stmt=@sqlString
person cindi    schedule 13.10.2009

Вам необходимо правильно оформить свою функцию CLR, чтобы отметьте его как детерминированный, точный и доступ к данным/доступ к системным данным как DataAccessKind.None.

person Remus Rusanu    schedule 12.10.2009
comment
Хм, я думал, что он помечен как детерминированный, но на самом деле это не так... в этом случае он будет возвращать одно и то же значение БОЛЬШИНСТВО времени, но, конечно, не ВСЕ время. Я не уверен, что делают другие... можно уточнить? - person Michael Bray; 13.10.2009
comment
Откуда dbo.MyCustomCLRDateFunction производит возвращаемую дату? Вы просматриваете таблицы? Выход зависит от текущего времени? Если вы не можете пометить вывод как детерминированный, мало шансов обмануть выполнение запроса для удаленной фильтрации. - person Remus Rusanu; 13.10.2009
comment
На самом деле я задаю этот единственный вопрос, но на самом деле у меня есть около 10 различных функций, которые используются по-разному. Некоторые зависят от времени, некоторые нет, но не все из них ВСЕГДА возвращают одно и то же значение для заданного набора аргументов. Те, что есть, я обязательно отмечу как таковые. Кроме того, разве DataAccessKind.None не используется по умолчанию? - person Michael Bray; 13.10.2009