/* 测试: 账户test1234 public权限, 默认数据库[CSDN], 没有赋予其它任何权限. 结论:可以实现,你说的功能. */ drop proc P_test go create proc p_test as begin select * from A end go grant exec on P_test to [test1234] go REVOKE VIEW ANY DATABASE FROM [test1234] go exec p_test /* col ---------- 123 123 */
上例中,实际上我[CSDN]数据库中存在两个表,A和B, 存储过程p_test. 但是如果使用test1234通过SSMS登录, 只能看到存储过程p_test, 不能看到具体的A表和B表. 更看不到表结构和表的数据. 但是可以通过 exec p_test抓到A表的数据. 不知道描述清楚没有. grant exec on P_test to [test1234] 表示账户test1234有exec 存储过程p_test的权限. 而 REVOKE VIEW ANY DATABASE FROM [test1234] 表示取消 test1234 查看所有定义的权限. 即使是该用户可以看到p_test,但是也看不到他的脚本是怎么定义的! 上例有点小问题, 修改后发出来.
/* 测试: 账户test1234 public权限, 默认数据库[CSDN], 没有赋予其它任何权限. 结论:可以实现,你说的功能. */ USE [CSDN] --添加数据库.. go drop proc P_test go create proc p_test as begin select * from A end go USE [CSDN] --添加数据库.. go grant exec on P_test to [test1234] go USE [master] --添加master数据库,REVOKE必须在master里面执行,否则会出错, go REVOKE VIEW ANY DATABASE FROM [test1234] go USE [CSDN] --添加数据库.. go exec p_test /* col ---------- 123 123 */
视图应该不支持参数吧,如果客户直接用 select * from 视图名 不就完了?一是看了不该看的数据,二是服务器速度受影响,如果只允许他访问储存过程,我必需要求他传入起止日期、单位编号、验证码等,实际查询时,储存过程会结合索引。而且,视图必须访问表,同样无法解决权限,我现在突然想到类似下面一个东东: select * from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名) 能不能通过类似这种办法在储存过程中指定一个新的用户名、密码,用这个密码执行查询不就行了吗?因为现在在家里,无法实验,上班后再试试
而直接使用SSMS查询select * from A /* Msg 229, Level 14, State 5, Line 1 SELECT permission denied on object 'A', database 'CSDN', schema 'dbo'. */也会报权限错误的. --测试环境: --window xp sp2 select @@version /* Standard Edition 9.00.1406.00 */
问题已经解决了,方法就是我在问题中提到的链接服务器,但只用一台服务器就行了,具体如下: 1、建立一个链接服务器,注意,链接服务器就是自己(我记得在sql server 2000中好象不能和自己建立链接服务器,我用的是sql server 2005,且端口号改为了4000),链接服务器用的登录名为sa 2、新建一个储存过程,假如为p1,该储存过程内容为 select * from table1 3、建立一个储存过程,名称为p2,这个储存过程对外,其内容为: exec [链接服务器名或IP,4000].[数据库名].dbo.p1 并允许用户帐号执行该储存过程大家已经看清楚了,外部调用的是p2储存过程,而p2实际上执行了链接服务器上(当然也就是本身了)的p1,因为是链接服务器,用了sa的帐号进行登录,当然可以访问任何表了,方法虽然难登大雅之堂,但的确解决了问题,如谁有更好办法,欢迎赐教。
发现字太小,放大一点: 问题已经解决了,方法就是我在问题中提到的链接服务器,但只用一台服务器就行了,具体如下: 1、建立一个链接服务器,注意,链接服务器就是自己(我记得在sql server 2000中好象不能和自己建立链接服务器,我用的是sql server 2005,且端口号改为了4000),链接服务器用的登录名为sa 2、新建一个储存过程,假如为p1,该储存过程内容为 select * from table1 3、建立一个储存过程,名称为p2,这个储存过程对外,其内容为: exec [链接服务器名或IP,4000].[数据库名].dbo.p1 并允许用户帐号执行该储存过程 大家已经看清楚了,外部调用的是p2储存过程,而p2实际上执行了链接服务器上(当然也就是本身了)的p1,因为是链接服务器,用了sa的帐号进行登录,当然可以访问任何表了,方法虽然难登大雅之堂,但的确解决了问题,如谁有更好办法,欢迎赐教
/*
测试:
账户test1234
public权限,
默认数据库[CSDN],
没有赋予其它任何权限.
结论:可以实现,你说的功能.
*/
drop proc P_test
go
create proc p_test
as
begin
select * from A
end
go
grant exec on P_test to [test1234]
go
REVOKE VIEW ANY DATABASE FROM [test1234]
go
exec p_test
/*
col
----------
123
123
*/
存储过程p_test.
但是如果使用test1234通过SSMS登录,
只能看到存储过程p_test,
不能看到具体的A表和B表.
更看不到表结构和表的数据.
但是可以通过
exec p_test抓到A表的数据.
不知道描述清楚没有.
grant exec on P_test to [test1234]
表示账户test1234有exec 存储过程p_test的权限.
而
REVOKE VIEW ANY DATABASE FROM [test1234]
表示取消 test1234 查看所有定义的权限.
即使是该用户可以看到p_test,但是也看不到他的脚本是怎么定义的!
上例有点小问题,
修改后发出来.
测试:
账户test1234
public权限,
默认数据库[CSDN],
没有赋予其它任何权限.
结论:可以实现,你说的功能.
*/
USE [CSDN] --添加数据库..
go
drop proc P_test
go
create proc p_test
as
begin
select * from A
end
go
USE [CSDN] --添加数据库..
go
grant exec on P_test to [test1234]
go
USE [master] --添加master数据库,REVOKE必须在master里面执行,否则会出错,
go
REVOKE VIEW ANY DATABASE FROM [test1234]
go
USE [CSDN] --添加数据库..
go
exec p_test
/*
col
----------
123
123
*/
select * from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)
能不能通过类似这种办法在储存过程中指定一个新的用户名、密码,用这个密码执行查询不就行了吗?因为现在在家里,无法实验,上班后再试试
/*
Msg 229, Level 14, State 5, Line 1
SELECT permission denied on object 'A', database 'CSDN', schema 'dbo'.
*/也会报权限错误的.
--测试环境:
--window xp sp2
select @@version
/*
Standard Edition
9.00.1406.00
*/
那就不要担心了. 你只赋予他们EXEC的权限就行了.(其他的权限别多了)
1、建立一个链接服务器,注意,链接服务器就是自己(我记得在sql server 2000中好象不能和自己建立链接服务器,我用的是sql server 2005,且端口号改为了4000),链接服务器用的登录名为sa
2、新建一个储存过程,假如为p1,该储存过程内容为 select * from table1
3、建立一个储存过程,名称为p2,这个储存过程对外,其内容为:
exec [链接服务器名或IP,4000].[数据库名].dbo.p1
并允许用户帐号执行该储存过程大家已经看清楚了,外部调用的是p2储存过程,而p2实际上执行了链接服务器上(当然也就是本身了)的p1,因为是链接服务器,用了sa的帐号进行登录,当然可以访问任何表了,方法虽然难登大雅之堂,但的确解决了问题,如谁有更好办法,欢迎赐教。
问题已经解决了,方法就是我在问题中提到的链接服务器,但只用一台服务器就行了,具体如下:
1、建立一个链接服务器,注意,链接服务器就是自己(我记得在sql server 2000中好象不能和自己建立链接服务器,我用的是sql server 2005,且端口号改为了4000),链接服务器用的登录名为sa
2、新建一个储存过程,假如为p1,该储存过程内容为 select * from table1
3、建立一个储存过程,名称为p2,这个储存过程对外,其内容为:
exec [链接服务器名或IP,4000].[数据库名].dbo.p1
并允许用户帐号执行该储存过程 大家已经看清楚了,外部调用的是p2储存过程,而p2实际上执行了链接服务器上(当然也就是本身了)的p1,因为是链接服务器,用了sa的帐号进行登录,当然可以访问任何表了,方法虽然难登大雅之堂,但的确解决了问题,如谁有更好办法,欢迎赐教
不错.在SQL Server 2000里是可以和自己建链接服务器的.