【问题标题】:Sql SMO: How to get path of database physical file name?Sql SMO:如何获取数据库物理文件名的路径?
【发布时间】:2009-01-23 20:59:59
【问题描述】:

我正在尝试返回数据库的 mdf/ldf 文件的物理文件路径。

我已尝试使用以下代码:

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

string filePath = database.PrimaryFilePath;

但是,这会引发异常“'database.PrimaryFilePath' 引发了类型为 'Microsoft.SqlServer.Management.Smo.PropertyNotSetException' 的异常 - 即使我运行它的数据库存在,并且它的 mdf 文件位于c:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL

我做错了什么?

【问题讨论】:

    标签: sql-server smo


    【解决方案1】:

    通常问题在于 DefaultFile 属性为空。默认数据文件是数据文件存储在 SQL Server 实例上的位置,除非在 FileName 属性中另有指定。如果没有指定其他默认位置,该属性将返回一个空字符串。

    因此,如果您未设置默认位置,则此属性不会返回任何内容(空字符串)。

    一种解决方法是检查 DefaultFile 属性,如果它返回一个空字符串,则使用 SMO 获取主数据库,然后使用 Database.PrimaryFilePath 属性检索默认数据文件位置(因为它没有更改)

    既然你说问题出在你的 PrimaryFilePath 上:

    • 确认您的连接已打开
    • 确认其他属性可用

    【讨论】:

      【解决方案2】:

      我就是这样做的,为多个文件名做好准备。访问 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;
      }
      

      【讨论】:

        【解决方案3】:

        服务器 srv = 新服务器(连接); DatabaseCollection dbc = svr.Databases; 数据库数据库 = dbc["dbName"]; 字符串文件路径 = 数据库.PrimaryFilePath;

        【讨论】:

          【解决方案4】:

          我认为最简单的方法是在您的 sql server 实例上运行 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;

          如果您将使用此 sn-p,请确保创建一个 DatabaseInfo 类,该类将存储从 Sql 服务器实例返回的信息。

          【讨论】:

            【解决方案5】:
            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;
            }
            

            【讨论】:

              猜你喜欢
              • 2012-06-04
              • 1970-01-01
              • 2011-11-22
              • 1970-01-01
              • 1970-01-01
              • 2011-09-20
              • 2012-04-14
              • 2019-05-04
              • 1970-01-01
              相关资源
              最近更新 更多