我正在尝试开发一个脚本,该脚本在运行时将删除以前缀" COMPANY \"开头的所有用户。不属于预授权用户列表的。将运行此脚本以定期扫描以前员工数据库用户帐户的服务器。出于测试目的,下面的脚本仅打印未授权用户的名称,而不是删除它们。我需要为服务器实例上的每个数据库执行此操作,因此我使用的是sp_MSforeachDB。但是,当我运行脚本时,我会收到多个错误,所有错误都是相同的消息:
Error in this script.
Msg 102, Level 15, State 1, Line 57
Incorrect syntax near 'GO'.
当我尝试在sp_MSforeachDB之外运行脚本时,脚本运行正常。因此,对我来说很明显,问题在于在sp_MSforeachDB中执行GO语句。
我在另一篇文章中发现GO不是T-SQL命令,这就是为什么它在sp_MSforeachDB内部时会抛出此错误,但如果我尝试删除GO,则会向我返回几个NULL错误而不是上面的错误:
Error in this script.
Msg 50000, Level 15, State 1, Line 51
Error Number: (null), Severity: (null), State: (null), Line: (null),
(null)
如果我正常运行GO-less语句(不在sp_MSforeachDB中),也会返回此错误。如果我删除脚本中的所有错误处理,它工作正常,但我需要在此脚本中进行错误处理。
所以...我对如何使这项工作感到有点迷茫。不可否认,我对T-SQL中的错误处理很新,并且正在尝试一个例子,所以可能有一些我不知道的东西。想法? sp_MSforeachDB是否有很好的替代方法可以完全不使用存储过程?任何和所有的帮助表示赞赏。
脚本如下。您可以删除GOTO BAGIT和BAGIT:GO以查看NULL错误。
EXECUTE master.sys.sp_MSforeachdb
'USE [?];
/* Declare error-handling variables */
DECLARE @err_no int, @err_severity int, @err_state int, @err_line int, @err_message varchar(4000)
DECLARE @nrows int
/* First pull in list of users who have a COMPANY user name but are not in list of approved users */
DECLARE @Fetch_UsersList_Status INT;
DECLARE @ExecuteSQL_UsersList VARCHAR(2500);
DECLARE @NextUser VARCHAR(250);
DECLARE UsersList CURSOR FOR
SELECT name FROM sys.database_principals
where
name LIKE ''COMPANY\%''
AND
name NOT IN (''COMPANY\User1'',''COMPANY\User2'',''COMPANY\User3'',''COMPANY\User4'',''COMPANY\User5'')
OPEN UsersList
FETCH NEXT FROM UsersList INTO @NextUser
/* Use local variable to store UsersList FETCH_STATUS. This will be used as the condition for the USERDROP WHILE loop */
SET @Fetch_UsersList_Status = @@FETCH_STATUS
/* USERDROP WHILE Loop */
BEGIN TRY
WHILE @Fetch_UsersList_Status = 0
BEGIN
PRINT @NextUser
FETCH NEXT FROM UsersList INTO @NextUser
SET @Fetch_UsersList_Status = @@FETCH_STATUS
END
END TRY
BEGIN CATCH
SELECT @err_no=ERROR_NUMBER(), @err_severity=ERROR_SEVERITY(), @err_state=ERROR_STATE(),
@err_line=ERROR_LINE(), @err_message=ERROR_MESSAGE()
GOTO ERROR_EXIT
END CATCH
CLOSE UsersList
DEALLOCATE UsersList
GOTO BAGIT
ERROR_EXIT:
DECLARE @newline char(1)
SET @newline = CHAR(10)
PRINT ''Error in this script.''
RAISERROR(''Error Number: %d, Severity: %d, State: %d, Line: %d, %s%s'', 15, 1,
@err_no, @err_severity, @err_state, @err_line, @newline, @err_message) WITH LOG
BAGIT:
GO
'