2009-01-23 9 views
5

J'essaie de retourner le chemin physique du fichier mdf/ldf d'une base de données.Sql SMO: Comment obtenir le chemin du nom de fichier physique de la base de données?

J'ai essayé en utilisant le code suivant:

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

string filePath = database.PrimaryFilePath; 

Toutefois, ce déclenche une exception « database.PrimaryFilePath» a jeté une exception de type 'Microsoft.SqlServer.Management.Smo.PropertyNotSetException' - même si la base de données que je suis en ce contre existe, et son fichier mdf se trouve dans c: \ Program Files \ Microsoft SQL Server \ MSSQL.1 \ MSSQL

Qu'est-ce que je fais mal

Répondre

5

en général, le problème est avec? la propriété DefaultFile étant null. fichier de données par défaut est où les fichiers de données sont stockés sur l'instance de SQL Server, sauf indication contraire dans la propriété FileName. Si aucun autre emplacement par défaut n'a été spécifié, la propriété renvoie une chaîne vide. Par conséquent, cette propriété ne restaure rien (chaîne vide) si vous n'avez pas défini l'emplacement par défaut.

Une solution de contournement est de vérifier la propriété DefaultFile, si elle retourne une chaîne vide utiliser SMO pour obtenir la base de données maître, puis utiliser la propriété Database.PrimaryFilePath pour récupérer l'emplacement du fichier de données par défaut (car il n'a pas changé)

Puisque vous dites que le problème est avec votre PrimaryFilePath:

  • Vérifiez que votre connexion est ouverte
  • Vérifiez que d'autres propriétés sont disponibles
+0

merci, a travaillé comme un charme! – flayto

0

Serveur srv = nouveau Serveur (connexion); DatabaseCollection dbc = svr.Databases; Base de données de base de données = dbc ["dbName"]; string filePath = database.PrimaryFilePath;

1

Voici comment je le fais, préparé pour plusieurs noms de fichiers. database.LogFiles d'accès pour obtenir la même liste de noms de fichiers journaux:

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; 
} 
0

Je pense que l'approche la plus simple serait d'exécuter le script SQL sur votre instance de serveur SQL qui sera toujours vous renvoyer des données correctes et connectez-vous des chemins de fichiers. La sql suivante fera l'affaire


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 

Vous pouvez toujours exécuter cette sql en utilisant SMO si vous voulez, qui vous renvoie un ensemble de données et vous pouvez extraire ces informations.

 

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; 
 

Si vous utilisez cet extrait alors assurez-vous de créer une classe DatabaseInfo qui stockera les informations renvoyées par instance de serveur Sql.

0
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; 
} 
Questions connexes