SqlServerのBackupフォルダのパスをゲットする

SqlServerではバックアップコマンドを実行したときにファイルが作られるデフォルトのフォルダがある。たとえば、SQL Server 2008 では「C:\MSSQL$インスタンス名\MSSQL10_50.インスタンス名\MSSQL\Backup」がそれだ。


バックアップや復元をするソフトを作るときにには、バックアップ先のフォルダのパスを知りたいわけだ。

ほとんど決め打ちなのだから、

  • C:\MSSQL$インスタンス名\MSSQL10_50.インスタンス名\MSSQL\Backup

でいくというのも一つの案ではある。簡単だしいいね。

ただ問題がいくつかあって、SqlServerのバージョンによってパス名が変わってしまうし(上の例はSQL Server 2008のもの)、またBackupフォルダは設定によって変更できる。こうした問題に対応したいなら、少し工夫する必要がある。

まず考えられる方法としては、レジストリに記録されているパスをゲットする方法。

レジストリキーの HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.インスタンス名\MSSQLServer を開くと、BackupDirectory という値があって、そこにBackupフォルダのパスが記録されているのが見つかる。


しかし、この値については、マイクロソフトのサポートサイトには情報が無くて、本当にそうなのかは不明。たぶん、そうだけど、こういうレジストリを探したら見つかったので使う、、、というやり方はもう21世紀なのでそろそろやめたい。ちゃんとサポート情報に書いてある保証された方法でやりたい。



ということで、次の方法は、データベースのフォルダのパスはデータベースに聞けということで、SQLコマンドを使って調べる方法。

select * from sys.database_files

このSQLを実行すると、physical_name 列にデータベースの実態ファイルのパスが得られる。たとえば、以下のような。

C:\MSSQL$インスタンス名\MSSQL10_50.インスタンス名\MSSQL\DATA\データベース名.mdf

ここからDATAフォルダのパスを得て、Backupフォルダはその隣にいるはずということで、Backupフォルダのパスを得ることができる。

            string p = System.IO.Path.GetDirectoryName(info.dataFilePath);
            var bp= System.IO.Directory.GetParent(p).FullName + "\\Backup";

            if (bp == p)
            {
                throw new ApplicationException(string.Format("バックアップフォルダのパスが得られませんでした。"));
            }
            if (!System.IO.Directory.Exists(bp))
            {
                throw new ApplicationException(string.Format("バックアップフォルダが見つかりません: {0}", bp));
            }
            info.backupFolderPath = bp;

上のコードでは、info.dataFilePath がデータファイルのパスで、そこからフォルダのパスを得て、その親フォルダのパスを得て、Backupというテキストを追加している。Backupフォルダを全然違う場所に設定されていたら、悲しいことになりますな。このコードではそこまでは対応していない。



あとは、SQL Server 管理オブジェクト (SMO)を使う方法もあるみたいだけど、これは試していない。SQLServer2005のような古いバージョンでも動くのかな。

とはいえ、SMOを使うのが一番正しい方法のような気がする。上の2つはバッドノウハウだね。



コメント

このブログの人気の投稿

varchar をデータ型 numeric に変換中に、算術オーバーフロー エラーが発生しました。