воскресенье, 27 марта 2016 г.

MS SQL - изменение collation сервера БД с большим числом баз

Вводная:
Как всегда достался в наследство сервер БД в котором при установке был  выбран не тот collation, а как известно "самый лучший софт" обычно чувствителен  к подобным настройкам.
Мне крупно повезло, что название всех БД были однотипными, по шаблону имя_номер. И до этого я уже провела ряд работ по наведению порядка в размещении БД.

Что делать:
Как известно, collation на сервере БД меняется путем пересоздания системных баз, при помощи команды

Setup /QUIET /ACTION=REBUILDDATABASE /INSTANCENAME=integration 
/SQLSYSADMINACCOUNTS=АдминистраторСервера /SAPWD=ПАРОЛЬ /SQLCOLLATION=Cyrillic_General_CI_AS

При пересозданием системных баз, есть ряд обязательных задач рекомендуемых к выполнению:
1. Это сохранение всех планов обслуживания и расписаний
2. Открепление (detach) баз данных
3. Прикрепление баз данных (attach) 
4. Восстановление необходимых заданий и планов обслуживания.

Открепление баз данных происходит очень быстро и просто при помощи немного модифицированного скрипта, найденного на просторах Internet.

use master
set nocount on
declare @dbname as varchar(80)
declare @server_name as varchar(20)
select @server_name = @@servername
declare rs_cursor CURSOR for select name from master.dbo.sysdatabases where name not in ('model','master','msdb','tempdb','alert_db','mssecurity')
open rs_cursor 
Fetch next from rs_cursor into @dbname
IF @@FETCH_STATUS <> 0 
   PRINT 'No database to backup...Please check your script!!!'
WHILE @@FETCH_STATUS = 0
BEGIN
  print 'Start detach of ' + upper(@dbname) 
  exec sp_detach_db @dbname 
  print 'sp_detach_db ' +  @dbname
  FETCH NEXT FROM rs_cursor INTO @dbname
END
CLOSE rs_cursor
deallocate rs_cursor

А вот что делать когда все базы (больше 100 штук придется прикреплять назад):
Если имена баз данных однотипны, то выполняем следующее:

1. Создаем таблицу в tempdb содержащую столбец с данными, содержащий отличающуюся часть имени базы данных, в моем случае номер. (001,002,003...)

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Num
 (
 Number char(10) NOT NULL
 )  ON [PRIMARY]
GO
ALTER TABLE dbo.Num ADD CONSTRAINT
 PK_Num PRIMARY KEY CLUSTERED 
 (
 Number
 ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

GO
ALTER TABLE dbo.Num SET (LOCK_ESCALATION = TABLE)
GO
COMMIT

2. Заполняем временную таблицу данными.
3. Определяем шаблон имени баз данных, определяем шаблон названия файлов баз данных и выполняем следующий скрипт.

USE [master]
GO

Declare  @DBName varchar (255);
Declare  @Log_Path varchar (255);
Declare  @DB_Path varchar (255);
Declare  @DB_N varchar (3);
Declare  @FileName_Log varchar (255);
Declare  @DB varchar (255);
Declare @SQL varchar (600);

SET @DB = 'Warehouse_';


declare rs_cursor CURSOR for select number from tempdb.dbo.Num 
open rs_cursor 
Fetch next from rs_cursor into @DB_N
IF @@FETCH_STATUS <> 0 
   PRINT 'No database to attach!!!'
WHILE @@FETCH_STATUS = 0
BEGIN

Set @DBName = @DB + @DB_N;
SET @Log_Path = 'G:\DataLog\Warehouse_'+@DB_N+'_log.ldf';
SET @DB_Path = 'F:\DataBase\Warehouse_'+@DB_N+'.mdf';
Set @FileName_Log = @DB+''+@DB_N + '_log';

Set @SQL = 'exec sp_attach_db @dbname = N' +  QuoteName( @DBName,'''') 
+ ',@filename1=N'
+ QuoteName(  @DB_Path, '''' )
+ ',@filename2=N'
+ QuoteName(  @Log_Path, '''' ) 
print @sql
Exec (@SQL)

 FETCH NEXT FROM rs_cursor INTO @DB_N

END
CLOSE rs_cursor
deallocate rs_cursor

print ' '
print 'ALL DONE'



1 комментарий:

Nghệ Nhân Trương комментирует...

Thanks for sharing, nice post!

Tìm hiểu máy đưa võng tự động là gì hay máy đưa võng cho bé loại nào tốt nhất và địa chỉ mua máy đưa võng giá rẻ uy tín nhất hiện nay mua máy đưa võng ở đâu uy tín giá rẻ.