SQL SMO:データベースの物理ファイル名のパスを取得する方法は?

StackOverflow https://stackoverflow.com/questions/474498

  •  19-08-2019
  •  | 
  •  

質問

データベースのmdf / ldfファイルの物理ファイルパスを返そうとしています。

次のコードを使用してみました:

Server srv = new Server(connection);
Database database = new Database(srv, dbName);

string filePath = database.PrimaryFilePath;

ただし、これは例外をスローします<!> quot; 'database.PrimaryFilePath'は、タイプ 'Microsoft.SqlServer.Management.Smo.PropertyNotSetException'の例外をスローしました。ファイルはc:\ Program Files \ Microsoft SQL Server \ MSSQL.1 \ MSSQLにあります

何が間違っているのですか?

役に立ちましたか?

解決

通常、問題はDefaultFileプロパティがnullであることです。デフォルトのデータファイルは、FileNameプロパティで特に指定されていない限り、SQL Serverのインスタンスでデータファイルが保存される場所です。他のデフォルトの場所が指定されていない場合、プロパティは空の文字列を返します。

したがって、デフォルトの場所を設定しなかった場合、このプロパティは何も返しません(空の文字列)。

回避策は、DefaultFileプロパティをチェックすることです。空の文字列が返される場合は、SMOを使用してmasterデータベースを取得し、Database.PrimaryFilePathプロパティを使用して(変更されていないため)デフォルトデータファイルの場所を取得します

PrimaryFilePathに問題があると言うので:

  • 接続が開いていることを確認します
  • 他のプロパティが利用可能であることを確認します

他のヒント

これは、複数のファイル名に対応するための準備方法です。 database.LogFilesにアクセスして、同じログファイル名のリストを取得します。

private static IList<string> _GetAttachedFileNames(Database database)
{
    var fileNames = new List<string>();

    foreach (FileGroup group in database.FileGroups)
        foreach (DataFile file in group.Files)
            fileNames.Add(file.FileName);

    return fileNames;
}

Server srv = new Server(connection); DatabaseCollection dbc = svr.Databases; データベースdatabase = dbc [<!> quot; dbName <!> quot;]; string filePath = database.PrimaryFilePath;

最も簡単なアプローチは、常に正しいデータとログファイルのパスを返すSQLサーバーインスタンスでSQLスクリプトを実行することだと思います。次のSQLがトリックを行います


SELECT
    db.name AS DBName,
    (select mf.Physical_Name FROM sys.master_files mf where mf.type_desc = 'ROWS' and db.database_id = mf.database_id ) as DataFile,
    (select mf.Physical_Name FROM sys.master_files mf where mf.type_desc = 'LOG' and db.database_id = mf.database_id ) as LogFile
FROM sys.databases db
order by DBName

必要であれば、SMOを使用してこのsqlを実行できます。これにより、データセットが返され、その情報を抽出できます。


var result = new List();
            var server = new Server( serverInstanceName );
            var data = server.Databases[ "master" ].ExecuteWithResults(sql);

            foreach ( DataRow row in data.Tables[ 0 ].Rows )
                result.Add( new DatabaseInfo( row[ "DBName" ].ToString(), row[ "DataFile" ].ToString(), row[ "LogFile" ].ToString() ) );

            return result;

このスニペットを使用する場合は、Sqlサーバーインスタンスから返された情報を格納するDatabaseInfoクラスを作成してください。

using Smo = Microsoft.SqlServer.Management.Smo;

public string GetDataBasePath(string strDatabaseName)
{
    ServerConnection srvConn = new ServerConnection();
    srvConn.ConnectionString = "<your connection string goes here>";
    Server srv = new Server(srvConn);

    foreach (Smo.Database db in srv.Databases)
    {
        if (string.Compare(strDatabaseName, db.Name, true) == 0)
        {
            return db.PrimaryFilePath;
        }
    }

    return string.Empty;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top