by WebSurfer
2016年3月18日 15:42
サーバー名の代わりに IP アドレスを使って SQL Server に接続に行くと、TCP/IP プロトコルを使って接続に行くようです。
自分の開発マシンには SQL Server 2005 Developer Edition と SQL Server 2008 Express Edition がインストールしてあって、プロトコルは前者が共有メモリのみ有効、後者が共有メモリ、名前つきパイプ、TCP/IP(ポートは 1433)が有効になっています。
そこに、コマンドラインから sqlcmd を使って接続に行くと、(local) の場合は SQL Server 2005 に、IP アドレスの場合は SQL Server 2008 に接続されます。(SELECT @@version; クエリで確認しました)
そして、上の画像で示したとおり、(local) の場合はプロトコルは共有メモリで、IP アドレス(192.168.1.4)の場合は TCP/IP で接続に行きます。
TCP/IP プロトコルを有効にしてあるのは SQL Server 2008 Express のみなので、TCP/IP プロトコルで接続に行く場合、自動的に SQL Server 2008 Express に接続されるということのようです。
知ってました? 実は自分は知らなくて、(local) とかサーバー名を使った場合と同様に SQL Server 2005 Developer Edition に接続に行くと思っていて、半日ぐらいハマってしまいました。(汗)
その他いろいろ新発見があったので、覚えておいたほうがよさそうなことを備忘録として以下に書いておきます。
サーバー名でなく IP アドレスを使った場合、プロトコルを強制的に指定しようとしても、指定できるプロトコルは tcp のみで、np, lpc ではエラーとなって接続できません。実際に試してみたところ、以下の結果となりました。
-
sqlcmd -S tcp:192.168.1.4 -E ⇒ OK
-
sqlcmd -S np:192.168.1.4 -E ⇒ NG
エラーメッセージ:Named Pipes Provider: Could not open a connection to SQL Server [64].
-
sqlcmd -S lpc:192.168.1.4 -E ⇒ NG
エラーメッセージ:SQL Server Network Interfaces: Cannot open a Shared Memory connection to a remote SQL Server instance [87].
sqlcmd -S (local) -E または sqlcmd -S <サーバー名> -E は SQL Server 2005 に共有メモリを使って接続されます。
sqlcmd -S (local)\sqlexpress -E または sqlcmd -S <サーバー名>\sqlexpress -E は SQL Server 2008 Express に共有メモリを使って接続されます。
インスタンス名を追加して sqlcmd -S 192.168.1.4\SQLEXPERESS -E とすると "SQL Server Network Interfaces: Error Locating Server/Instance Specified [xFFFFFFFF]." というエラーとなって接続に失敗します。sqlcmd -S 192.168.1.4\SQLEXPERESS,1433 -E というようにポートを指定すれば接続できます。
その理由は、先の記事 SQLEXPRESS は「名前つきインスタンス」名で書きましたように、インスタンス名を指定した場合、UDP 1434 (SQL Browser サービス) に接続して、指定したインスタンス名のポート番号を取得し、その後対象ポートに接続をするという動作になるからのようです。
MSDN Blog の記事 Troubleshooting Connectivity #1 – SQL Server への接続によると、SQL Server に接続する場合、以下の 3 つのステップにで処理が行われるそうです。この記事の話は「OS レベルのセッション確立」のステップに該当します。
-
OS レベルのセッション確立
-
ログイン認証
-
データベースアクセス
上に紹介した MSDN Blog の記事にはいろいろ参考になることが書いてありますので、一読されることをお勧めします。あと、Troubleshooting Connectivity #5 – セッション確立までの動作という記事も参考になると思います。