サーバ名を変えた後、SQL Server のメンテナンスプランが実行エラーになる時の対応

# はじめに

クラウド環境でSQL ServerをインストールしたWindowsサーバをコピーして別サーバとして起動した際に、SQL Serverのサーバ名変更をちゃんと実施したにもかかわらずメンテナンスプランが実行エラーになる事象に出くわしてハマってしまったのでその時の作業メモ。
実施環境はSQL Server 2016。

# １．前提作業

## SQL Serverの ServerName の変更
SQL Serverで保持しているServerName を新しいサーバ名に変更

### 確認SQL
```
SELECT @@SERVERNAME AS 'Server Name';
select * from sys.servers;
```
### 設定変更SQL
```
sp_dropserver '旧サーバー名';
GO
sp_addserver '新サーバー名', local;
GO
```

## リモートログインの削除（使っている場合）
```
//既定のインスタンスの場合は、次のプロシージャを実行します。
sp_dropremotelogin old_name;
GO  

//名前付きインスタンスの場合は、次のプロシージャを実行します。
sp_dropremotelogin old_name\instancename;
GO
```

## Reporting Servicesの設定変更（使っている場合）

こちらを参考に実施
https://dev.classmethod.jp/articles/sql-server/


# ２．この状態でメンテナンスプランを実行するとどうなるか

SQL Management Studio からメンテナンスプランを実行したら、下記のエラーにより失敗した。

「The Execute method on the task returned error code 0x80131904 (SQL Server への接続を確立しているときにネットワーク関連またはインスタンス固有のエラーが発生しました。サーバーが見つからないかアクセスできません。インスタンス名が正しいこと、および SQL Server がリモート接続を許可するように構成されていることを確認してください。」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/a2e9e60c-6c76-48d8-3d0c-41d2dabb9cd2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/708d1381-943a-c067-d119-6d227398849c.png)

エラーメッセージはジョブの履歴から参照可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/ce858a1b-049d-9d77-13e2-93ca3521cf47.png)


# ３．メンテナンスプランの実行が失敗する理由

メンテナンスプランの接続定義を見ると古いサーバー名のままになっており、これが原因で実行に失敗している事がわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/05c0c10a-1a17-a92b-acec-c0199be914f9.png)

# ４．対処法

方法は２つある。
　　方法１　SQLを使ってメンテナンスプラン定義のサーバ名を置換
　　方法２　メンテナンスプラン定義をExport→修正→Import

## 方法１　SQLを使ってメンテナンスプラン定義のサーバ名を置換

#### (1) メンテナンスプランのIDを確認

```
use msdb
go

SELECT  x.*,
        LocalServerConnectionString = cm.value('declare namespace DTS="www.microsoft.com/SqlServer/Dts";DTS:ObjectData[1]/DTS:ConnectionManager[1]/@DTS:ConnectionString', 'varchar(1000)')
FROM (
    SELECT  id, name, packageXML = CAST(CAST(packagedata AS VARBINARY(MAX)) AS XML)
    FROM dbo.sysssispackages
    WHERE id IN (SELECT id FROM dbo.sysmaintplan_plans)
) x
CROSS APPLY packageXML.nodes('declare namespace DTS="www.microsoft.com/SqlServer/Dts";/DTS:Executable/DTS:ConnectionManagers/DTS:ConnectionManager[@DTS:ObjectName="Local server connection"]') p(cm)
go
```

#### (2) 定義のアップデートの実行

```
use msdb
go

UPDATE dbo.sysssispackages
SET packagedata = CAST(
	CAST(
		REPLACE(
			CAST(CAST(packagedata AS VARBINARY(MAX)) AS VARCHAR(MAX)),'旧サーバー名','新サーバー名'
		) AS XML
	) AS VARBINARY(MAX)
)
WHERE id = '手順１で確認したID';
go
```

## 方法２　メンテナンスプラン定義をExport→修正→Import

#### (1) SQL Server Management Studioで Integration Services に接続

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/75a401c7-3553-69a9-3061-9a841324d460.png)

#### (2) 対象のメンテナンスプランを右クリックしてExport
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/1df67abd-60d1-5141-99c8-a18135cdd8de.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/cbab0077-0a32-0055-ce43-138034ac1525.png)

#### (3) Exportされたファイルをテキストエディタで開きサーバー名を修正

```
  ||
  DTS:CreatorComputerName="旧サーバー名"
  ||
  <DTS:ConnectionManagers>
        <DTS:ConnectionManager
          DTS:ConnectionString="Data Source=旧サーバー名;Integrated Security=True ・・・・・
```

#### (4) Import

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/f5fa5690-04fb-f670-f9be-3091267d905b.png)


# ５．確認

３に記載の手順でメンテナンスプランの実行先サーバ名が変わっている事を確認した上でメンテナンスプランを実行してみる。正常終了すればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/d699d118-5998-0a79-6b57-e86004aacf52.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551087/273f3019-0fb0-0ef8-8b83-a54915ce2dd1.png)

# 参考URL
- [Microsoft Docs | SQL Server のスタンドアロン インスタンスをホストするコンピューターの名前変更](https://docs.microsoft.com/ja-JP/sql/database-engine/install-windows/rename-a-computer-that-hosts-a-stand-alone-instance-of-sql-server?redirectedfrom=MSDN&view=sql-server-ver15)
- [Classmethod | SQL Serverインスタンスでコンピュータの名前変更を行ったらやっておくこと。](https://dev.classmethod.jp/articles/sql-server/)
- [Move SQL Server Maintenance Plan from One Server to Another](https://www.mssqltips.com/sqlservertip/5335/move-sql-server-maintenance-plan-from-one-server-to-another/)
- [serverfault | Renamed a SQL Server, however maintenance plans still have old name](https://serverfault.com/questions/289995/renamed-a-sql-server-however-maintenance-plans-still-have-old-name)