#1 楼
注意:下面的脚本实际上并没有设置任何权限,它只是创建可以复制并粘贴到新查询中的脚本,然后可以在执行之前对其进行编辑。下面的脚本将帮助您将一个用户的权限复制/克隆到另一用户:
--- To copy permissions of one user/role to another user/role.
USE database_name -- Use the database from which you want to extract the permissions
GO
SET NOCOUNT ON
DECLARE @OldUser sysname, @NewUser sysname
SET @OldUser = 'userOLD' --The user or role from which to copy the permissions from
SET @NewUser = 'userNEW' --The user or role to which to copy the permissions to
SELECT 'USE' + SPACE(1) + QUOTENAME(DB_NAME()) AS '--Database Context'
SELECT '--Cloning permissions from' + SPACE(1) + QUOTENAME(@OldUser) + SPACE(1) + 'to' + SPACE(1) + QUOTENAME(@NewUser) AS '--Comment'
SELECT 'EXEC sp_addrolemember @rolename ='
+ SPACE(1) + QUOTENAME(USER_NAME(rm.role_principal_id), '''') + ', @membername =' + SPACE(1) + QUOTENAME(@NewUser, '''') AS '--Role Memberships'
FROM sys.database_role_members AS rm
WHERE USER_NAME(rm.member_principal_id) = @OldUser
ORDER BY rm.role_principal_id ASC
SELECT CASE WHEN perm.state <> 'W' THEN perm.state_desc ELSE 'GRANT' END
+ SPACE(1) + perm.permission_name + SPACE(1) + 'ON ' + QUOTENAME(SCHEMA_NAME(obj.schema_id)) + '.' + QUOTENAME(obj.name)
+ CASE WHEN cl.column_id IS NULL THEN SPACE(0) ELSE '(' + QUOTENAME(cl.name) + ')' END
+ SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> 'W' THEN SPACE(0) ELSE SPACE(1) + 'WITH GRANT OPTION' END AS '--Object Level Permissions'
FROM sys.database_permissions AS perm
INNER JOIN
sys.objects AS obj
ON perm.major_id = obj.[object_id]
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
LEFT JOIN
sys.columns AS cl
ON cl.column_id = perm.minor_id AND cl.[object_id] = perm.major_id
WHERE usr.name = @OldUser
ORDER BY perm.permission_name ASC, perm.state_desc ASC
SELECT CASE WHEN perm.state <> 'W' THEN perm.state_desc ELSE 'GRANT' END
+ SPACE(1) + perm.permission_name + SPACE(1)
+ SPACE(1) + 'TO' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> 'W' THEN SPACE(0) ELSE SPACE(1) + 'WITH GRANT OPTION' END AS '--Database Level Permissions'
FROM sys.database_permissions AS perm
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
WHERE usr.name = @OldUser
AND perm.major_id = 0
ORDER BY perm.permission_name ASC, perm.state_desc ASC
#2 楼
这是Pavel Pawlowski编写的一个非常不错的脚本,可以完成这项工作:http://www.pawlowski.cz/2011/03/cloning-user-rights-database/
主要优点:
脚本/副本角色成员身份
脚本/副本对象级别权限
脚本/副本数据库级别权限
我不是该脚本的作者。该脚本是从Pavel Pawlowski博客上的此链接复制粘贴的,请参阅该链接以获取有关如何使用该脚本的更多信息。
USE [master]
GO
--============================================
-- Author: Pavel Pawlowski
-- Created: 2010/04/16
-- Description: Copies rights of old user to new user
--==================================================
CREATE PROCEDURE sp_CloneRights (
@oldUser sysname, --Old user from which to copy right
@newUser sysname, --New user to which copy rights
@printOnly bit = 1, --When 1 then only script is printed on screen, when 0 then also script is executed, when NULL, script is only executed and not printed
@NewLoginName sysname = NULL --When a NewLogin name is provided also a creation of user is part of the final script
)
AS
BEGIN
SET NOCOUNT ON
CREATE TABLE #output (
command nvarchar(4000)
)
DECLARE
@command nvarchar(4000),
@sql nvarchar(max),
@dbName nvarchar(128),
@msg nvarchar(max)
SELECT
@sql = N'',
@dbName = QUOTENAME(DB_NAME())
IF (NOT EXISTS(SELECT 1 FROM sys.database_principals where name = @oldUser))
BEGIN
SET @msg = 'Source user ' + QUOTENAME(@oldUser) + ' doesn''t exists in database ' + @dbName
RAISERROR(@msg, 11,1)
RETURN
END
INSERT INTO #output(command)
SELECT '--Database Context' AS command UNION ALL
SELECT 'USE' + SPACE(1) + @dbName UNION ALL
SELECT 'SET XACT_ABORT ON'
IF (ISNULL(@NewLoginName, '') <> '')
BEGIN
SET @sql = N'USE ' + @dbName + N';
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name = @newUser)
BEGIN
INSERT INTO #output(command)
SELECT ''--Create user'' AS command
INSERT INTO #output(command)
SELECT
''CREATE USER '' + QUOTENAME(@NewUser) + '' FOR LOGIN '' + QUOTENAME(@NewLoginName) +
CASE WHEN ISNULL(default_schema_name, '''') <> '''' THEN '' WITH DEFAULT_SCHEMA = '' + QUOTENAME(dp.default_schema_name)
ELSE ''''
END AS Command
FROM sys.database_principals dp
INNER JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE dp.name = @OldUser
END'
EXEC sp_executesql @sql, N'@OldUser sysname, @NewUser sysname, @NewLoginName sysname', @OldUser = @OldUser, @NewUser = @NewUser, @NewLoginName=@NewLoginName
END
INSERT INTO #output(command)
SELECT '--Cloning permissions from' + SPACE(1) + QUOTENAME(@OldUser) + SPACE(1) + 'to' + SPACE(1) + QUOTENAME(@NewUser)
INSERT INTO #output(command)
SELECT '--Role Memberships' AS command
SET @sql = N'USE ' + @dbName + N';
INSERT INTO #output(command)
SELECT ''EXEC sp_addrolemember @rolename =''
+ SPACE(1) + QUOTENAME(USER_NAME(rm.role_principal_id), '''''''') + '', @membername ='' + SPACE(1) + QUOTENAME(@NewUser, '''''''') AS command
FROM sys.database_role_members AS rm
WHERE USER_NAME(rm.member_principal_id) = @OldUser
ORDER BY rm.role_principal_id ASC'
EXEC sp_executesql @sql, N'@OldUser sysname, @NewUser sysname', @OldUser = @OldUser, @NewUser = @NewUser
INSERT INTO #output(command)
SELECT '--Object Level Permissions'
SET @sql = N'USE ' + @dbName + N';
INSERT INTO #output(command)
SELECT CASE WHEN perm.state <> ''W'' THEN perm.state_desc ELSE ''GRANT'' END
+ SPACE(1) + perm.permission_name + SPACE(1) + ''ON '' + QUOTENAME(USER_NAME(obj.schema_id)) + ''.'' + QUOTENAME(obj.name)
+ CASE WHEN cl.column_id IS NULL THEN SPACE(0) ELSE ''('' + QUOTENAME(cl.name) + '')'' END
+ SPACE(1) + ''TO'' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> ''W'' THEN SPACE(0) ELSE SPACE(1) + ''WITH GRANT OPTION'' END
FROM sys.database_permissions AS perm
INNER JOIN
sys.objects AS obj
ON perm.major_id = obj.[object_id]
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
LEFT JOIN
sys.columns AS cl
ON cl.column_id = perm.minor_id AND cl.[object_id] = perm.major_id
WHERE usr.name = @OldUser
ORDER BY perm.permission_name ASC, perm.state_desc ASC'
EXEC sp_executesql @sql, N'@OldUser sysname, @NewUser sysname', @OldUser = @OldUser, @NewUser = @NewUser
INSERT INTO #output(command)
SELECT N'--Database Level Permissions'
SET @sql = N'USE ' + @dbName + N';
INSERT INTO #output(command)
SELECT CASE WHEN perm.state <> ''W'' THEN perm.state_desc ELSE ''GRANT'' END
+ SPACE(1) + perm.permission_name + SPACE(1)
+ SPACE(1) + ''TO'' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> ''W'' THEN SPACE(0) ELSE SPACE(1) + ''WITH GRANT OPTION'' END
FROM sys.database_permissions AS perm
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
WHERE usr.name = @OldUser
AND perm.major_id = 0
ORDER BY perm.permission_name ASC, perm.state_desc ASC'
EXEC sp_executesql @sql, N'@OldUser sysname, @NewUser sysname', @OldUser = @OldUser, @NewUser = @NewUser
DECLARE cr CURSOR FOR
SELECT command FROM #output
OPEN cr
FETCH NEXT FROM cr INTO @command
SET @sql = ''
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@printOnly IS NOT NULL)
PRINT @command
SET @sql = @sql + @command + CHAR(13) + CHAR(10)
FETCH NEXT FROM cr INTO @command
END
CLOSE cr
DEALLOCATE cr
IF (@printOnly IS NULL OR @printOnly = 0)
EXEC (@sql)
DROP TABLE #output
END
GO
EXECUTE sp_ms_marksystemobject 'dbo.sp_CloneRights'
GO
#3 楼
在对象资源管理器中右键单击数据库
任务->生成脚本...
选择“仅用户”部分并按原样完成向导
注意:最终,您将获得用于所有用户创建的脚本,并且他们的角色几乎已准备就绪。
,但是即使您选择“脚本对象级权限”为true,也不会为授予存储过程的执行权限创建脚本。
评论
它不会工作:它将不会生成脚本来授权执行存储过程
–最大
16-2-2在14:25
是的,你是对的。我添加了一些说明
–伊曼
16年3月3日在13:20
#4 楼
基于@ Kin-shah的出色回答,我编写了一个脚本,该脚本可以在一个sql服务器实例中复制所有数据库的权限。如果您有许多用户和许多数据库,它的可读性会差很多,但可能会派上用场:USE master
GO
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.ROUTINES r WHERE r.ROUTINE_NAME = 'clone_user')
DROP PROCEDURE clone_user
GO
CREATE PROCEDURE clone_user @database sysname, @OldUser sysname, @NewUser sysname AS BEGIN
DECLARE @sql nvarchar(max)
SET @sql = '
USE '+@database+'
DECLARE @database sysname = '''+@database+'''
DECLARE @OldUser sysname = '''+@OldUser+'''
DECLARE @NewUser sysname = '''+@NewUser+'''
SET NOCOUNT ON
SELECT ''EXEC sp_addrolemember @rolename =''
+ SPACE(1) + QUOTENAME(USER_NAME(rm.role_principal_id), '''''''') + '', @membername ='' + SPACE(1) + QUOTENAME(@NewUser, '''''''') AS ''--Role Memberships''
INTO #roles
FROM sys.database_role_members AS rm
WHERE USER_NAME(rm.member_principal_id) = @OldUser
ORDER BY rm.role_principal_id ASC
SELECT CASE WHEN perm.state <> ''W'' THEN perm.state_desc ELSE ''GRANT'' END
+ SPACE(1) + perm.permission_name + SPACE(1) + ''ON '' + QUOTENAME(USER_NAME(obj.schema_id)) + ''.'' + QUOTENAME(obj.name)
+ CASE WHEN cl.column_id IS NULL THEN SPACE(0) ELSE ''('' + QUOTENAME(cl.name) + '')'' END
+ SPACE(1) + ''TO'' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> ''W'' THEN SPACE(0) ELSE SPACE(1) + ''WITH GRANT OPTION'' END AS ''--Object Level Permissions''
INTO #grant1
FROM sys.database_permissions AS perm
INNER JOIN
sys.objects AS obj
ON perm.major_id = obj.[object_id]
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
LEFT JOIN
sys.columns AS cl
ON cl.column_id = perm.minor_id AND cl.[object_id] = perm.major_id
WHERE usr.name = @OldUser
ORDER BY perm.permission_name ASC, perm.state_desc ASC
SELECT CASE WHEN perm.state <> ''W'' THEN perm.state_desc ELSE ''GRANT'' END
+ SPACE(1) + perm.permission_name + SPACE(1)
+ SPACE(1) + ''TO'' + SPACE(1) + QUOTENAME(@NewUser) COLLATE database_default
+ CASE WHEN perm.state <> ''W'' THEN SPACE(0) ELSE SPACE(1) + ''WITH GRANT OPTION'' END AS ''--Database Level Permissions''
INTO #grant2
FROM sys.database_permissions AS perm
INNER JOIN
sys.database_principals AS usr
ON perm.grantee_principal_id = usr.principal_id
WHERE usr.name = @OldUser
AND perm.major_id = 0
ORDER BY perm.permission_name ASC, perm.state_desc ASC
IF EXISTS (SELECT * FROM #roles UNION ALL SELECT * FROM #grant1 UNION ALL SELECT * FROM #grant2) BEGIN
SELECT ''USE ''+@database AS ''-- '+@database+'/'+@OldUser+''' INTO #tmp
SELECT * FROM #tmp UNION ALL SELECT * FROM #roles UNION ALL SELECT * FROM #grant1 UNION ALL SELECT * FROM #grant2
END
'
EXECUTE sp_executesql @sql
END
GO
EXEC sp_MSforeachdb 'EXECUTE [dbo].[clone_user] ?, ''OldUser'', ''NewUser'''
DROP PROCEDURE clone_user
评论
@sweetritz如果有用于克隆用户的GUI,则无需询问问题,因为您只需按一下按钮即可。没有。仅仅因为您“不擅长代码”就不能成为没有学会变得更好的借口...
–亚伦·伯特兰(Aaron Bertrand)
2014年5月6日14:47
不要仅仅局限于使用GUI。 GUI对新手有好处,但有一定局限性。对于您的任务,上述脚本只会生成可用于创建/克隆用户的实际脚本。
–金沙(Kin Shah)
2014年5月6日14:48
感谢亚伦的建议:)和@Kin感谢您的帮助,这真的是一个快速的回复,非常感谢:) :)
–sweetritz
2014年5月6日在16:22
我认为需要明确的是,运行上面的脚本实际上并没有设置任何权限,它只是创建了可以复制并粘贴到新查询中的脚本,然后可以在执行之前对其进行编辑。我只是自己使用它,所以效果很好!节省时间!!
–艾伦·费舍尔
2015年10月13日在18:24
@AlanFisher感谢您的评论,并很高兴它对您有所帮助。更新了我的答案以反映您的评论。谢谢 !
–金沙(Kin Shah)
15年10月13日在18:59