我现在的数据库是SQL SERVER2008,有个普通用户trtest需要执行系统存储过程SP_Monitor,而SP_Monitor中有限制,
if (not (is_srvrolemember('sysadmin') = 1)) -- Make sure that it is the SA executing this.
begin
raiserror(15247,-1,-1)
return(1)
end
对于普通用户trtest,我不想赋予sysadmin权限,所以想问:
1、不改系统存储过程,不赋予sysadmin权限情况下,我如何能达到?
2、如何修改系统存储过程?直接修改提示:
消息 208,级别 16,状态 6,过程 sp_monitor,第 173 行
对象名 'sys.sp_monitor' 无效。
谢谢!
9 个解决方案
#1
较有难度的帖子,在微软的论坛也发了!要求必须用这个名称,sp_monitor!
#2
不能修改2008中的系统存储过程。
楼主,你可以换个思路。虽然不能修改系统存储过程,但可以新建一个存储过程,达到同样的目的。步骤如下:
1、先通过语句:sp_helptext 'sp_monitor' 查看该系统存储过程的源代码
2、新建个存储过程,将步骤1的源代码复制过来,将其中的
这些语句删除。
3、最后将执行新存储过程的权限赋予普通用户trtest即可。
楼主,你可以换个思路。虽然不能修改系统存储过程,但可以新建一个存储过程,达到同样的目的。步骤如下:
1、先通过语句:sp_helptext 'sp_monitor' 查看该系统存储过程的源代码
2、新建个存储过程,将步骤1的源代码复制过来,将其中的
if (not (is_srvrolemember('sysadmin') = 1)) -- Make sure that it is the SA executing this.
begin
raiserror(15247,-1,-1)
return(1)
end
这些语句删除。
3、最后将执行新存储过程的权限赋予普通用户trtest即可。
#3
create procedure sys.sp_monitor
as
if (not (is_srvrolemember('sysadmin') = 1)) -- 改这里?
begin
raiserror(15247,-1,-1)
return(1)
end
/*
** Declare variables to be used to hold current monitor values.
*/
declare @now datetime
declare @cpu_busy int
declare @io_busy int
declare @idle int
declare @pack_received int
declare @pack_sent int
declare @pack_errors int
declare @connections int
declare @total_read int
declare @total_write int
declare @total_errors int
declare @oldcpu_busy int /* used to see if DataServer has been rebooted */
declare @interval int
declare @mspertick int /* milliseconds per tick */
/*
** If we're in a transaction, disallow this since it might make recovery
** impossible.
*/
set implicit_transactions off
if @@trancount > 0
begin
raiserror(15002,-1,-1,'sp_monitor')
return (1)
end
/*
** Set @mspertick. This is just used to make the numbers easier to handle
** and avoid overflow.
*/
select @mspertick = convert(int, @@timeticks / 1000.0)
/*
** Get current monitor values.
*/
select
@now = getdate(),
@cpu_busy = @@cpu_busy,
@io_busy = @@io_busy,
@idle = @@idle,
@pack_received = @@pack_received,
@pack_sent = @@pack_sent,
@connections = @@connections,
@pack_errors = @@packet_errors,
@total_read = @@total_read,
@total_write = @@total_write,
@total_errors = @@total_errors
/*
** Check to see if DataServer has been rebooted. If it has then the
** value of @@cpu_busy will be less than the value of spt_monitor.cpu_busy.
** If it has update spt_monitor.
*/
select @oldcpu_busy = cpu_busy
from master.dbo.spt_monitor
if @oldcpu_busy > @cpu_busy
begin
update master.dbo.spt_monitor
set
lastrun = @now,
cpu_busy = @cpu_busy,
io_busy = @io_busy,
idle = @idle,
pack_received = @pack_received,
pack_sent = @pack_sent,
connections = @connections,
pack_errors = @pack_errors,
total_read = @total_read,
total_write = @total_write,
total_errors = @total_errors
end
/*
** Now print out old and new monitor values.
*/
set nocount on
select @interval = datediff(ss, lastrun, @now)
from master.dbo.spt_monitor
/* To prevent a divide by zero error when run for the first
** time after boot up
*/
if @interval = 0
select @interval = 1
select last_run = lastrun, current_run = @now, seconds = @interval
from master.dbo.spt_monitor
select
cpu_busy = substring(convert(varchar(11),
convert(int, ((@cpu_busy * @mspertick) / 1000)))
+ '('
+ convert(varchar(11), convert(int, (((@cpu_busy - cpu_busy)
* @mspertick) / 1000)))
+ ')'
+ '-'
+ convert(varchar(11), convert(int, ((((@cpu_busy - cpu_busy)
* @mspertick) / 1000) * 100) / @interval))
+ '%',
1, 25),
io_busy = substring(convert(varchar(11),
convert(int, ((@io_busy * @mspertick) / 1000)))
+ '('
+ convert(varchar(11), convert(int, (((@io_busy - io_busy)
* @mspertick) / 1000)))
+ ')'
+ '-'
+ convert(varchar(11), convert(int, ((((@io_busy - io_busy)
* @mspertick) / 1000) * 100) / @interval))
+ '%',
1, 25),
idle = substring(convert(varchar(11),
convert(int, ((convert(bigint,@idle) * @mspertick) / 1000)))
+ '('
+ convert(varchar(11), convert(int, (((@idle - idle)
* @mspertick) / 1000)))
+ ')'
+ '-'
+ convert(varchar(11), convert(int, ((((@idle - idle)
* @mspertick) / 1000) * 100) / @interval))
+ '%',
1, 25)
from master.dbo.spt_monitor
select
packets_received = substring(convert(varchar(11), @pack_received) + '(' +
convert(varchar(11), @pack_received - pack_received) + ')', 1, 25),
packets_sent = substring(convert(varchar(11), @pack_sent) + '(' +
convert(varchar(11), @pack_sent - pack_sent) + ')', 1, 25),
packet_errors = substring(convert(varchar(11), @pack_errors) + '(' +
convert(varchar(11), @pack_errors - pack_errors) + ')', 1, 25)
from master.dbo.spt_monitor
select
total_read = substring(convert(varchar(11), @total_read) + '(' +
convert(varchar(11), @total_read - total_read) + ')', 1, 19),
total_write = substring(convert(varchar(11), @total_write) + '(' +
convert(varchar(11), @total_write - total_write) + ')', 1, 19),
total_errors = substring(convert(varchar(11), @total_errors) + '(' +
convert(varchar(11), @total_errors - total_errors) + ')', 1, 19),
connections = substring(convert(varchar(11), @connections) + '(' +
convert(varchar(11), @connections - connections) + ')', 1, 18)
from master.dbo.spt_monitor
/*
** Now update spt_monitor
*/
update master.dbo.spt_monitor
set
lastrun = @now,
cpu_busy = @cpu_busy,
io_busy = @io_busy,
idle = @idle,
pack_received = @pack_received,
pack_sent = @pack_sent,
connections = @connections,
pack_errors = @pack_errors,
total_read = @total_read,
total_write = @total_write,
total_errors = @total_errors
return (0) -- sp_monitor
#4
ALTER PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'cdc'
AS
SELECT user_name(); -- Shows execution context is set to SqlUser1.
GO
create procedure cdc.sp_monitor
as
select @@SERVERNAME
使用excute as 来提升权限,用不同的架构来封装sp_monitor
#5
Thank you!
主要是,我们的监控上面有调用到这一存储过程,然后搞监控的人不太会调整,所以必须要用这个名字!
就是想不改名字的情况下完成这一的效果!
主要是,我们的监控上面有调用到这一存储过程,然后搞监控的人不太会调整,所以必须要用这个名字!
就是想不改名字的情况下完成这一的效果!
#7
看到了,厉害啊,谢谢啊!
#1
较有难度的帖子,在微软的论坛也发了!要求必须用这个名称,sp_monitor!
#2
不能修改2008中的系统存储过程。
楼主,你可以换个思路。虽然不能修改系统存储过程,但可以新建一个存储过程,达到同样的目的。步骤如下:
1、先通过语句:sp_helptext 'sp_monitor' 查看该系统存储过程的源代码
2、新建个存储过程,将步骤1的源代码复制过来,将其中的
这些语句删除。
3、最后将执行新存储过程的权限赋予普通用户trtest即可。
楼主,你可以换个思路。虽然不能修改系统存储过程,但可以新建一个存储过程,达到同样的目的。步骤如下:
1、先通过语句:sp_helptext 'sp_monitor' 查看该系统存储过程的源代码
2、新建个存储过程,将步骤1的源代码复制过来,将其中的
if (not (is_srvrolemember('sysadmin') = 1)) -- Make sure that it is the SA executing this.
begin
raiserror(15247,-1,-1)
return(1)
end
这些语句删除。
3、最后将执行新存储过程的权限赋予普通用户trtest即可。
#3
create procedure sys.sp_monitor
as
if (not (is_srvrolemember('sysadmin') = 1)) -- 改这里?
begin
raiserror(15247,-1,-1)
return(1)
end
/*
** Declare variables to be used to hold current monitor values.
*/
declare @now datetime
declare @cpu_busy int
declare @io_busy int
declare @idle int
declare @pack_received int
declare @pack_sent int
declare @pack_errors int
declare @connections int
declare @total_read int
declare @total_write int
declare @total_errors int
declare @oldcpu_busy int /* used to see if DataServer has been rebooted */
declare @interval int
declare @mspertick int /* milliseconds per tick */
/*
** If we're in a transaction, disallow this since it might make recovery
** impossible.
*/
set implicit_transactions off
if @@trancount > 0
begin
raiserror(15002,-1,-1,'sp_monitor')
return (1)
end
/*
** Set @mspertick. This is just used to make the numbers easier to handle
** and avoid overflow.
*/
select @mspertick = convert(int, @@timeticks / 1000.0)
/*
** Get current monitor values.
*/
select
@now = getdate(),
@cpu_busy = @@cpu_busy,
@io_busy = @@io_busy,
@idle = @@idle,
@pack_received = @@pack_received,
@pack_sent = @@pack_sent,
@connections = @@connections,
@pack_errors = @@packet_errors,
@total_read = @@total_read,
@total_write = @@total_write,
@total_errors = @@total_errors
/*
** Check to see if DataServer has been rebooted. If it has then the
** value of @@cpu_busy will be less than the value of spt_monitor.cpu_busy.
** If it has update spt_monitor.
*/
select @oldcpu_busy = cpu_busy
from master.dbo.spt_monitor
if @oldcpu_busy > @cpu_busy
begin
update master.dbo.spt_monitor
set
lastrun = @now,
cpu_busy = @cpu_busy,
io_busy = @io_busy,
idle = @idle,
pack_received = @pack_received,
pack_sent = @pack_sent,
connections = @connections,
pack_errors = @pack_errors,
total_read = @total_read,
total_write = @total_write,
total_errors = @total_errors
end
/*
** Now print out old and new monitor values.
*/
set nocount on
select @interval = datediff(ss, lastrun, @now)
from master.dbo.spt_monitor
/* To prevent a divide by zero error when run for the first
** time after boot up
*/
if @interval = 0
select @interval = 1
select last_run = lastrun, current_run = @now, seconds = @interval
from master.dbo.spt_monitor
select
cpu_busy = substring(convert(varchar(11),
convert(int, ((@cpu_busy * @mspertick) / 1000)))
+ '('
+ convert(varchar(11), convert(int, (((@cpu_busy - cpu_busy)
* @mspertick) / 1000)))
+ ')'
+ '-'
+ convert(varchar(11), convert(int, ((((@cpu_busy - cpu_busy)
* @mspertick) / 1000) * 100) / @interval))
+ '%',
1, 25),
io_busy = substring(convert(varchar(11),
convert(int, ((@io_busy * @mspertick) / 1000)))
+ '('
+ convert(varchar(11), convert(int, (((@io_busy - io_busy)
* @mspertick) / 1000)))
+ ')'
+ '-'
+ convert(varchar(11), convert(int, ((((@io_busy - io_busy)
* @mspertick) / 1000) * 100) / @interval))
+ '%',
1, 25),
idle = substring(convert(varchar(11),
convert(int, ((convert(bigint,@idle) * @mspertick) / 1000)))
+ '('
+ convert(varchar(11), convert(int, (((@idle - idle)
* @mspertick) / 1000)))
+ ')'
+ '-'
+ convert(varchar(11), convert(int, ((((@idle - idle)
* @mspertick) / 1000) * 100) / @interval))
+ '%',
1, 25)
from master.dbo.spt_monitor
select
packets_received = substring(convert(varchar(11), @pack_received) + '(' +
convert(varchar(11), @pack_received - pack_received) + ')', 1, 25),
packets_sent = substring(convert(varchar(11), @pack_sent) + '(' +
convert(varchar(11), @pack_sent - pack_sent) + ')', 1, 25),
packet_errors = substring(convert(varchar(11), @pack_errors) + '(' +
convert(varchar(11), @pack_errors - pack_errors) + ')', 1, 25)
from master.dbo.spt_monitor
select
total_read = substring(convert(varchar(11), @total_read) + '(' +
convert(varchar(11), @total_read - total_read) + ')', 1, 19),
total_write = substring(convert(varchar(11), @total_write) + '(' +
convert(varchar(11), @total_write - total_write) + ')', 1, 19),
total_errors = substring(convert(varchar(11), @total_errors) + '(' +
convert(varchar(11), @total_errors - total_errors) + ')', 1, 19),
connections = substring(convert(varchar(11), @connections) + '(' +
convert(varchar(11), @connections - connections) + ')', 1, 18)
from master.dbo.spt_monitor
/*
** Now update spt_monitor
*/
update master.dbo.spt_monitor
set
lastrun = @now,
cpu_busy = @cpu_busy,
io_busy = @io_busy,
idle = @idle,
pack_received = @pack_received,
pack_sent = @pack_sent,
connections = @connections,
pack_errors = @pack_errors,
total_read = @total_read,
total_write = @total_write,
total_errors = @total_errors
return (0) -- sp_monitor
#4
ALTER PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'cdc'
AS
SELECT user_name(); -- Shows execution context is set to SqlUser1.
GO
create procedure cdc.sp_monitor
as
select @@SERVERNAME
使用excute as 来提升权限,用不同的架构来封装sp_monitor
#5
Thank you!
主要是,我们的监控上面有调用到这一存储过程,然后搞监控的人不太会调整,所以必须要用这个名字!
就是想不改名字的情况下完成这一的效果!
主要是,我们的监控上面有调用到这一存储过程,然后搞监控的人不太会调整,所以必须要用这个名字!
就是想不改名字的情况下完成这一的效果!
#6
#7
看到了,厉害啊,谢谢啊!