0

场景:我正在用 C# 创建一个管理工具,它将在服务器中恢复完整的 sql server 备份并应用事务日志。db上来后。我已经运行了一些如下所示的脚本。

use master
EXEC sp_addlogin '<destsid>', '<sidadmpass>','<dbname>'
use <dbname>
EXEC sp_grantdbaccess '<destsid>'
EXEC sp_addrolemember 'db_owner', '<destsid>'
EXEC sp_change_users_login 'Update_One','<destsid>','<destsid>'
use master
EXEC sp_grantdbaccess '<destsid>'
EXEC sp_addrolemember 'db_owner', '<destsid>'
use msdb
EXEC sp_grantdbaccess '<destsid>'
EXEC     sp_addrolemember 'db_owner', '<destsid>'
use model
EXEC sp_grantdbaccess '<destsid>'
EXEC sp_addrolemember 'db_owner', '<destsid>'
use tempdb
EXEC sp_grantdbaccess '<destsid>'
EXEC sp_addrolemember 'db_owner', '<destsid>'
use master
grant all on xp_cmdshell to <destsid>
EXEC sp_addsrvrolemember '<destsid>', 'serveradmin'
EXEC sp_addsrvrolemember '<destsid>', 'dbcreator'
EXEC sp_addsrvrolemember '<destsid>', 'bulkadmin'
use <dbname>
if object_id('sp_change_sapuser') is not null
    drop procedure sp_change_sapuser 
create procedure sp_change_sapuser @oldid sysname, @newid sysname
as begin
declare @oldid_uid  smallint
declare @newid_uid  smallint    
declare @object     sysname
declare @object_full    nvarchar(999)
set @oldid_uid = user_id(@oldid)
set @newid_uid = user_id(@newid)
if @oldid_uid is not null and @newid_uid is not null
begin
declare object_cursor cursor local for 
select name from sysobjects where((xtype='U' and name <> 'dtproperties') or (xtype='V' and name not in ('syssegments','sysconstraints')) or (xtype='P' and name not like 'dt_%') or (xtype='D' and name not like 'DF__dtpropert%') or (xtype in ('FN','TF','IF'))) and @oldid_uid = uid
open object_cursor
fetch next from object_cursor into @object
while @@fetch_status=0
begin
set @object_full = user_name(@oldid_uid) + '.' + @object
exec sp_changeobjectowner @object_full, @newid
fetch next from object_cursor into @object
end
end
else
if @oldid_uid is null
begin
print '*** old database user does not exist ***'
end
if @newid_uid is null
begin
print '*** new database user does not exist ***'
end
end
exec sp_change_sapuser '<sourcesid>', '<destsid>'
use master
EXEC sp_grantlogin   'AMR\<destsid>adm'
EXEC sp_grantlogin   'AMR\SAPService<dbname>'
EXEC sp_defaultdb    'AMR\<destsid>adm','<dbname>'
EXEC sp_defaultdb    'AMR\SAPService<dbname>','<dbname>'
EXEC sp_addsrvrolemember 'AMR\<destsid>adm',     'sysadmin'
EXEC sp_addsrvrolemember 'AMR\SAPService<dbname>', 'sysadmin'
EXEC xp_sqlagent_proxy_account 'SET', '<servername>', 'SAPMssXPUser',N'<sidadmpass>'
use master
EXEC sp_addlogin '<destsid>', '<sidadmpass>', <dbname>
use <dbname>
EXEC sp_change_users_login 'Update_One','<destsid>','<destsid>'
EXEC sp_grantdbaccess '<destsid>'
EXEC sp_addrolemember 'db_owner', '<destsid>'
use master
EXEC sp_grantdbaccess '<destsid>'
EXEC sp_addrolemember 'db_owner', '<destsid>'
use msdb
EXEC sp_grantdbaccess '<destsid>'
EXEC sp_addrolemember 'db_owner', '<destsid>'
use model
EXEC sp_grantdbaccess '<destsid>'
EXEC sp_addrolemember 'db_owner', '<destsid>'
use tempdb
EXEC sp_grantdbaccess '<destsid>'
EXEC sp_addrolemember 'db_owner', '<destsid>'
use master
grant all on xp_cmdshell to <destsid>
EXEC sp_addsrvrolemember '<destsid>', 'serveradmin'
EXEC sp_addsrvrolemember '<destsid>', 'dbcreator'
EXEC sp_addsrvrolemember '<destsid>', 'bulkadmin'
--EXEC xp_sqlagent_proxy_account 'SET', '<servername>', 'SAPMssXPUser', N'<sidadmpass>'
EXEC sp_grantlogin   '<destsid>adm'
EXEC sp_grantlogin   'SAPService<dbname>'
EXEC sp_defaultdb    '<destsid>adm','<dbname>'
EXEC sp_defaultdb    'SAPService<dbname>','<dbname>'
EXEC sp_addsrvrolemember '<destsid>adm',     'sysadmin'
EXEC sp_addsrvrolemember 'SAPService<dbname>', 'sysadmin'

注意:给出的值将替换为实际值。

在运行这些脚本时,很少有人会抛出异常。但即使某些脚本抛出错误,我也想继续。而且我还删除了 GO(batch terminator),因为我无法将单独的 dll 添加到服务器中。请提出一些想法来解决这个问题。

详细信息:编程语言:C# Db - Sql Server 2005,08

4

2 回答 2

1

你不能错过GOs。对于某些语句(例如CREATE PROCEDURE),重要的是它们存在于自己的单独批次中。

GO是对客户端工具(例如 SSMS)的指令,它应该将前面的文本(返回到前一个GO或脚本的开头,以较晚者为准)作为批处理发送到服务器。因此,如果您通过代码将 SQL 发送到服务器,您应该做同样的事情 - 或者将每个批次存储为单独的文本片段,这样您就不必担心解析文本(考虑多行字符串可能包含单词 GO 的文字)。

对于每个批次(最初在原始脚本中由 s 分隔),您需要通过调用或类似GO方法将其作为单独的批次发送到服务器- 然后用下一批创建一个新对象(或替换现有对象的文本)被执行。ExecuteNonQuerySqlCommand

然后,您可能决定处理来自 C# 代码中 SQL 执行的任何错误,然后开始设置下一批并执行它。

于 2012-11-05T08:41:57.413 回答
0

将每个“部分”包装到它自己的Try/Catch 块中,您的脚本应该能够克服任何错误。如果遇到错误,脚本将直接跳转到下一个“部分”。

此外,根据MSDN:GO (Transact-SQL)

GO 不是 Transact-SQL 语句;它是 sqlcmd 和 osql 实用程序以及 SQL Server Management Studio 代码编辑器识别的命令。

于 2012-11-05T07:46:25.037 回答