如何findSQL Server实例的数据目录?

我们有几个巨大的数据库(20GB +),其中大部分都包含静态查找数据。 由于我们的应用程序对这些数据库中的表执行连接,因此它们必须是每个开发人员本地SQL Server的一部分(即,它们不能托pipe在中央共享数据库服务器上)。

我们计划复制实际的SQL Server数据库文件(* .mdf和* .ldf)的规范集,并将它们附加到每个开发人员的本地数据库。

找出本地SQL Server实例的数据目录的最佳方法是什么,以便我们可以将文件复制到正确的位置? 这将通过一个自动化的过程完成,所以我必须能够从构build脚本中find并使用它。

这取决于是否为数据和日志文件设置默认path。

如果在“ Properties =>“ Database Settings =“ Database default locations Database Settings显式设置path,则SQL Server将其以DefaultDataDefaultLog值存储在Software\Microsoft\MSSQLServer\MSSQLServer中。

但是,如果没有明确设置这些参数,SQL Server将使用主数据库的数据和日志path。

贝娄是涵盖两种情况的脚本。 这是SQL Management Studio运行的查询的简化版本。

此外,请注意,我使用xp_instance_regread而不是xp_regread ,所以此脚本将适用于任何实例,默认或命名。

 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 

您可以使用SMO来获得相同的结果。 Bellow是C#示例,但您可以使用任何其他.NET语言或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; } 

在SQL Server 2012及更高版本中,这是非常简单的,假设你有默认的path设置(这可能总是正确的):

 select InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'), InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath') 

我在SQL Server帮助中的“创build数据库”语句的文档中偶然发现了这个解决scheme:

 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 

即使这是一个非常老的线程,我觉得我需要提供一个简单的解决scheme。 每当您知道Management Studio中的某个参数位于您想要访问的任何types的自动脚本时,最简单的方法是在独立testing系统上运行快速剖析器跟踪,并捕获Management Studio在后端执行的操作。

在这种情况下,假设您有兴趣find默认数据和日志位置,您可以执行以下操作:

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

对于当前数据库,您可以使用:

select physical_name from sys.database_files; select physical_name from sys.database_files;

要指定另一个数据库,例如'Model',请使用sys.master_files

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

从Sql Server 2012开始,您可以使用以下查询:

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

(这是从http://technet.microsoft.com/en-us/library/ms174396.aspx的评论中获得的,并经过testing。);

SQL Server的各种组件(数据,日志,SSAS,SSIS等)都有一个默认目录。 这个设置可以在registry中find。 在这里阅读更多:

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

所以,如果你使用CREATE DATABASE MyDatabaseName创build一个数据库,它将在上面的设置之一中指定的path创build。

现在,如果pipe理员/安装程序更改了默认path,则实例的默认path将存储在registry中

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

如果您知道实例的名称,那么您可以查询registry。 这个例子是SQL 2008特定的 – 让我知道你是否也需要SQL2005path。

 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 

当您使用适当的参数发出CREATE DATABASE DBName语句时,可以创build每个数据库,覆盖它自己的位置中的服务器设置。 你可以通过执行sp_helpdb来发现

 exec sp_helpdb 'DBName' 

保持简单:

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

这将返回所有数据库与关联的文件

在GUI中:打开服务器属性,转到数据库设置 ,然后查看数据库默认位置

请注意,您可以将数据库文件放在任何位置,尽pipe将它们保留在默认目录中似乎更清晰。

您可以使用以下T-SQL查找当前SQL Server实例的默认数据和日志位置:

 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' 

小挑逗:没有数据文件夹,只有一个默认的数据文件夹。

无论如何,要find它,假设你想安装第一个默认实例:

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

如果有一个命名的实例,MSSQL.1就像MSSQL10.INSTANCENAME。

扩展“溅出的碎片”的答案,这里是一个完整的脚本:

 @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 

只是因为更容易和支持版本化,我会做一个备份恢复。 参考数据尤其需要进行版本化,以便知道何时开始生效。 附加附件不会给你这个能力。 还有备份,您可以继续提供更新的副本,而不必closures数据库。

亚历克斯的答案是正确的,但是对于后人来说,还有另一种select:创build一个新的空数据库。 如果你使用CREATE DATABASE而不指定目标目录,你会得到默认的数据/日志目录。 简单。

但个人而言,我可能会:

  • 将数据库恢复到开发人员的PC,而不是复制/附加(备份可以压缩,暴露在UNC上),或者
  • 使用链接服务器来避免这样做(取决于多less数据通过连接)

ps:即使在2015年,20GB也不算庞大,但都是相对的。

 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\%' 

在这里输入图像说明

您可以从如何查找SQL Server实例的数据目录下载详细的SQL脚本

如果用户数据库通过此查询,您将获得默认位置:

 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'