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.
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')
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]
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
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');
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é.)
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'
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
À 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.
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'
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
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.
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:
ps: 20gb n’est pas énorme, même en 2015. Mais tout est relatif.
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\%'
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
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.