Comment puis-je trouver le répertoire de données pour une instance SQL Server?
-
19-09-2019 - |
Question
Nous avons quelques énorme (bases de données 20GB +) qui contiennent principalement des données de consultation statiques. Parce que nos applications se exécute des tables dans les jointures contre ces bases de données, ils doivent faire partie de chaque développeurs locaux SQL Server (à savoir qu'ils ne peuvent pas être hébergé sur un serveur de base de données centrale, partagée).
Nous prévoyons la copie d'un ensemble canonique des fichiers réels de base de données SQL Server (* .mdf et * .ldf) et les attacher à la base de données locale de chaque développeur.
Quelle est la meilleure façon de découvrir le répertoire de l'instance locale de SQL Server de données afin que nous puissions copier les fichiers au bon endroit? Cela se fera au moyen d'un processus automatisé, donc je dois être en mesure de trouver et de l'utiliser à partir d'un script de compilation.
La solution
Il dépend de chemin par défaut est défini pour les données et les fichiers journaux ou non.
Si le chemin est explicitement défini à Properties
=> Database Settings
=> Database default locations
puis serveur stocke SQL il à Software\Microsoft\MSSQLServer\MSSQLServer
en valeurs DefaultData
et DefaultLog
.
Cependant, si ces paramètres ne sont pas définis explicitement, SQL Server utilise des chemins de données et de journal base de données maître.
Bellow est le script qui couvre les deux cas. Ceci est simplifiée version de la requête qui exécute SQL Management Studio.
En outre, notez que j'utilise xp_instance_regread
au lieu de xp_regread
, donc ce script fonctionne pour toute instance, par défaut ou le nom.
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. Bellow est échantillon C #, mais vous pouvez utiliser une autre langue .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;
}
Il est tellement plus simple dans SQL Server 2012 et au-dessus, en supposant que vous avez des chemins par défaut définis (ce qui est probablement toujours une bonne chose à faire):
select
InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'),
InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath')
Autres conseils
Bien que ce soit un fil très vieux, je sens que je dois apporter une solution simple. Chaque fois que vous savez où dans Management Studio un paramètre est situé que vous souhaitez accéder à toute sorte de script automatisé, le plus simple est d'exécuter une trace profileur rapide sur un système de test autonome et de capturer ce que Management Studio est fait sur le backend .
Dans ce cas, en supposant que vous êtes intéressé à trouver les données par défaut et connectez emplacements que vous pouvez effectuer les opérations suivantes:
SELECT
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:
pour spécifier une autre base de données, par exemple 'Modèle', utilisez sys.master_files
select physical_name from sys.master_files where database_id = DB_ID(N'Model');
Au Sql Server 2012, vous pouvez utiliser la requête suivante:
SELECT SERVERPROPERTY('INSTANCEDEFAULTDATAPATH') as [Default_data_path], SERVERPROPERTY('INSTANCEDEFAULTLOGPATH') as [Default_log_path];
(Ceci a été pris d'un commentaire à 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 de ce qui peut être trouvé dans le Registre. En savoir plus ici:
http://technet.microsoft.com/ fr-fr / bibliothèque / ms143547% 28SQL.90% 29.aspx
Donc, si vous avez créé une base de données en utilisant seulement CREATE DATABASE MyDatabaseName
il serait créé au chemin d'accès spécifié dans l'un des paramètres ci-dessus.
Maintenant, si l'admin / installateur a changé le chemin par défaut, le chemin par défaut pour l'instance est stockée 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 SQL 2008 spécifique -. Laissez-moi savoir si vous avez besoin du chemin SQL2005 et
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 redéfinissant la configuration du serveur dans son propre emplacement lorsque vous émettez l'instruction CREATE DATABASE DBName
avec les paramètres appropriés. Vous pouvez constater que par l'exécution sp_helpdb
exec sp_helpdb 'DBName'
Garder simple:
use master
select DB.name, F.physical_name from sys.databases DB join sys.master_files F on DB.database_id=F.database_id
renverra toutes les bases de données avec les fichiers associés
A partir de l'interface graphique. Ouvrez vos propriétés du serveur, allez à Paramètres de base de données , et voir Base de données des emplacements par défaut
Notez que vous pouvez déposer vos fichiers de base de données où vous le souhaitez, mais il semble plus propre à les conserver dans le répertoire par défaut.
Vous pouvez trouver des données par défaut et les emplacements journal de l'instance actuelle de SQL Server en utilisant le T-SQL suivante:
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'
Petit pinailler:. Il n'y a pas de dossier de données, seulement default dossier de données
Quoi qu'il en soit, pour le trouver, en supposant que vous souhaitez installer pour la première instance par défaut:
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SQL Server \ MSSQL.1 \ Setup \ SQLDataRoot
S'il y a une instance nommée, MSSQL.1 devient quelque chose comme MSSQL10.INSTANCENAME.
« Développant les bits éclaboussé » réponse, 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
je l'aurais fait une restauration de sauvegarde simplement plus facile becuase son versionnage et de soutien. Les données de référence doit en particulier être versionné afin de savoir quand il a commencé à prendre effet. Une dettach attache vous donnera pas cette capacité. De plus avec les sauvegardes que vous pouvez continuer à fournir des copies mises à jour sans avoir à fermer la base de données.
réponse 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 un répertoire cible que vous obtenez ... les données par défaut / log répertoires. Facile.
Personnellement, cependant je serais probablement soit:
- Restaurez la base de données au PC du développeur, plutôt que de copier / attach (sauvegardes peuvent être compressées, exposées sur un UNC), ou
- Utiliser un serveur lié à éviter de le faire en premier lieu (dépend la quantité de données passe au-dessus de la jointure)
ps:. 20gb est pas énorme, même en 2015. Mais il 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 détail script SQL comment trouver le répertoire de données pour une instance SQL Server
Vous obtiendrez l'emplacement par défaut si la base de données de l'utilisateur par cette requête:
declare @DataFileName nVarchar(500)
declare @LogFileName nVarchar(500)
set @DataFileName = (select top 1 RTRIM(LTRIM(name)) FROM master.sys.master_files where database_id >4 AND file_id = 1)+'.mdf'
set @LogFileName = (select top 1 RTRIM(LTRIM(name)) FROM master.sys.master_files where database_id >4 AND file_id = 2)+'.ldf'
select
( SELECT top 1 SUBSTRING(physical_name, 1, CHARINDEX(@DataFileName, LOWER(physical_name)) - 1)
FROM master.sys.master_files
WHERE database_id >4 AND file_id = 1) as 'Data File'
,
(SELECT top 1 SUBSTRING(physical_name, 1, CHARINDEX(@LogFileName, LOWER(physical_name)) - 1)
FROM master.sys.master_files
WHERE database_id >4 AND file_id = 2) as 'Log File'