如何查找 SQL Server 实例的数据目录?
-
19-09-2019 - |
题
我们有几个 巨大的 数据库(20GB+),主要包含静态查找数据。因为我们的应用程序对这些数据库中的表执行联接,所以它们必须是每个开发人员本地 SQL Server 的一部分(即,它们不能托管在中央共享数据库服务器上)。
我们计划复制一组规范的实际 SQL Server 数据库文件(*.mdf 和 *.ldf)并将它们附加到每个开发人员的本地数据库。
找出本地 SQL Server 实例的数据目录以便我们将文件复制到正确位置的最佳方法是什么?这将通过自动化过程完成,因此我必须能够从构建脚本中找到并使用它。
解决方案
这取决于默认路径是否被设置为数据和日志文件或不
如果路径在Properties
=> Database Settings
=>然后Database default locations
SQL服务器存储它明确地设定在Software\Microsoft\MSSQLServer\MSSQLServer
和DefaultData
值DefaultLog
然而,如果这些参数没有显式地设置,SQL服务器使用主数据库的数据和日志路径。
娄是覆盖这两种情况下该脚本。这简化该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相同的结果。波纹管是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以上,假设你已经默认路径设置(这可能是永远做正确的事):
select
InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'),
InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath')
其他提示
尽管这是一个非常古老的线程,我觉得自己需要贡献一个简单的解决方案。 你知道在哪里Management Studio中参数位于您要访问的任何类型的自动脚本的任何时候,最简单的方法是将一个独立测试系统上运行快速探查器跟踪并捕捉什么管理工作室正在做后台
在这种情况下,假设你有兴趣在寻找的默认数据和日志的位置,你可以做到以下几点:
选择,点击 SERVERPROPERTY( 'instancedefaultdatapath')AS [DefaultFile],结果 SERVERPROPERTY( 'instancedefaultlogpath')AS [DefaultLog] 强>
我碰到这个解决方案的文档中在帮助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
有关当前数据库中你可以使用:
到例如指定另一个数据库'模型',使用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 和测试。)
SQL服务器(数据,日志SSAS,SSIS等)的各种组件具有默认目录。此项设置可以在注册表中找到。在这里阅读更多:
http://technet.microsoft.com/ EN-US /库/ ms143547%28SQL.90%29.aspx
所以,如果你只使用CREATE DATABASE MyDatabaseName
它会在上面设置一个指定的路径创建创建数据库。
现在,如果管理员/安装改变默认路径,则对于实例的默认路径被存储在注册表中,在
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\[INSTANCENAME]\Setup
如果您知道实例的名称,然后你就可以查询注册表。这个例子是SQL 2008的具体 - 让我知道如果你需要的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
每个数据库都可以创建覆盖在当您发出适当的参数CREATE DATABASE DBName
声明一个它自己的位置服务器设置。你可以发现,从通过执行的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:打开你的服务器属性,去的数据库设置的,看的数据库默认位置的
请注意,你可以将你的数据库文件你喜欢的地方,但它似乎更清洁,让他们在默认目录。
您可以使用下面的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'
小挑剔:没有数据文件夹中,仅一个默认数据文件夹
总之,要找到它,假设你要安装的第一个默认实例:
HKEY_LOCAL_MACHINE \ SOFTWARE \微软\ Microsoft SQL Server的\ MSSQL.1 \设置\ 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
我会做一个备份恢复只是监守它更容易和支持版本。参考的数据尤其是需要才能知道是版本的时候才开始生效。一个dettach附上不会给你这种能力。也有备份,你可以继续提供更新的副本,而无需关闭数据库。
亚历克斯的回答 是正确的,但对于后代来说,这是另一种选择:创建一个新的空数据库。如果您使用 CREATE DATABASE 而不指定目标目录,您会得到...默认数据/日志目录。简单的。
但就我个人而言,我可能会:
- 将数据库恢复到开发人员的 PC,而不是复制/附加(可以压缩备份,在 UNC 上公开),或者
- 使用链接服务器可以避免首先执行此操作(取决于连接上传输的数据量)
附:即使在 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\%'
您将得到默认的位置,如果此查询用户数据库:
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'