动态SQL创建用户声明

时间:2016-02-28 04:18:14

标签: sql-server tsql dynamic-sql

我正在尝试创建一个用户脚本,它将从表中提取用户名并将其放入变量中,但我遇到了一堆错误。这就是我所拥有的。

USE AP
GO

IF EXISTS (SELECT DB_ID('AP'))
        DROP TABLE NewLogins

CREATE TABLE NewLogins
    (LoginName VARCHAR(128))

INSERT INTO NewLogins
VALUES ('BBrown'), ('CChaplin'), ('DDyer'), ('EEbbers')

DECLARE NewLogins CURSOR
STATIC
FOR (SELECT LoginName, SUBSTRING(LoginName, 1, 4) FROM NewLogins)

DECLARE @LoginName VARCHAR(128), @Password VARCHAR(128)

OPEN NewLogins
FETCH NEXT FROM NewLogins
INTO @LoginName, @Password
DECLARE @DropLogin VARCHAR(200)
SET @DropLogin ='DROP LOGIN ' + @LoginName + ''
WHILE(@@FETCH_STATUS = 0)
    BEGIN

        IF EXISTS (SELECT DB_ID('AP'))
            EXEC @DropLogin

        FETCH NEXT FROM NewLogins

        Declare @sqlstmt VARCHAR(200)
        SET @sqlstmt='CREATE LOGIN '+@LoginName +' WITH PASSWORD ='''+ LOWER(@Password) +'9999'''
        PRINT @sqlstmt
        EXEC (@sqlstmt)

        DECLARE @CreateUser VARCHAR(200)
        SET @CreateUser ='CREATE USER '+@LoginName +'FOR LOGIN ' + @LoginName

        DECLARE @AddMemberToGroup VARCHAR(200)
        SET @AddMemberToGroup ='EXEC sp_addrolemember ' + @LoginName +', ' + 'PaymentEntry'

        IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = @LoginName)
            BEGIN
            EXEC @CreateUser
            EXEC @AddMemberToGroup
        END
    END
CLOSE NewLogins
DEALLOCATE NewLogins

出于某种原因,我不断出现错误:

CREATE LOGIN BBrown WITH PASSWORD ='bbro9999'
Msg 15025, Level 16, State 1, Line 3
The server principal 'BBrown' already exists.
Msg 2812, Level 16, State 62, Line 45
Could not find stored procedure 'CREATE USER BBrownFOR LOGIN BBrown'.
Msg 2812, Level 16, State 62, Line 46
Could not find stored procedure 'EXEC sp_addrolemember BBrown, PaymentEntry'.
Msg 2812, Level 16, State 62, Line 28
Could not find stored procedure 'DROP LOGIN BBrown'.

1 个答案:

答案 0 :(得分:4)

首先,您将始终从SELECT DB_ID('AP')获取结果集。该结果集在它返回的一行/列中可能具有NULL值,但它仍然存在,因此使用IF EXISTS会出错。您需要检查IF DB_ID('AP') IS NOT NULL

接下来,您将自己打开SQL注入。您应该非常仔细地研究它,并理解为什么您使用的动态SQL是危险的。

最后,当使用带有动态SQL字符串的EXEC时,需要将其放在大括号中,否则SQL会认为您正在尝试调用存储过程。 EXEC函数和EXEC命令的语法略有不同。所以,你需要EXEC(@CreateUser)