存储过程中创建Windows登录名的代码为何触发‘登录已存在’错误?
解决登录名已存在时的编译错误问题
问题根源
SQL Server执行代码前会预编译整个批处理,哪怕CREATE LOGIN语句处于不会被执行的IF分支中,只要目标登录名已存在,编译阶段就会检测到冲突,直接抛出“Login already exists”错误,导致整个批处理提前失败,IF判断根本没机会生效。
可行解决方案
方案1:将检查与创建逻辑都放入动态SQL
把存在性检查和创建语句都封装到动态SQL里,这样只有当需要执行创建操作时,才会编译这段代码,避免预编译阶段的冲突检测:
Declare @User varchar(50) Declare @sqlstmt varchar(200) set @User = quotename('JSmith') set @sqlstmt = ' if not exists (select name from sys.syslogins where name = '+ @User +' and isntuser = 1) begin CREATE LOGIN '+ @User +' FROM WINDOWS end' Exec (@sqlstmt)
方案2:用TRY...CATCH捕获并忽略特定错误
直接尝试创建登录,通过异常处理只忽略“登录名已存在”的错误,其他异常正常抛出:
Declare @User varchar(50) Declare @sqlstmt varchar(200) set @User = quotename('JSmith') begin try set @sqlstmt='CREATE LOGIN '+ @User +' FROM WINDOWS' Exec (@sqlstmt) end try begin catch -- 仅忽略登录名已存在的错误(对应错误码15025),其他错误正常抛出 if error_number() <> 15025 begin throw; end end catch
提示:如果不确定环境中的错误码,可手动触发一次“登录名已存在”错误,通过
SELECT ERROR_NUMBER()获取实际编号替换15025。
内容的提问来源于stack exchange,提问作者TheSearcher
相关产品推荐
相关产品推荐

