web-dev-qa-db-fra.com

Comment trouver le répertoire de données pour une instance SQL Server?

Nous avons quelques gigantesques bases de données (20 Go +) qui contiennent principalement des données de recherche statiques. Étant donné que notre application exécute des jointures sur les tables de ces bases de données, celles-ci doivent faire partie de chaque serveur SQL Server local de développeurs (c'est-à-dire qu'elles ne peuvent pas être hébergées sur un serveur de base de données central et partagé). 

Nous prévoyons de copier un ensemble canonique des fichiers de base de données SQL Server (* .mdf et * .ldf) et de les associer à la base de données locale de chaque développeur.

Quel est le meilleur moyen de connaître le répertoire de données de l'instance SQL Server locale afin de pouvoir copier les fichiers au bon endroit? Cela se fera via un processus automatisé, donc je dois pouvoir le trouver et l'utiliser à partir d'un script de construction.

65
Aaron Jensen

Cela dépend si le chemin par défaut est défini pour les fichiers de données et les fichiers journaux ou non.

Si le chemin est défini explicitement sur Properties => Database Settings => Database default locations, le serveur SQL le stocke à Software\Microsoft\MSSQLServer\MSSQLServer dans les valeurs DefaultData et DefaultLog.

Toutefois, si ces paramètres ne sont pas définis explicitement, SQL Server utilise les chemins d'accès aux données et aux journaux de la base de données master.

Ci-dessous est le script qui couvre les deux cas. Il s'agit d'une version simplifiée de la requête exécutée par SQL Management Studio.

De plus, notez que j'utilise xp_instance_regread au lieu de xp_regread, donc ce script fonctionnera pour n'importe quelle instance, par défaut ou nommée.

declare @DefaultData nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultData', @DefaultData output

declare @DefaultLog nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultLog', @DefaultLog output

declare @DefaultBackup nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'BackupDirectory', @DefaultBackup output

declare @MasterData nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg0', @MasterData output
select @MasterData=substring(@MasterData, 3, 255)
select @MasterData=substring(@MasterData, 1, len(@MasterData) - charindex('\', reverse(@MasterData)))

declare @MasterLog nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg2', @MasterLog output
select @MasterLog=substring(@MasterLog, 3, 255)
select @MasterLog=substring(@MasterLog, 1, len(@MasterLog) - charindex('\', reverse(@MasterLog)))

select 
    isnull(@DefaultData, @MasterData) DefaultData, 
    isnull(@DefaultLog, @MasterLog) DefaultLog,
    isnull(@DefaultBackup, @MasterLog) DefaultBackup

Vous pouvez obtenir le même résultat en utilisant SMO. Ci-dessous un exemple en C #, mais vous pouvez utiliser n’importe quel autre langage .NET ou PowerShell.

using (var connection = new SqlConnection("Data Source=.;Integrated Security=SSPI"))
{
    var serverConnection = new ServerConnection(connection);
    var server = new Server(serverConnection);
    var defaultDataPath = string.IsNullOrEmpty(server.Settings.DefaultFile) ? server.MasterDBPath : server.Settings.DefaultFile;
    var defaultLogPath = string.IsNullOrEmpty(server.Settings.DefaultLog) ? server.MasterDBLogPath : server.Settings.DefaultLog;
}

C'est tellement plus simple dans SQL Server 2012 et versions ultérieures, en supposant que vous ayez défini des chemins par défaut (ce qui est probablement toujours une bonne chose à faire):

select 
    InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'),
    InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath')
95
Alex Aza

Bien que ce fil soit très ancien, j’ai le sentiment de devoir apporter une solution simple . Chaque fois que vous savez où se trouve dans Management Studio un paramètre auquel vous souhaitez accéder pour toute sorte de script automatisé, le plus simple Pour cela, vous pouvez exécuter une trace rapide du profileur sur un système de test autonome et capturer ce que Management Studio fait sur le backend.

Dans ce cas, en supposant que vous souhaitiez trouver les données par défaut et les emplacements de journal, vous pouvez procéder comme suit:

SELECTIONNER
SERVERPROPERTY ('instancedefaultdatapath') AS [DefaultFile], 
SERVERPROPERTY ('instancedefaultlogpath') AS [DefaultLog]

33
TDrudge

Je suis tombé sur cette solution dans la documentation de l'instruction Create Database dans l'aide pour SQL Server:

SELECT SUBSTRING(physical_name, 1, CHARINDEX(N'master.mdf', LOWER(physical_name)) - 1)
                  FROM master.sys.master_files
                  WHERE database_id = 1 AND file_id = 1
32
Aaron Jensen

Pour la base de données actuelle, vous pouvez simplement utiliser:

_select physical_name from_ sys.database_files;

pour spécifier une autre base de données, par exemple 'Model', utilisez sys.master_files

select physical_name from sys.master_files where database_id = DB_ID(N'Model');

23
Remus Rusanu

A partir de SQL Server 2012, vous pouvez utiliser la requête suivante:

SELECT SERVERPROPERTY('INSTANCEDEFAULTDATAPATH') as [Default_data_path], SERVERPROPERTY('INSTANCEDEFAULTLOGPATH') as [Default_log_path];

(Extrait d'un commentaire de http://technet.Microsoft.com/en-us/library/ms174396.aspx , et testé.)

15
Nathan

Divers composants de SQL Server (données, journaux, SSAS, SSIS, etc.) ont un répertoire par défaut. Le réglage pour cela peut être trouvé dans le registre. Lire la suite ici:

http://technet.Microsoft.com/en-us/library/ms143547%28SQL.90%29.aspx

Donc, si vous avez créé une base de données en utilisant uniquement CREATE DATABASE MyDatabaseName, elle serait créée selon le chemin spécifié dans l'un des paramètres ci-dessus.

Maintenant, si l’administrateur/installateur a changé le chemin par défaut, le chemin par défaut de l’instance est stocké dans le registre à

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\[INSTANCENAME]\Setup

Si vous connaissez le nom de l'instance, vous pouvez interroger le registre. Cet exemple est spécifique à SQL 2008 - indiquez-moi si vous avez également besoin du chemin d'accès SQL2005.

DECLARE @regvalue varchar(100)

EXEC master.dbo.xp_regread @rootkey='HKEY_LOCAL_MACHINE',
        @key='SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLServer\Setup',
        @value_name='SQLDataRoot',
        @value=@regvalue OUTPUT,
        @output = 'no_output'

SELECT @regvalue as DataAndLogFilePath

Chaque base de données peut être créée en remplaçant le paramètre du serveur dans son propre emplacement lorsque vous émettez l'instruction CREATE DATABASE DBName avec les paramètres appropriés. Vous pouvez le trouver en exécutant sp_helpdb

exec sp_helpdb 'DBName'
8
Raj More

Garder les choses simples:

use master
select DB.name, F.physical_name from sys.databases DB join sys.master_files F on DB.database_id=F.database_id

cela retournera toutes les bases de données avec les fichiers associés

6
Deptor

À partir de l'interface graphique: ouvrez les propriétés de votre serveur, accédez à Paramètres de base de données et consultez Emplacements par défaut de la base de données .

Notez que vous pouvez déposer vos fichiers de base de données où vous voulez, bien qu'il semble plus propre de les conserver dans le répertoire par défaut.

2
Michael Petrotta

Vous pouvez rechercher des emplacements de données et de journaux par défaut pour l'instance SQL Server actuelle à l'aide du T-SQL suivant:

DECLARE @defaultDataLocation nvarchar(4000)
DECLARE @defaultLogLocation nvarchar(4000)

EXEC master.dbo.xp_instance_regread
    N'HKEY_LOCAL_MACHINE',
    N'Software\Microsoft\MSSQLServer\MSSQLServer',
    N'DefaultData', 
    @defaultDataLocation OUTPUT

EXEC master.dbo.xp_instance_regread
    N'HKEY_LOCAL_MACHINE',
    N'Software\Microsoft\MSSQLServer\MSSQLServer',
    N'DefaultLog', 
    @defaultLogLocation OUTPUT

SELECT @defaultDataLocation AS 'Default Data Location',
       @defaultLogLocation AS 'Default Log Location'
1
Regent

En développant la réponse "éclaboussures", voici un script complet qui le fait:

@ECHO off
SETLOCAL ENABLEDELAYEDEXPANSION

SET _baseDirQuery=SELECT SUBSTRING(physical_name, 1, CHARINDEX(N'master.mdf', LOWER(physical_name)) - 1) ^
 FROM master.sys.master_files WHERE database_id = 1 AND file_id = 1;
ECHO.
SQLCMD.EXE -b -E -S localhost -d master -Q "%_baseDirQuery%" -W >data_dir.tmp
IF ERRORLEVEL 1 ECHO Error with automatically determining SQL data directory by querying your server&ECHO using Windows authentication.
CALL :getBaseDir data_dir.tmp _baseDir

IF "%_baseDir:~-1%"=="\" SET "_baseDir=%_baseDir:~0,-1%"
DEL /Q data_dir.tmp
echo DataDir: %_baseDir%

GOTO :END
::---------------------------------------------
:: Functions 
::---------------------------------------------

:simplePrompt 1-question 2-Return-var 3-default-Val
SET input=%~3
IF "%~3" NEQ "" (
  :askAgain
  SET /p "input=%~1 [%~3]:"
  IF "!input!" EQU "" (
    GOTO :askAgain
  ) 
) else (
  SET /p "input=%~1 [null]: "
)   
SET "%~2=%input%"
EXIT /B 0

:getBaseDir fileName var
FOR /F "tokens=*" %%i IN (%~1) DO (
  SET "_line=%%i"
  IF "!_line:~0,2!" == "c:" (
    SET "_baseDir=!_line!"
    EXIT /B 0
  )
)
EXIT /B 1

:END
PAUSE
0
djangofan

j'aurais fait une restauration de sauvegarde simplement parce qu'il est plus facile et supporte le versioning. Les données de référence doivent en particulier être versionnées pour savoir quand elles ont commencé à prendre effet. Un attachement de dettach ne vous donnera pas cette capacité. De plus, avec les sauvegardes, vous pouvez continuer à fournir des copies mises à jour sans devoir arrêter la base de données. 

0
Jayanth Kurup

La réponse d'Alex est la bonne, mais pour la postérité, voici une autre option: créer une nouvelle base de données vide. Si vous utilisez CREATE DATABASE sans spécifier de répertoire cible, vous obtenez ... les répertoires de données/log par défaut. Facile.

Personnellement, je serais probablement soit:

  • RESTAURER la base de données sur le PC du développeur, plutôt que de copier/joindre (les sauvegardes peuvent être compressées, exposées sur un UNC), ou
  • Utilisez un serveur lié pour éviter cela en premier lieu (dépend de la quantité de données acheminée par la jointure)

ps: 20gb n’est pas énorme, même en 2015. Mais tout est relatif.

0
piers7
SELECT DISTINCT dbo.GetDirectoryPath(filename) AS InstanceDataPaths
FROM sys.sysaltfiles WHERE filename like '%.mdf' and filename not like '%\MSSQL\Binn\%'

SELECT DISTINCT dbo.GetDirectoryPath(filename) AS InstanceLogPaths
FROM sys.sysaltfiles WHERE filename like '%.ldf' and filename not like '%\MSSQL\Binn\%'

 enter image description here

Vous pouvez télécharger un script SQL détaillé à partir de comment trouver le répertoire de données d’une instance SQL Server

0
frank tan

Petit nitpick: il n'y a pas de dossier de données, seulement un dossier default data.

Quoi qu'il en soit, pour le trouver, en supposant que vous souhaitiez installer la première instance par défaut:

HKEY_LOCAL_MACHINE\LOGICIEL\Microsoft\Microsoft SQL Server\MSSQL.1\Setup\SQLDataRoot

S'il existe une instance nommée, MSSQL.1 devient quelque chose comme MSSQL10.INSTANCENAME.

0
Stu