动态SQL只可以查询当前连接用户的表的行数?急寻答案,谢谢!

[复制链接]
查看11 | 回复5 | 2005-10-30 17:05:33 | 显示全部楼层 |阅读模式
以下函数,为什么只能查出当前用户的表的记录数?
我的需求是用一个procedure计算所有Oracle用户所有表的记录数.而数据库里现在有多少用户,是动态改变的.
比如:
该函数如果在scott里创建,通过scott登陆则查询不了system的表;
若在system里创建,通过system登陆,则查询不了scott的表;
我把以下存储过程,使用本地动态SQL实现,现象也如上面所描述的一样.
急寻答案,谢谢!

CREATE OR REPLACE function get_row_cnts(p_tname in varchar2) return number
as
v_the_cursor
int;
v_column_value
number default NULL;
v_status
int;
begin

v_the_cursor := dbms_sql.open_cursor;
dbms_sql.parse(c=>v_the_cursor,statement=>'select count(*) from '||p_tname,language_flag=>dbms_sql.native);
dbms_sql.define_column(c=>v_the_cursor,position=>1,column=>v_column_value);
v_status := dbms_sql.execute(v_the_cursor);
if ( dbms_sql.fetch_rows(c=>v_the_cursor) > 0) then

dbms_sql.column_value(c=>v_the_cursor,position=>1,value=>v_column_value);

end if;

dbms_sql.close_cursor(c=>v_the_cursor);
return v_column_value;
exception
when others then

dbms_output.put_line('=========>'||sqlerrm);

dbms_sql.close_cursor(c=>v_the_cursor);

RAISE;

end;
/


CREATE OR REPLACE PROCEDURE OBJECT_cont
(v_collection_time date)
AS
v_segment_name dba_segments.segment_name%type;
v_owner
dba_segments.owner%type;
v_bytes
number;
v_count
int;
str_tmep
varchar(400);
cursor tab_info is
select segment_name,owner,bytes/1024/1024 from DBA_SEGMENTS where segment_type = 'TABLE';
BEGIN


open tab_info;

loop

fetch tab_info into v_segment_name,v_owner,v_bytes;

exit when tab_info%notfound;



str_tmep := 'select count(*) from c_ynunicom.'||v_segment_name;


EXECUTE IMMEDIATE str_tmepinto v_count;



.......................................................

commit;



end loop;

close tab_info;

END;
/
回复

使用道具 举报

千问 | 2005-10-30 17:05:33 | 显示全部楼层
有了查询不同用户的权限,啥事做不了呢
回复

使用道具 举报

千问 | 2005-10-30 17:05:33 | 显示全部楼层
不行.
因我执行该函数的用户已经是具有dba,sysdba权限的了,而且同样的查询,在func里执行不了,可放在SQLPLUS里可以执行;
经过测试,在 8i 里是不存在问题的,完全可以用; 但在 9i里不行.
回复

使用道具 举报

千问 | 2005-10-30 17:05:33 | 显示全部楼层
你可以以一个用户的身份,给另一个用户授权某个对象,这样应该没问题.dba,sysdba权限不能代表一切哟,
回复

使用道具 举报

千问 | 2005-10-30 17:05:33 | 显示全部楼层
这位仁兄说出了关键的地方,但发现一个现象,请大家斟酌:
1,使用该get_row_cnts函数,如果不做其他权限处理,则只能计算当前连接用户的表的记录数.
2,赋权限dba,sysdba给创建get_row_cnts函数的用户,一样无法使用函数查询其他用户的表的记录数,但是:不使用函数,直接使用SQLPLUS 查询其他用户的表的记录数,是可以的。
3,如果在其他用户模式下,赋予创建get_row_cnts函数的用户在对象上的select权限,则可以使用函数查询该被赋予权限的表的记录数了。
奇怪就奇怪在:
为什么函数必须要明显的赋予select权限才可以查询其他用户下的表的记录数,而不需要明显的赋予select权限是可以在SQLPLUS里查询的呢?
例:
SQL> select get_row_cnts('c_ynunicom.PM_TMSCTREE') from dual;
select get_row_cnts('c_ynunicom.PM_TMSCTREE') from dual
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at "DBMONITOR.GET_ROW_CNTS", line 29

SQL> select count(*) from c_ynunicom.PM_TMSCTREE;
COUNT(*)
----------
2
SQL> show user
USER is "DBMONITOR"
SQL>
此时在另外一个窗口:
SQL> show user
USER is "C_YNUNICOM"
SQL> grant select on c_ynunicom.PM_TMSCTREE to dbmonitor;
Grant succeeded.
SQL> commit;
,此时回到第一个窗口:
SQL> select get_row_cnts('c_ynunicom.PM_TMSCTREE') from dual;
GET_ROW_CNTS('C_YNUNICOM.PM_TMSCTREE')
--------------------------------------

2

靠,居然可以了。郁闷啊。。。。。
回复

使用道具 举报

千问 | 2005-10-30 17:05:33 | 显示全部楼层
问题解决了,经过测试,发现:
1,即使赋予的DBA角色里已拥有select any table的权限,但他还是不能在函数里select其他用户的表。
2,此时显示的conn /as sysdba,grant select any table to XXXX;此时函数可以随便运行了。
哎,角色里的权限居然不能用。。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行