Pergunta

Temos alguns enorme bancos de dados (20GB +) que contêm principalmente dados de pesquisa estáticos. Porque os nossos executa aplicativos junta-se contra tabelas nesses bancos de dados, eles têm que ser parte de cada desenvolvedores de SQL Server local (ou seja, eles não podem ser hospedados em um servidor de banco de dados central, compartilhada).

Estamos pensando em copiar um conjunto canônico dos arquivos de banco de dados SQL Server reais (* .mdf e * .ldf) e anexá-las ao banco de dados local de cada desenvolvedor.

Qual é a melhor maneira de descobrir o diretório de dados do instância local do SQL Server para que possamos copiar os arquivos para o lugar certo? Isto será feito através de um processo automatizado, então eu tenho que ser capaz de encontrar e usá-lo a partir de um script de construção.

Foi útil?

Solução

Depende se caminho padrão está definido para dados e arquivos de log ou não.

Se o caminho está definido explicitamente na Properties => Database Settings => Database default locations então servidor armazena SQL TI em Software\Microsoft\MSSQLServer\MSSQLServer em valores DefaultData e DefaultLog.

No entanto, se esses parâmetros não são definidas explicitamente, servidor SQL utiliza caminhos de dados e de log do banco de dados mestre.

Abaixo está o script que cobre ambos os casos. Esta é simplificada versão da consulta que SQL Management Studio é executado.

Além disso, observe que eu uso xp_instance_regread vez de xp_regread, então este script irá trabalhar para qualquer instância, padrão ou nomeado.

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

Você pode conseguir o mesmo resultado usando SMO. Bellow é C amostra #, mas você pode usar qualquer outra linguagem .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;
}

É muito mais simples no SQL Server 2012 e acima, supondo que você tenha caminhos padrão definido (o que provavelmente é sempre uma coisa certa a fazer):

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

Outras dicas

Mesmo que este é um fio muito velho, eu sinto que eu preciso para contribuir com uma solução simples. Qualquer hora que você sabe onde no Management Studio um parâmetro está localizado que você deseja acessar para qualquer tipo de script automatizado, a maneira mais fácil é executar um rastreio profiler rápido em um sistema de teste autônomo e captura o Management Studio está fazendo no backend .

Neste exemplo, supondo que você está interessado em encontrar os dados padrão e os locais de log que você pode fazer o seguinte:

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

me deparei com esta solução na documentação para a instrução Criar banco de dados na ajuda para o 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

Para o banco de dados atual você pode apenas usar:

select physical_name from href="http://msdn.microsoft.com/en-us/library/ms174397.aspx" rel="noreferrer"> sys.database_files;

para especificar outro banco de dados, por exemplo, 'Model', de uso sys.master_files

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

A partir do SQL Server 2012, você pode usar a seguinte consulta:

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

(Isto foi tomado de um comentário em http://technet.microsoft.com/en-us /library/ms174396.aspx , e testado.)

Vários componentes do SQL Server (Data, Logs, SSAS, SSIS, etc) tem um diretório padrão. A configuração para isso pode ser encontrado no Registro. Leia mais aqui:

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

Então, se você criou um banco de dados usando apenas CREATE DATABASE MyDatabaseName seria criado no caminho especificado em uma das configurações acima.

Agora, se o administrador / instalador mudou o caminho padrão, em seguida, o caminho padrão para a instância é armazenada no registro em

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

Se você sabe o nome da instância, em seguida, você pode consultar o registro. Este exemplo é SQL específica de 2008 -. Deixe-me saber se você precisa do caminho SQL2005 bem

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

Cada banco de dados pode ser criado sobrepondo a configuração do servidor em um local próprio que é quando você emitir a declaração CREATE DATABASE DBName com os parâmetros apropriados. Você pode descobrir isso por executar sp_helpdb

exec sp_helpdb 'DBName'

Mantê-lo simples:

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

este retornará todos os bancos de dados com arquivos associados

A partir da GUI:. Aberta suas propriedades do servidor, vá para o Configurações de banco de dados , e veja locais padrão de banco de dados

Note que você pode soltar os arquivos de banco de dados onde quer que você gosta, embora pareça mais limpo para mantê-los no diretório padrão.

Você pode encontrar dados e de log locais padrão para a instância atual do SQL Server usando o seguinte 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'

pequeno procurar defeitos:. Não há nenhuma pasta de dados, apenas uma padrão pasta de dados

De qualquer forma, para encontrá-lo, supondo que você deseja instalar pela primeira instância padrão:

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

Se houver uma instância nomeada, MSSQL.1 torna-se algo como MSSQL10.INSTANCENAME.

resposta Expansão em "pedaços salpicado", aqui está um script completo que faz isso:

@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

i teria feito uma cópia de segurança restaurar simplesmente becuase é mais fácil e suporte de versões. Dados de referência precisa especialmente para ser versionadas, a fim de saber quando ele começou a fazer efeito. A destacá anexar não vai dar-lhe essa capacidade. Também com backups você pode continuar a fornecer cópias atualizadas sem ter que desligar o banco de dados.

de

Alex resposta é o caminho certo, mas para a posteridade aqui está uma outra opção: criar um novo banco de dados vazio. Se você usar CREATE DATABASE sem especificar um dir-alvo que você começa ... os dados padrão / diretórios de log. Fácil.

Pessoalmente no entanto eu provavelmente quer:

  • restaurar o banco de dados para PC do desenvolvedor, em vez de copiar / attach (backups podem ser comprimidos, exposta em um UNC), ou
  • Use um servidor vinculado para evitar fazer isso em primeiro lugar (depende a quantidade de dados vai até a junção)

ps:. 20gb não é enorme, mesmo em 2015. Mas é tudo 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\%'

enter descrição da imagem aqui

Você pode baixar script SQL detalhe como encontrar o diretório de dados para uma instância do SQL Server

Você vai obter a localização padrão se do banco de dados do usuário por esta consulta:

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'
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top