سؤال

لدينا عدد قليل تسربت قواعد البيانات (20GB +) والتي تحتوي في الغالب على بيانات البحث الثابت. نظرا لأن تطبيقنا ينفذ ينضم إلى الجداول في قواعد البيانات هذه، يجب أن يكون جزءا من كل مطوري SQL Server محلي (أي لا يمكن استضافتها على خادم قاعدة بيانات مركزية ومشتركة).

نحن نخطط لنسخ مجموعة واضحة من ملفات قاعدة بيانات SQL Server الفعلية (* .mdf و * .ldf) وإرفاقها على قاعدة بيانات كل مطور محلية.

ما هي أفضل طريقة لمعرفة دليل بيانات مثلي SQL Server المحلي حتى نتمكن من نسخ الملفات إلى المكان المناسب؟ سيتم القيام بذلك عن طريق عملية آلية، لذلك يجب أن أكون قادرا على العثور عليها واستخدامها من البرنامج النصي للبناء.

هل كانت مفيدة؟

المحلول

يعتمد ذلك على ما إذا كان المسار الافتراضي محدد لملفات البيانات والسجل أم لا.

إذا تم ضبط المسار بشكل صريح في Properties => Database Settings => Database default locations ثم SQL Server يخزنه في Software\Microsoft\MSSQLServer\MSSQLServer في DefaultData و DefaultLog القيم.

ومع ذلك، إذا لم يتم تعيين هذه المعلمات بشكل صريح، فإن SQL Server يستخدم بيانات البيانات وسجل قاعدة البيانات الرئيسية.

رفع الصوت عاليا هو البرنامج النصي الذي يغطي كلتا الحالتين. هذا هو إصدار مبسط من الاستعلام الذي يعمل 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')

نصائح أخرى

على الرغم من أن هذا هو موضوع قديم للغاية، أشعر أنني بحاجة إلى المساهمة في حل بسيط. في أي وقت تعرفه حيث توجد معلمة في إدارة الاستوديو التي ترغب في الوصول إليها لأي نوع من البرنامج النصي الآلي، فإن الطريقة الأسهل هي تشغيل تتبع منشآت سريعة في نظام اختبار مستقل والتقاط ما يقوم الاستوديو بالإدارة في الخلفية وبعد

في هذه الحالة، على افتراض أنك مهتم بإيجاد البيانات الافتراضية ومواقع السجل التي يمكنك القيام بما يلي:

تحديد
serverproperty ('instancedefaultdatapath') كما [defaultfile]،
serverproperty ('instancedefaultlogpath') كما [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

بالنسبة لقاعدة البيانات الحالية، يمكنك فقط استخدام:

select physical_name fromsys.database_files;

لتحديد قاعدة بيانات أخرى مثل "نموذج"، استخدم 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 Server (البيانات، سجلات، SSAS، SSIS، إلخ) لها دليل افتراضي. يمكن العثور على الإعداد لهذا السجل. اقرأ المزيد هنا:

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

لذلك إذا قمت بإنشاء قاعدة بيانات باستخدام فقط CREATE DATABASE MyDatabaseName سيتم إنشاؤه في المسار المحدد في أحد الإعدادات أعلاه.

الآن، إذا قام المشرف / 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'

الحفاظ عليه بسيط:

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: افتح خصائص الخادم الخاصة بك، انتقل إلى إعدادات قاعدة البيانات, ، ونرى مواقع قاعدة البيانات الافتراضية.

لاحظ أنه يمكنك إسقاط ملفات قاعدة البيانات الخاصة بك أينما تريد، على الرغم من أنها تبدو نظافة لإبقائها في الدليل الافتراضي.

يمكنك العثور على بيانات البيانات والخطوط الافتراضية لمثيل SQL Server الحالي باستخدام 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'

nitpick الصغيرة: لا يوجد مجلد بيانات، فقط إفتراضي مجلد البيانات.

على أي حال، للعثور عليه، على افتراض أنك تريد تثبيت مثيل الافتراضي الأول:

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

كنت قد فعلت استعادة النسخ الاحتياطي ببساطة أصبحت نسخة أسهل ودعمها. يجب إصدار البيانات المرجعية بشكل خاص من أجل معرفة متى بدأت نافذة المفعول. إرفاق Dettach لن يمنحك هذه القدرة. أيضا مع النسخ الاحتياطية، يمكنك الاستمرار في توفير نسخ محدثة دون الحاجة إلى إيقاف تشغيل قاعدة البيانات.

إجابة أليكس هو الصحيح، ولكن بالنسبة للأجيال القادمة هنا خيار آخر: إنشاء قاعدة بيانات فارغة جديدة. إذا كنت تستخدم إنشاء قاعدة بيانات دون تحديد DIR الهدف، فستحصل على ... الدلائل الافتراضية للبيانات / السجل. سهل.

ولكن شخصيا ربما كذلك:

  • استعادة قاعدة البيانات إلى كمبيوتر المطور، بدلا من النسخ / إرفاق (يمكن ضغط النسخ الاحتياطية، مكشوفة على UNC)، أو
  • استخدم خادم مرتبط لتجنب القيام بذلك في المقام الأول (يعتمد مقدار البيانات التي تمر عبر الصلة)

ملاحظة: 20GB ليست ضخمة، حتى في عام 2015. ولكن كل ذلك قريب.

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 image description here

يمكنك تنزيل التفاصيل SQL Script من كيفية العثور على دليل البيانات لمثيل SQL Server

سوف تحصل على الموقع الافتراضي إذا كانت قاعدة بيانات المستخدم حسب هذا الاستعلام:

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'
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top