Должен ли я использовать связанный с localhost сервер или функцию HOST_NAME(), чтобы избежать жесткого кодирования этого имени сервера SQL Server?

Я унаследовал унаследованную систему, которая имеет два экземпляра SQL Server на одном сервере. Иногда некоторые действия пользователя заставляют некоторые записи "синхронизироваться" по всем экземплярам. Система использует "связанный сервер", поэтому sproc на основном экземпляре может запрашивать другой экземпляр. Таблица sys.servers содержит следующие записи:

| server_id | name | 
=========================== 
| 0 | sql08\main |
| 1 | sql08\other |

Веб-сайт, который вызывает sproc, сохраняет имя связанного сервера в файле конфигурации. Я предполагаю, что они ожидали, что он изменится в какой-то момент, но этого никогда не было. Он всегда находится на том же хосте, что и основной экземпляр.

<appsettings>
 </appsettings>

И это передается sproc для генерации динамического оператора SQL. Я пропущу команду/параметр ADO.NET, все нормально. Sproc делает что-то вроде этого:

DECLARE @sql VARCHAR(MAX) = 'SELECT * FROM [' + @LinkedServer + '].db.schema.table WHERE ...'
EXEC sp_executesql @sql

Я использовал преобразования web.config для поддержки указания конфигурации Debug в тестовую среду и конфигурацию Release для производства. Но мне также нужно, чтобы он работал на любой рабочей станции разработчика, что подразумевает использование localhost, а не фактическое имя хоста.

Вариант A: Добавить специальный связанный сервер

Я могу потребовать специальный связанный сервер, используя localhost вместо имени хоста. Мне не нравится, что он отличается от среды тестирования/производства и требует специальной настройки. Здесь есть какие-то "пропахи"? Я не мог найти никаких указаний так или иначе.

EXEC sp_addlinkedserver 'localhost\other', @srvproduct = 'SQL Server'

Вариант B: сбросьте настройки

Или, учитывая, что связанный сервер всегда находится на одном хосте, я мог бы использовать функцию host_name() в sproc, устраняя необходимость в конфигурации вообще. Есть ли что-то, на что можно обратить внимание, если я использую этот параметр, кроме того, что движется связанный сервер?

DECLARE @sql VARCHAR(MAX) = 'SELECT * FROM [' + HOST_NAME() + '\other].db.schema.table WHERE ...'
EXEC sp_executesql @sql
1 ответ

Я бы предложил использовать SYNONYM на вашем сервере и в производстве. Таким образом, вы можете иметь разные связанные серверы, а остальная часть системы не знает.

В развитие:

CREATE SYNONYM dbo.linkedtable FOR [LOCALHOST\other].db.schema.table;

В производстве:

CREATE SYNONYM dbo.linkedtable FOR [SQL08\other].db.schema.table;

Если у вас их большое количество, создайте дополнительный связанный сервер в обоих местах с одинаковым именем.

Если у вас есть сценарий, который запускается на каждом настроенном вами сервере, вы можете динамически генерировать синоним, например:

DECLARE @sql NVARCHAR(MAX);

SET @sql = N'CREATE SYNONYM dbo.linkedtable FOR ['
 + HOST_NAME() + '\other].db.schema.table;';

EXEC sp_executesql @sql;

licensed under cc by-sa 3.0 with attribution.