SQL Server修改数据库对象所有者(Owner)浅析
在SQL Server数据库中如何修改数据库对象(表、视图、存储过程..)的所有者(Owner)呢?一般我们可以使用系统提供的系统存储过程sp_changeobjectowner来修改。 我们先看看sp_changeobjectowner在MSDN的文档介绍吧
更改当前数据库中对象的所有者。
重要提示:此存储过程只针对 Microsoft SQL Server 2000 中可用的对象进行。后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。另请使用 ALTER SCHEMA 或 ALTER AUTHORIZATION。sp_changeobjectowner 同时更改架构和所有者。若要保持与早期版本 SQL Server 的兼容性,如果当前所有者和新所有者拥有的架构名称与它们的数据库用户名相同,则此存储过程将只更改对象所有者。
Transact-SQL 语法约定
语法
sp_changeobjectowner [ @objname = ] 'object' , [ @newowner = ] 'owner'
参数
[ @objname = ] 'object'
当前数据库中现有表、视图、用户定义函数或存储过程的名称。object 是 nvarchar(776),没有默认值。如果架构及其所有者具有相同的名称,则 object 可由现有对象所有者限定,格式为 existing_owner.object。
[ @newowner=] 'owner '
将成为对象的新所有者的安全帐户的名称。owner 的数据类型为 sysname,没有默认值。owner 必须是可访问当前数据库的有效数据库用户、服务器角色、Microsoft Windows 登录名或 Windows 组。如果新所有者是没有对应数据库级主体的 Windows 用户或 Windows 组,则将创建数据库用户。
返回代码值
0(成功)或 1(失败)
注释
sp_changeobjectowner 删除对象中的所有现有权限。在运行 sp_changeobjectowner 之后,必须重新应用要保留的任何权限。因此,建议首先编写现有权限的脚本,然后再运行sp_changeobjectowner。更改了对象的所有权之后,便可使用该脚本重新应用权限。在运行该脚本之前必须在权限脚本中修改对象所有者。有关数据库脚本的详细信息,请参阅编写数据库文档和脚本。
若要更改安全对象的所有者,请使用 ALTER AUTHORIZATION.若要更改架构,请使用 ALTER SCHEMA。
权限
要求具有 db_owner 固定数据库角色的成员身份,或 db_ddladmin 固定数据库角色和 db_securityadmin 固定数据库角色的成员身份,同时还需要对对象具有 CONTROL 权限。
如上MSDN文档所描述的,系统存储过程的使用非常简单,如下所示
use test;
go
exec sp_changeobjectowner '[db_owner].[T1]','dbo';
批量修改数据库对象的所有者(owner)
执行上面存储过程过后,表对象T1的所有者(owner)就从db_owner改为了dbo了。如果一个数据库里面的表对象非常多,那么使用该方法就非常的繁琐了。此时就可以使用sp_MSforeachtable来批量处理该工作。
use test;
go
exec sp_MSforeachtable 'exec sp_changeobjectowner ''?'',''dbo'' '
但是使用sp_MSforeachtable结合系统存储过程sp_changeobjectowner,只能修改数据库里面所有表对象的所有者(owner)。并不能修改视图、存储过程、用户函数的所有者。那么应该如何批量修改存储过程、视图、用户自定义函数的所有者呢? 其实也很简单,自己写个脚本将所有SQL Script脚本生成就OK了
SELECT 'exec sp_changeobjectowner ''' + USER_NAME(uid) +'.' + name + ''', ''dbo'';'
from sys.sysobjects where xtype in ('V','P','F')
网上有个脚本对数据库所有对象所有者进行批量修改,已经相当全面了,在此就不重复造轮子了。
declare tb cursor local for
select 'sp_changeobjectowner ''['+replace(user_name(uid),']',']]')+'].['
+replace(name,']',']]')+']'',''dbo'''
from sysobjects
where xtype in('U','V','P','TR','FN','IF','TF') and status>=0
open tb
declare @s nvarchar(4000)
fetch tb into @s
while @@fetch_status=0
begin
exec(@s)
fetch tb into @s
end
close tb
deallocate tb
go
使用sp_changeobjectowner需要注意的地方
在使用系统函数sp_changeobjectowner时,你都会收到一条提示信息“注意: 更改对象名的任一部分都可能会破坏脚本和存储过程。”,这个是因为系统函数sp_changeobjectowner虽然会修改数据库对象的所有者,但是,在视图、存储过程、用户自定义函数里面,如果你使用了owner.object_name这种写法,系统函数并不能检测到。所以当数据库对象修改过后,就有可能导致部分视图、存储过程出现错误,不太明白上面描述的,可以通过下面的例子理解一下。
USE Test;
GO
CREATE TABLE [db_owner].T1
(
ID INT ,
NAME VARCHAR(20)
);
CREATE VIEW [db_owner].V_T1
AS
SELECT * FROM T1;
CREATE VIEW [db_owner].V_T2
AS
SELECT * FROM db_owner.T1;
CREATE PROCEDURE PRC_TEST_ONE
AS
SELECT * FROM T1;
GO
CREATE PROCEDURE PRC_TEST_TWO
AS
SELECT * FROM db_owner.T1;
GO
修改了表T1的所有者后,视图[db_owner].V_T2、存储过程PRC_TEST_TWO都会报错。 如下截图所示。这也就是提示信息“注意: 更改对象名的任一部分都可能会破坏脚本和存储过程。”所描述的情况。
exec sp_changeobjectowner 'db_owner.T1', 'dbo';
如果存在对应表的同义词,那么使用系统存储过程sp_changeobjectowner修改对象的所有者是会报错的。
CREATE TABLE [db_owner].T1
(
ID INT ,
NAME VARCHAR(20)
)
CREATE SYNONYM T1
FOR [db_owner].T1
GO
exec sp_changeobjectowner 'db_owner.T1', 'dbo';
sp_changeobjectowner这个系统存储过程的定义如下所示:
CREATE PROCEDURE Sp_changeobjectowner @objname NVARCHAR(517),
-- may be "[owner].[object]"
@newowner SYSNAME
-- must be entry from sysusers
AS
SET nocount ON
SET ansi_padding ON
DECLARE @objid INT,
@newuid SMALLINT
-- CHECK PERMISSIONS: Because changing owner changes both schema and
-- permissions, the caller must be one of:
-- (1) db_owner
-- (2) db_ddladmin AND db_securityadmin
IF ( Is_member('db_owner') = 0 )
AND ( Is_member('db_securityadmin') = 0
OR Is_member('db_ddladmin') = 0 )
BEGIN
RAISERROR(15247,-1,-1)
RETURN ( 1 )
END
-- RESOLVE OBJECT NAME (CANNOT BE A CHILD OBJECT: TRIGGER/CONSTRAINT) --
SELECT @objid = Object_id(@objname, 'local')
IF ( @objid IS NULL )
OR (SELECT parent_obj
FROM sysobjects
WHERE id = @objid) <> 0
OR Objectproperty(@objid, 'IsMSShipped') = 1
OR Objectproperty(@objid, 'IsSystemTable') = 1
OR Objectproperty(@objid, 'ownerid') IN ( 0, 3, 4 )
OR --public, INFORMATION_SCHEMA, system_function_schema
-- Check for Dependencies: No RENAME or CHANGEOWNER of OBJECT when exists:
EXISTS (SELECT *
FROM sysdepends d
WHERE d.depid = @objid -- A dependency on this object
AND d.deptype > 0 -- that is enforced
AND @objid <> d.id
-- that isn't a self-reference (self-references don't use object name)
AND @objid <>
-- And isn't a reference from a child object (also don't use object name)
(SELECT o.parent_obj
FROM sysobjects o
WHERE o.id = d.id))
BEGIN
-- OBJECT NOT FOUND
RAISERROR(15001,-1,-1,@objname)
RETURN 1
END
-- RESOLVE NEW OWNER NAME (ATTEMPT ADDING IMPLICIT ROW FOR NT NAME) --
-- Disallow aliases, and public cannot own objects --
SELECT @newuid = uid
FROM sysusers
WHERE NAME = @newowner
AND isaliased = 0
AND uid NOT IN ( 0, 3, 4 )
--public, INFORMATION_SCHEMA, system_function_schema
IF @newuid IS NULL
BEGIN
EXECUTE Sp_msadduser_implicit_ntlogin
@newowner
SELECT @newuid = uid
FROM sysusers
WHERE NAME = @newowner
AND isaliased = 0
AND NAME <> 'public'
END
IF @newuid IS NULL
BEGIN
RAISERROR(15410,-1,-1,@newowner)
RETURN ( 1 )
END
-- CHECK IF CHANGING OWNER OF OBJECT OR ITS CHILDREN WOULD PRODUCE A DUPLICATE
IF EXISTS (SELECT *
FROM sysobjects
WHERE uid = @newuid
AND NAME IN (SELECT NAME
FROM sysobjects
WHERE id = @objid
OR parent_obj = @objid))
BEGIN
RAISERROR(15505,-1,-1,@objname,@newowner)
RETURN ( 1 )
END
-- DO THE OWNER TRANSFER (WITH A WARNING) --
RAISERROR(15477,-1,-1)
BEGIN TRANSACTION
-- Locks Object and increments schema_ver.
DBCC lockobjectschema(@objname)
-- drop permissions (they'll be incorrect with new owner) --
DELETE syspermissions
WHERE id = @objid
UPDATE sysobjects
SET uid = @newuid
WHERE id = @objid
UPDATE sysobjects
SET uid = @newuid
WHERE parent_obj = @objid
COMMIT TRANSACTION
RETURN 0 -- sp_changeobjectowner
go
其他方式修改数据库对象的所有者
使用ALTER SCHEMA修改数据库对象的所有者。如下所示:
ALTER SCHEMA dbo TRANSFER db_owner.T1;
GO
SQL Server修改数据库对象所有者(Owner)浅析的更多相关文章
- SQL Server 修改数据库
1. 可视化界面修改数据库 (1)右击数据库,然后选择属性. (2)在工具选项卡中,选择[文件]页,可以更改所有者,文件大小,自增量等参数. 2. 使用ALTER Database修改数据库 (1) ...
- SQL SERVER 修改数据库名称(包括 db.mdf 名称的修改)
刚开始学习SQL SERVER 2005,弄了一个上午修改数据库名,主要是需要修改db.mdf 和db_log.ldf的名字,总算解决了.在这里记下,以后再要修改了就别忘了. 假设原来数据库名为db, ...
- 通过SQL Server 2008数据库复制实现数据库同步备份
SQL Server 2008数据库复制是通过发布/订阅的机制进行多台服务器之间的数据同步,我们把它用于数据库的同步备份.这里的同步备份指的是备份服务器与主服务器进行 实时数据同步,正常情况下只使用主 ...
- 【转】通过SQL Server 2008数据库复制实现数据库同步备份
SQL Server 2008数据库复制是通过发布/订阅的机制进行多台服务器之间的数据同步,我们把它用于数据库的同步备份.这里的同步备份指的是备份服务器与主服务器进行实时数据同步,正常情况下只使用主数 ...
- SQLServer2008修改sa密码的方法与SQL server 2008数据库的备份与还原
sa密码的修改转载自:http://blog.csdn.net/templar1000/article/details/20211191 SQL server 2008数据库的备份与还原转自 :htt ...
- SQL Server 2012 数据库笔记
慕课网 首页 实战 路径 猿问 手记 Python 手记 \ SQL Server 2012 数据库笔记 SQL Server 2012 数据库笔记 2016-10-25 16:29:33 1 ...
- SQL Server中数据库文件的存放方式,文件和文件组
原文地址:http://www.cnblogs.com/CareySon/archive/2011/12/26/2301597.html SQL Server中数据库文件的存放方式,文件和文件组 ...
- C# VS2010结合SQL Server 2008数据库编程实现方法
SQL Server 数据库在C#编程中经常用到,如何实现在具体项目中数据库和具体应用的结合是我们经常遇到的问题,我们这次主要针对如何使用SQL Server 数据库展开,下面是具体的操作以及简单的代 ...
- (5.1)sql server系统数据库
关键词:mssql系统数据库,sql server系统数据库,tempdb的作用 master:它包含一个系统表集合,是整个实例的中央存储库,维护登录账户,其他数据库,文件分布,系统配置设置,磁盘空间 ...
随机推荐
- 跟我学PHP第二篇- 配置Mysql以及PHP WampServer篇(1)
大家好,昨天我给大家介绍了如何去安装ZEND STUDIO,下面昨天文章的链接: http://www.cnblogs.com/kmsfan/p/zendStudio.html 本节为配置的第一部分, ...
- 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)
一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...
- 关于JSON的那些事儿
JSON的那些事儿 曾经有一段时间,XML是互联网上传输结构化数据的事实标准,其突出特点是服务器与服务器间的通信.但是业内不少人认为XML过于繁琐.冗长,后面为了解决这个问题也出现了一些方案,但是由于 ...
- Windows下80端口被pid为4的System进程占用解决方法
前言 之前是Windows 7系统,前段时间装了Windows 10,php环境还没来得及搭建.今天折腾了一下,是用nginx+php,端口是80(已经停止了iis服务),nginx就是起不来,十之八 ...
- .NET 扩展方法 (一)
我还记得刚刚学编程的时候,老师经常会提到一句话:注意空指针.所以经常在某些“入口”位置,进行代码校验,空指针的判断就是其中的一项工作. string类型作为常用的数据类型,它在项目中出现的机率极高,所 ...
- ASP.NET Core开发-如何配置Kestrel 网址Urls
ASP.NET Core中如何配置Kestrel Urls呢,大家可能都知道使用UseUrls() 方法来配置. 今天给介绍全面的ASP.NET Core 配置 Urls,使用多种方式配置Urls. ...
- 【Win10开发】Toast通知——后台激活
前篇文章我们写了关于Toast的前台激活,那么接下来就讲一讲它的后台激活.当通知出现时并不会出现app的界面,但是app能在后台获取到通知中的信息. 关于xaml和Toast通知架构我们在这里就不再赘 ...
- 【Win10开发】绘制静态UI
相信经历过Windows Insider的人对下面这个图都不会陌生,偶然看见邹欣老师领导的微软团队写了篇用xaml绘制这个静态页面,那咱也来亲手实验一番.唔...请做和放宽! 首先我们来看看xaml代 ...
- csharp: .NET Object Relationional Mapper (ORM)- SubSonic
https://github.com/subsonic/SubSonic-3.0 http://subsonic.codeplex.com/ https://code.google.com/archi ...
- php判断数据库中某个字段是否有值去执行excel表格写入操作


