25. Februar 2014 20:19
set @SourceDB = N'<DB-Name>'
set @Person = N'<eig. Kürzel>'
-- SQL Server Mangement Studio 2012 SP1.
-- Kopie einer Datenbank innerhalb eines SQL-Server anlegen
-- Name der Kopie aus Original-Name abgeleitet
-- weitere Vorraussetzungen :
-- läuft bei mir unter dem SQL-User sa, der auch DatenbankOwner aller Datenbanken ist
-- nutzt das Verzeichnis d:\temp
-- xp_cmdshell ist aktiviert (http://technet.microsoft.com/de-de/library/ms175046.aspx)
-- eventuell bestehende Zieldatenbank wird überschrieben
-- Alle Benutzer der Zieldatenbank werden gelöscht
-- eine Liste von UserID wird mit "super"-Rechten in die Zieldatenbank eingetragen
--
Declare @SourceDB varchar(250)
Declare @Person varchar(20)
set @SourceDB = N'<DB-Name>'
set @Person = N'<eig. Kürzel>'
--
-- berechnete Werte
Declare @TargetDB varchar(250)
set @TargetDB = N'Test_'+@Person+'_'+@SourceDB
Declare @TempPath varchar(250)
set @TempPath = N'd:\Temp\Kopiebasis_'+@SourceDB+'.bak'
-- Weitere Einmal-Werte
set nocount on
Declare @ManUserList table (UserID varchar(30),UserName varchar(30))
-- Beispiel 'UserID','UserName'
-- beliebig viele Einträge möglich
insert into @ManUserList values('UserId_1','User_ID_1_Name')
Declare @ManWindowsLoginList table (UserID varchar(80) )
-- Beispiel : '\\domäne\UserID'
-- beliebig viele Einträge möglich
insert into @ManWindowsLoginList values('\\domain\user_id')
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Declare @SIDOutput Table (Outputzeile varchar(80))
Declare curSIDOutput cursor for
select Outputzeile from @SIDOutput
Declare curManUserList cursor for
select UserID,Username from @ManUserList
Declare curManWindowsLoginList cursor for
select UserId from @ManWindowsLoginList
declare @FileListTable table
(
LogicalName nvarchar(128),
PhysicalName nvarchar(260),
[Type] char(1),
FileGroupName nvarchar(128),
Size numeric(20,0),
MaxSize numeric(20,0),
FileID bigint,
CreateLSN numeric(25,0),
DropLSN numeric(25,0),
UniqueID uniqueidentifier,
ReadOnlyLSN numeric(25,0),
ReadWriteLSN numeric(25,0),
BackupSizeInBytes bigint,
SourceBlockSize int,
FileGroupID int,
LogGroupGUID uniqueidentifier,
DifferentialBaseLSN numeric(25,0),
DifferentialBaseGUID uniqueidentifier,
IsReadOnl bit,
IsPresent bit,
TDEThumbprint varbinary(32)
)
DECLARE curFileLIst CURSOR FOR
SELECT 'MOVE N''' + LogicalName + ''' TO N''' +
replace(PhysicalName, @SourceDB, @TargetDB) + ''''
FROM @FileListTable
Declare @v_strTEMP varchar(4000)
DECLARE @spidstr varchar(8000)
Declare @DynAusdr varchar(4000)
Declare @MoveAusdr varchar(4000)
Declare @T1 varchar(80)
Declare @T2 varchar(80)
Declare @DomainName varchar(80)
Declare @DomainUser varchar(80)
Declare @DomainSID varchar(80)
Declare @ManCount table(Zaehler int)
Declare curManCount cursor for
select Zaehler from @ManCount
Declare @VarManCount int
-- Rechtsklick auf die Quell-Datenbank
-- > Tasks
-- > Sichern
-- > Festplatte auswählen, DB sichern, fertig.
set @DynAusdr= 'BACKUP DATABASE ['+@SourceDB+']
TO DISK = N'''+@TempPath+'''
WITH NOFORMAT, INIT,
NAME = N''Nur für Kopiervorgang'',
SKIP, NOREWIND, NOUNLOAD,STATS=10'
print @DynAusdr
exec(@DynAusdr)
-- Dann Rechtsklick auf Datenbanken
-- > Dateien und Dateigruppen wiederherstellen
-- > Wiederherzustellendes Ziel
-- > neue DB eintragen
-- > unten bei der Quelle wählst Du die Quell-Datenbank aus
-- > unten die Sicherung auswählen
-- > OK, fertig
if db_id(@TargetDB) is not null
begin
SET @spidstr = ''
SELECT @spidstr=coalesce(@spidstr,',' )+'kill '+convert(varchar, spid)+ '; '
FROM master..sysprocesses WHERE dbid=db_id(@TargetDB)
print @spidstr
EXEC(@spidstr)
end
set @DynAusdr = 'RESTORE FILELISTONLY
FROM DISK = N'''+@TempPath+'''
WITH FILE = 1'
print @DynAusdr
insert into @FileListTable exec(@DynAusdr)
set @DynAusdr = 'RESTORE DATABASE ['+@TargetDB+']
FROM DISK = N'''+@TempPath+'''
WITH FILE = 1,
'
OPEN curFileList
FETCH NEXT FROM curFileList into @v_strTEMP
WHILE @@Fetch_Status = 0
BEGIN
SET @DynAusdr = @DynAusdr + @v_strTEMP + ',
'
FETCH NEXT FROM curFileList into @v_strTEMP
END
CLOSE curFileList
DEALLOCATE curFileList
SET @DynAusdr = @DynAusdr + 'NOUNLOAD, REPLACE,STATS=10'
print @DynAusdr
exec(@DynAusdr)
set @DynAusdr = N'cmd.exe /c del '+ @TempPath
exec XP_cmdshell @DynAusdr , no_output
if object_id(@Targetdb+'.dbo.benutzer') is not NULL
begin
print '1' + object_id(@Targetdb+'.dbo.benutzer')
set @DynAusdr = 'Truncate table ['+@Targetdb+'].[dbo].[benutzer]'
print @DynAusdr
exec(@DynAusdr)
set @DynAusdr = 'Truncate table ['+@Targetdb+'].[dbo].[Mitglied von]'
print @DynAusdr
exec(@DynAusdr)
set @DynAusdr = 'select count(COLUMN_NAME) from ['+@Targetdb+'].INFORMATION_SCHEMA.Columns Where '+
'TABLE_NAME=''benutzer'' AND COLUMN_NAME=''Alternativbenutzer'''
print @DynAusdr
insert into @ManCount exec(@DynAusdr)
OPEN curManCount
FETCH NEXT FROM curManCount into @VarManCount
CLOSE curManCount
print N'Spalte vorhanden : '+cast(@VarManCount as varchar(5))
open curManUserList
FETCH NEXT FROM curManUserList INTO @T1,@T2
if @VarManCount <> 0
begin;
-- Navision 2.00 Objekte
WHILE @@FETCH_STATUS = 0
BEGIN
set @DynAusdr = 'insert into ['+@Targetdb+'].[dbo].[benutzer]'+
'([Benutzer Id],[Name],[Ablaufdatum],[Kennwort],[Alternativbenutzer])'+
' values(N'''+@T1+''',N'''+@T2+''',''01.01.2999'','''','''')'
print @DynAusdr
exec(@DynAusdr)
set @DynAusdr = 'insert into ['+@Targetdb+'].[dbo].[Mitglied von]'+
'([Benutzer Id],[Gruppen ID],[Mandant])'+
' values(N'''+@T1+''',N''SUPER'','''')'
print @DynAusdr
exec(@DynAusdr)
FETCH NEXT FROM curManUserList INTO @T1,@T2
end
end else begin
-- Navision 2.60 Objekte
WHILE @@FETCH_STATUS = 0
BEGIN
set @DynAusdr = 'insert into ['+@Targetdb+'].[dbo].[benutzer]'+
'([Benutzer Id],[Name],[Ablaufdatum],[Kennwort])'+
' values(N'''+@T1+''',N'''+@T2+''',''01.01.2999'','''')'
print @DynAusdr
exec(@DynAusdr)
set @DynAusdr = 'insert into ['+@Targetdb+'].[dbo].[Mitglied von]'+
'([Benutzer Id],[Rollen ID],[Mandant])'+
' values(N'''+@T1+''',N''SUPER'','''')'
print @DynAusdr
exec(@DynAusdr)
FETCH NEXT FROM curManUserList INTO @T1,@T2
end
end
CLOSE curManUserList
DEALLOCATE curManUserList
end
if object_id(@Targetdb+'.dbo.user') is not NULL
begin
-- Nav 2009 Objekte
print '2'
print object_id(@Targetdb+'.dbo.user')
set @DynAusdr = N'Truncate table ['+@Targetdb+'].[dbo].[user]'
print @DynAusdr
exec(@DynAusdr)
set @DynAusdr = N'Truncate table ['+@Targetdb+'].[dbo].[Member of]'
print @DynAusdr
exec(@DynAusdr)
open curManUserList
FETCH NEXT FROM curManUserList INTO @T1,@T2
WHILE @@FETCH_STATUS = 0
BEGIN
set @DynAusdr = 'insert into ['+@Targetdb+'].[dbo].[user]'+
'([User Id],[Name],[Expiration Date],[Password])'+
' values(N'''+@T1+''',N'''+@T2+''',''01.01.2999'','''')'
print @DynAusdr
exec(@DynAusdr)
set @DynAusdr = 'insert into ['+@Targetdb+'].[dbo].[Member of]'+
'([User Id],[Role ID],[Company])'+
' values(N'''+@T1+''',N''SUPER'','''')'
print @DynAusdr
exec(@DynAusdr)
FETCH NEXT FROM curManUserList INTO @T1,@T2
end
CLOSE curManUserList
DEALLOCATE curManUserList
end
if object_id(@Targetdb+'.dbo.Windows Login') is not NULL
begin
-- scheint bei 2.00 , 2.60 und 2009 identisch zu sein
print '3'
print object_id(@Targetdb+'.dbo.Windows Login')
set @DynAusdr = 'Truncate table ['+@Targetdb+'].[dbo].[Windows Login]'
print @DynAusdr
exec(@DynAusdr)
set @DynAusdr = 'Truncate table ['+@Targetdb+'].[dbo].[Windows Access Control]'
print @DynAusdr
exec(@DynAusdr)
open curManWindowsLoginList
FETCH NEXT FROM curManWindowsLoginList INTO @T1
WHILE @@FETCH_STATUS = 0
BEGIN
set @T1 = substring(@T1,3,LEN(@T1)-2)
set @DomainName = substring(@T1,1,charindex('\',@T1)-1)
set @DomainUser =substring(@T1,charindex('\',@T1)+1,LEN(@T1)-charindex('\',@T1))
set @DynAusdr = N'wmic useraccount where (name='''+@DomainUser+''' and domain='''+@DomainName+''') get name,sid'
print @DynAusdr
insert into @SIDOutput exec XP_cmdshell @DynAusdr
open curSIDOutput
fetch next from curSIDOutput into @T1
fetch next from curSIDOutput into @T1
set @DomainSID = substring(@T1,charindex(' ',@T1)+2,len(@T1)-charindex(' ',@T1)-4)
set @DynAusdr = 'insert into ['+@Targetdb+'].[dbo].[Windows Login](SID) values('''+@DomainSID+''')'
print @DynAusdr
exec(@DynAusdr)
set @DynAusdr = 'insert into ['+@Targetdb+'].[dbo].[Windows Access Control]'+
'([Login SID],[Role ID],[Company Name]) values('+
''''+@DomainSID+''',N''SUPER'','''')'
print @DynAusdr
exec(@DynAusdr)
close curSIDOutput
Delete from @SIDOutput
FETCH NEXT FROM curManWindowsLoginList INTO @T1
end
CLOSE curManWindowsLoginList
DEALLOCATE curManWindowsLoginList
end
GO