Come faccio a trovare la directory dei dati per un'istanza di SQL Server?
-
19-09-2019 - |
Domanda
Abbiamo un paio di enorme database (20GB +) che contengono la maggior parte dei dati di ricerca statici. Perché i nostri esegue applicazioni si unisce contro tabelle in questi database, devono essere parte di ogni sviluppatori locali di SQL Server (vale a dire che non può essere ospitato su un server database condiviso centrale).
Abbiamo intenzione di copiare una serie canonica dei file di database SQL Server effettivi (* .mdf e .ldf *) e di collegarli a database locale di ogni sviluppatore.
Qual è il modo migliore per scoprire directory dei dati del istanza locale di SQL Server in modo che possiamo copiare i file al posto giusto? Ciò avverrà tramite un processo automatico, quindi devo essere in grado di trovare e utilizzare da uno script di build.
Soluzione
Dipende se percorso predefinito è impostato per i dati e file di log oppure no.
Se il percorso è impostato in modo esplicito a Properties
=> Database Settings
=> Database default locations
poi SQL server memorizza in Software\Microsoft\MSSQLServer\MSSQLServer
nei valori DefaultData
e DefaultLog
.
Tuttavia, se questi parametri non sono impostati in modo esplicito, SQL Server utilizza i percorsi dati e di log del database master.
Bellow è lo script che copre entrambi i casi. Questo è semplificata versione della query che SQL Management Studio viene eseguito.
Si noti inoltre che io uso xp_instance_regread
invece di xp_regread
, quindi questo script funziona per qualsiasi esempio, di default o di nome.
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
È possibile ottenere lo stesso risultato utilizzando SMO. Bellow è C # di esempio, ma è possibile utilizzare qualsiasi altro linguaggio .NET o 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;
}
E 'molto più semplice in SQL Server 2012 e, soprattutto, a patto di avere percorsi di default impostato (che probabilmente è sempre una cosa giusta da fare):
select
InstanceDefaultDataPath = serverproperty('InstanceDefaultDataPath'),
InstanceDefaultLogPath = serverproperty('InstanceDefaultLogPath')
Altri suggerimenti
Anche se questa è una discussione molto vecchio, mi sento come se avessi bisogno di contribuire una soluzione semplice. Ogni volta che si sa dove in Management Studio un parametro si trova che si desidera accedere a qualsiasi tipo di script automatico, il modo più semplice è quello di eseguire una traccia di profiler rapida su un sistema di test indipendente e catturare ciò Management Studio sta facendo sul backend .
In questo caso, supponendo che si sono interessati a trovare i dati di default e accede posizioni è possibile effettuare le seguenti operazioni:
SELEZIONA
SERVERPROPERTY ( 'instancedefaultdatapath') AS [DefaultFile],
SERVERPROPERTY ( 'instancedefaultlogpath') AS [DefaultLog]
mi sono imbattuto in questa soluzione nella documentazione per l'istruzione Crea database nella Guida per 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
Per il database corrente si può semplicemente utilizzare:
per specificare un altro database per esempio 'Modello', uso sys.master_files
select physical_name from sys.master_files where database_id = DB_ID(N'Model');
Come di SQL Server 2012, è possibile utilizzare la seguente query:
SELECT SERVERPROPERTY('INSTANCEDEFAULTDATAPATH') as [Default_data_path], SERVERPROPERTY('INSTANCEDEFAULTLOGPATH') as [Default_log_path];
(questo è stato preso da un commento a http://technet.microsoft.com/en-us /library/ms174396.aspx , e testato.)
I vari componenti di SQL Server (dati, registri, SSAS, SSIS, ecc) hanno una directory predefinita. L'impostazione di questo può essere trovato nel Registro di sistema. Per saperne di più qui:
http://technet.microsoft.com/ it-it / library / ms143547% 28SQL.90% 29.aspx
Quindi, se è stato creato un database utilizzando solo CREATE DATABASE MyDatabaseName
sarebbe creato nel percorso specificato in una delle impostazioni di cui sopra.
Ora, se l'amministratore / installatore ha cambiato il percorso predefinito, quindi il percorso predefinito per l'istanza viene memorizzato nel Registro di sistema
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\[INSTANCENAME]\Setup
Se si conosce il nome dell'istanza allora si può interrogare il Registro di sistema. Questo esempio è SQL 2008 specifica -. Fatemi sapere se avete bisogno il percorso SQL2005 pure
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
Ogni database può essere creato ignorando l'impostazione del server in essa la propria posizione quando si emette la dichiarazione CREATE DATABASE DBName
con i parametri appropriati. Potete scoprirlo eseguendo sp_helpdb
exec sp_helpdb 'DBName'
La semplicità:
use master
select DB.name, F.physical_name from sys.databases DB join sys.master_files F on DB.database_id=F.database_id
questo restituirà tutti i database con i file associati
Dalla GUI:. Apri la tua proprietà del server, andare a Impostazioni database , e vediamo posizioni predefinite database
Si noti che è possibile eliminare i file di database dove si vuole, anche se sembra più pulito per tenerli nella directory di default.
Si possono trovare dati di default e le posizioni di registro per l'istanza corrente di SQL Server utilizzando il seguente T-SQL:
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'
Piccolo nitpick:. Non v'è alcuna cartella dati, solo un default cartella di dati
In ogni caso, per trovarlo, supponendo che si desidera installare per la prima istanza di default:
HKEY_LOCAL_MACHINE \ SOFTWARE Microsoft \ Microsoft SQL Server \ MSSQL.1 \ Setup \ \ SQLDataRoot
Se c'è un'istanza denominata, MSSQL.1 diventa qualcosa di simile a MSSQL10.INSTANCENAME.
Ampliando "bit" schizzato risposta, qui è uno script completo che fa:
@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
avrei fatto ripristinare un backup semplicemente becuase suo controllo delle versioni più facile e sostegno. I dati di riferimento deve in particolare essere di versione in modo da sapere quando è iniziato a prendere vigore. Un dettach allegare non ti dà quella capacità. Anche con i backup è possibile continuare a fornire copie aggiornate, senza dover chiudere il database.
di Alex risposta è quella giusta, ma per i posteri, ecco un'altra opzione: creare un nuovo database vuoto. Se si utilizza CREATE DATABASE senza specificare una directory di destinazione si ottiene ... i dati di default / directory log. Facile.
Personalmente però mi sarebbe probabilmente uno:
- ripristinare il database PC dello sviluppatore, piuttosto che copiare / attaccare (backup possono essere compressi, esposto su un UNC), o
- Utilizzare un server collegato per evitare di fare questo, in primo luogo (dipende da quanto i dati va oltre il join)
ps:. 20gb non è enorme, anche nel 2015. Ma è tutto relativo
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\%'
È possibile scaricare i dettagli script SQL da come trovare il directory dei dati per un'istanza di SQL Server
Si otterrà posizione predefinita se il database utente da questa query:
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'