如何使用sp_executesql循环dbs

时间:2016-12-16 01:12:12

标签: tsql stored-procedures

跟进问题sp execute code

我想循环存储在游标中的dbs名称列表,我不知道将USE命令集成到sp执行命令有什么用处,因为我需要该语句来防止改变DBS。

我已尝试过以下代码,但sp_executesql在@dbfullname上返回语法错误。 (在了解了更多sp_executesql的定义之后,我认为没有办法添加那个USE命令。那么如何做到这一点呢?任何指针?它是否需要在批处理事务中完成?)

        declare @dbfullname varchar(60)
        declare @name varchar(50)
        DECLARE @userName1 varchar(20)
        DECLARE @userexists bit

        SET @userName1 = 'testUser'

WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @dbfullname = N'MyDb' + @name

        EXEC sp_executesql  N'use @dbfullname; SET @userexists = CASE WHEN EXISTS(SELECT 1 
                                FROM  sys.database_principals
                                WHERE name = @userName1)
                                THEN 1 ELSE 0 
                                   END',
                            N'@userName1 varchar(20), @userExists bit output',
                            @userName1,
                            @userExists output

    END

2 个答案:

答案 0 :(得分:1)

USE不接受变量或表达式,只接受静态数据库名称。

您可以在EXEC之前汇总命令,例如:

set @dbfullname = N'MyDb' + @name;
declare @SQL as NVarChar(1000) = N'use ' + @dbfullname +
  N'; set @userExists = case when exists ...;';
exec SP_ExecuteSQL @SQL, @userName1, @userExists output;

请注意,如果@dbfullname中存在任何顽皮值,则会使您暴露于SQL注入攻击。

答案 1 :(得分:0)

根据Habo ..他的解决方案解决了我的问题..我只是想发布我改变了那些可能不会完全遵循改变的人的内容。注意必须使用nvarchar,因为sp_executesql需要它。

        declare @nsql nvarchar(1000)

        SET @nsql = N'use ' + @dbfullname + N'; SET @userexists = CASE WHEN EXISTS(SELECT 1 ' +
                                ' FROM  sys.database_principals ' +
                                ' WHERE name = @userName1) ' +
                                ' THEN 1 ELSE 0 ' +
                                '   END'

        EXEC sp_executesql @nsql, 
                            N'@userName1 varchar(20), @userExists bit output',
                            @userName1,
                            @userExists output