一,修改数据库远程登录帐号(当然也可以手工在sql数据库内建设)

use abc

go

exec sp_change_users_login 'update_one','abc_f','abc_f'

go


数据库导入完成后,还有一个地方需要确认,就是一般客户的表格以及存储过程的属主都是默认的dbo,在这种权限下,用户abc_f对表格是具有读写权限的,可以添加删除表格,但是无法更改现有属主为dbo的表格的表结构,对于存储过程,abc_f没有任何读写执行权限,这就可能造成用户程序出现问题。

从原理讲,解决方法有二,扩大数据库用户的权限,或者将这些表格and存储过程的属主修改为abc_f,前种方法涉及安全问题,不允许做此类操作,所以只能使用后种方法。


二,基本修改对象属主的存储过程使用方法如下:

use abc

go

exec sp_changeobjectowner 'tablename','abc_f'

go


三,上述语句只能更改单个对象,无法实现批量修改,不过对于表格,SQL Server自带一个遍历表格的存储过程sp_msforeachtable,对于修改所有表格属主的语句如下:

use abc

go

sp_msforeachtable 'sp_changeobjectowner ''?'',''abc_f'''

go


注意对于引号里面字段需要使用两个单引号来界定。


四,如果客户数据库没有存储过程以及其他对象,完成上述操作后,应该可以发现客户数据库所有表格属主都已经替换为客户的用户,这样就可以对表格作任何修改。如果客户数据库还含有存储过程等其他对象,因为SQL Server本身没有提供类似msforeachprodure的存储过程,所以不能批量修改这类对象。解决办法是使用自己写存储过程来实现,下面代码可以建立一个msforeachobject的存储过程,用于遍历数据库中的各种对象,只需将这段代码放入查询分析器执行即可。

USE MASTER

GO

CREATE proc sp_MSforeachObject

@objectType int=1,

@command1 nvarchar(2000), 

@replacechar nchar(1) = N'?', 

@command2 nvarchar(2000) = null,

   @command3 nvarchar(2000) = null, 

@whereand nvarchar(2000) = null,

@precommand nvarchar(2000) = null, 

@postcommand nvarchar(2000) = null

as

/* This proc returns one or more rows for each table (optionally, matching @where), with each table defaulting to its


own result set */

/* @precommand and @postcommand may be used to force a single result set via a temp table. */


/* Preprocessor won't replace within quotes so have to use str(). */

declare @mscat nvarchar(12)

select @mscat = ltrim(str(convert(int, 0x0002)))


if (@precommand is not null)

exec(@precommand)


/* Defined @isobject for save object type */

Declare @isobject varchar(256)


select @isobject= case @objectType when 1 then 'IsUserTable'

        when 2 then 'IsView'

        when 3 then 'IsTrigger'

        when 4 then 'IsProcedure' 

        when 5 then 'IsDefault'   

        when 6 then 'IsForeignKey'

        when 7 then 'IsScalarFunction'

        when 8 then 'IsInlineFunction'

        when 9 then 'IsPrimaryKey'

        when 10 then 'IsExtendedProc'    

        when 11 then 'IsReplProc'

        when 12 then 'IsRule'

                 end


/* Create the select */

/* Use @isobject variable isstead of IsUserTable string */

EXEC(N'declare hCForEach cursor global for select ''['' + REPLACE(user_name(uid), N'']'', N'']]'') + '']'' + ''.'' + ''['' +


REPLACE(object_name(id), N'']'', N'']]'') + '']'' from dbo.sysobjects o '

       + N' where OBJECTPROPERTY(o.id, ) = 1 '+N' and o.category & ' + @mscat + N' = 0 '

      + @whereand)


declare @retval int

select @retval = @@error

if (@retval = 0)

exec @retval = sp_MSforeach_worker @command1, @replacechar, @command2, @command3


if (@retval = 0 and @postcommand is not null)

exec(@postcommand)


return @retval


GO


五,上段代码是仿制msforeachtable创建的存储过程,可以用于遍历各种对象,使用方法如下:

use abc

go

EXEc sp_MSforeachObject @command1="sp_changeobjectowner '?', 'abc_f'",@objectType=1

go


最后一个参数objectType代表对象类型,1为表格,2为视图,3为触发器,4为存储过程,7可以修改该客户自己定义的函数。

通过此命令可以将各类对象的属主改为客户的数据库账号,则可以解决上述数据库权限问题


收藏于 2009-04-02