Я пытаюсь использовать функцию связанного сервера в SQL Server (2014) для выполнения кросс-серверного запроса (вычисления) из хранимой процедуры.SQL Server Linked Server Queries w/ANSI_WARNINGS OFF
Хранимая процедура была первоначально разработана для выполнения локального запроса (вычисления) с использованием динамического T-SQL (через sp_executeSQL
). Выражение генерируется нашим приложением и может быть любым арифметическим выражением.
Простой пример (A/B)
запрос реализован как:
(dynamic sql)
SELECT f1.Value/f2.Value
FROM dbo.DimDate d
INNER JOIN
dbo.vAverageData f1 ON f1.ParentID=x and f1.TimeStamp = d.TimeStamp
INNER JOIN
dbo.vAverageData f2 ON f2.ParentID=y f2.TimeStamp = d.TimeStamp
WHERE d.TimeStamp BETWEEN @StartDateTime AND @EndDateTime
Теперь это становится интересным в том, что ни один из расчета выражений проверки для обработки или условий, таких как деление на ноль. Вместо этого, оригинальный разработчик решил выпустить два заявления, прежде чем любой из динамического T-SQL выполняется:
SET ANSI_WARNINGS OFF
SET ARITHABORT OFF
Это хорошо работало в течение многих лет, пока в один прекрасный день кто-то спросил нас, если мы могли бы выполнять перекрестные запросы сервера. Естественно, первым вариантом, который появился у меня в голове, было реализовать (1) соединение связанного сервера между двумя серверами и (2) изменить динамический код генерации T-SQL (в нашем приложении), чтобы префикс каждого объекта с именем связанного сервера и имя базы данных.
В приведенном выше примере будет преобразована в нечто вроде:
(dynamic sql)
SELECT f1.Value/f2.Value
FROM dbo.DimDate d
INNER JOIN
dbo.vAverageData f1 ON f1.ParentID=x and f1.TimeStamp = d.TimeStamp
INNER JOIN
*<LinkedServer>.<RemoteDatabase>*.dbo.vAverageData f2 ON f2.ParentID=y f2.TimeStamp = d.TimeStamp
WHERE d.TimeStamp BETWEEN @StartDateTime AND @EndDateTime
В первый раз, я пытался запустить одну из этих перекрестных запросов сервера, я получил позорные:
«Гетерогенные запросы для этого необходимо установить параметры ANSI_NULLS и ANSI_WARNINGS . Это обеспечивает согласованный запрос семантики . Включите эти параметры, а затем переиздайте свой запрос. "
Очевидно, что проще всего было бы удалить упомянутые выше звонки SET
. Однако в нашем случае они служат цели и предотвращают прерывание запроса/транзакции в случае деления на ноль, переполнения и т. Д.
На этом этапе (без основной перезаписи) предположим, что мы должны иметь эти SET на месте ...
Есть ли что-нибудь, что я могу сделать, чтобы сделать эту работу без удаления вызовов SET? Существуют ли какие-либо настройки на удаленном сервере/базе данных, которые можно установить? Как насчет связанного объекта сервера?
Я не пробовал, но есть свойства базы данных для ANSI Warnings Enabled и т. Д. Будет ли это исправлено, если оно будет установлено последовательно в обеих базах данных? Это плохая/опасная практика?
Оба сервера точно такая же версия SQL Server (2014) и обе базы данных содержат наш код, то есть мы можем изменить все, что угодно.
Можете ли вы попробовать открыть набор строк и посмотреть, работает ли это, я не пробовал, но всего лишь выстрел – TheGameiswar
Отличная идея, но я попытался что-то сделать с помощью INNER JOIN OPENROWSET ('SQLNCLI', 'SERVER = xxx; UID = yyy; PWD = zzz; ',' SELECT * FROM vAverageData WHERE ParentID = a '), но я все еще получаю ту же ошибку. –
Кажется, что заданные параметры должны быть истинными в соответствии с этим, и кажется, что они включены на разных уровнях: https: //technet.microsoft.com/en-us/library/ms175088 (v = sql.105) .aspx – TheGameiswar