我们有一些巨大的数据库(20GB +),其中大部分都包含静态查找数据。因为我们的应用程序对这些数据库中的表执行连接,所以它们必须是每个开发人员本地SQL Server的一部分(即它们不能托管在中央的共享数据库服务器上)。
我们计划复制一组规范的实际SQL Server数据库文件(* .mdf和* .ldf)并将它们附加到每个开发人员的本地数据库。
找出本地SQL Server实例的数据目录的最佳方法是什么,以便我们可以将文件复制到正确的位置?这将通过自动化过程完成,因此我必须能够从构建脚本中找到并使用它。
答案 0 :(得分:97)
这取决于是否为数据和日志文件设置了默认路径。
如果路径明确设置为Properties
=> Database Settings
=> Database default locations
然后SQL Server将Software\Microsoft\MSSQLServer\MSSQLServer
存储在DefaultData
和DefaultLog
值。
但是,如果未明确设置这些参数,则SQL Server将使用master数据库的数据和日志路径。
Bellow是涵盖这两种情况的脚本。这是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及更高版本中它是如此简单,假设您设置了默认路径(这可能总是正确的事情):
select
InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'),
InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath')
答案 1 :(得分:35)
即使这是一个非常古老的主题,我觉得我需要提供一个简单的解决方案。 只要您知道要在任何类型的自动脚本中访问Management Studio中的参数位置,最简单的方法是在独立测试系统上运行快速探查器跟踪并捕获Management Studio在后端执行的操作
在这种情况下,假设您有兴趣查找默认数据和日志位置,您可以执行以下操作:
选择
SERVERPROPERTY('instancedefaultdatapath')AS [DefaultFile],
SERVERPROPERTY('instancedefaultlogpath')AS [DefaultLog]
答案 2 :(得分:32)
我在SQL Server帮助中的Create Database语句的文档中偶然发现了这个解决方案:
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
答案 3 :(得分:23)
对于当前数据库,您可以使用:
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');
答案 4 :(得分:16)
从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的评论,并经过测试。)
答案 5 :(得分:8)
SQL Server的各种组件(数据,日志,SSAS,SSIS等)都有一个默认目录。可以在注册表中找到此设置。在这里阅读更多内容:
http://technet.microsoft.com/en-us/library/ms143547%28SQL.90%29.aspx
因此,如果您仅使用CREATE DATABASE MyDatabaseName
创建数据库,则会在上述某个设置中指定的路径上创建数据库。
现在,如果admin / installer更改了默认路径,那么实例的默认路径将存储在注册表中
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'
答案 6 :(得分:6)
保持简单:
use master
select DB.name, F.physical_name from sys.databases DB join sys.master_files F on DB.database_id=F.database_id
这将返回所有带有相关文件的数据库
答案 7 :(得分:2)
从GUI:打开服务器属性,转到数据库设置,然后查看数据库默认位置。
请注意,您可以将数据库文件放在任何您喜欢的位置,但将它们保存在默认目录中似乎更简洁。
答案 8 :(得分:1)
您可以使用以下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'
答案 9 :(得分:0)
Small nitpick:没有数据文件夹,只有默认数据文件夹。
无论如何,要找到它,假设您要为第一个默认实例安装:
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SQL Server \ MSSQL.1 \ Setup \ SQLDataRoot
如果有一个命名实例,MSSQL.1就像MSSQL10.INSTANCENAME一样。
答案 10 :(得分:0)
扩展“splattered bits”答案,这是一个完整的脚本:
@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
答案 11 :(得分:0)
我会做一个备份恢复,只是因为它更容易和支持版本控制。参考数据尤其需要进行版本控制,以便了解它何时开始生效。一个脱离附件不会给你这种能力。此外,通过备份,您可以继续提供更新的副本,而无需关闭数据库。
答案 12 :(得分:0)
Alex's answer是正确的,但对于后人来说,这是另一种选择:创建一个新的空数据库。如果在没有指定目标目录的情况下使用CREATE DATABASE,则会得到...默认的数据/日志目录。容易。
但我个人可能要么:
ps:即使在2015年,20gb并不大。但它都是相对的。
答案 13 :(得分:0)
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\%'
您可以从how to find the data directory for a SQL Server instance
下载详细的SQL脚本答案 14 :(得分:-1)
如果用户数据库通过此查询,您将获得默认位置:
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'