提取当前oracle库中所有表的前10行

悬崖跳舞被人砍 2016-01-26 03:12:35
现有一个需求,需要查询oracle库中所有表的前十行,我的想法是通过游标和动态SQL来查询,自己写了一个语句如下:
DECLARE 
CURSOR cur_tabname
IS
SELECT owner,table_name FROM dba_tables WHERE owner NOT IN ('SYS','TEST','SYSMAN','SYSTEM');
c_1 cur_tabname%ROWTYPE;
BEGIN
FOR c_1 IN cur_tabname LOOP
EXECUTE IMMEDIATE 'select :V1 as 所属用户,:V2 as 表名,*
from :V1||'.'||:V2 WHERE rownum < 11'
USING c_1.owner,c_1.table_name;
END LOOP;
END;

因为对游标与动态SQL一知半解,所以语句只能是自己模仿别人的语句写的。
写出来运行报错如下:

要是我写的语句没有大问题的话,希望大家指出语句的错误。要是语句本身问题很大的话 ,希望大家帮我拟一下语句,或者提供一个思路~谢谢~
...全文
460 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 4 楼 codeck 的回复:

declare
type tb_tbName is table of varchar2(1000);
vtb_tbName tb_tbName;
v_sql varchar2(500);
type p_lines is ref cursor;
vp_line p_lines;
begin
select table_name bulk collect into vtb_tbName from user_tables;
for v_index in vtb_tbName.first .. vtb_tbName.last loop
--dbms_output.put_line( vtb_tbName(v_index));
v_sql:='select * from '||vtb_tbName(v_index)||' where rownum<=10';
execute immediate v_sql ...;
end loop;
end;
---------------execute immediate 替换下面似乎也不行--------------------

Open vp_line for v_sql loop
exit when vp_line%notfound;
fetch vp_line into ..... --- 由于每张表列名都是动态的,进一步处理字符串也很麻烦。
end loop;

写了半天发现做到上面那里卡住了,如果谁有比较简洁的办法输出行,问题应该就解决了。


引用 4 楼 codeck 的回复:

declare
type tb_tbName is table of varchar2(1000);
vtb_tbName tb_tbName;
v_sql varchar2(500);
type p_lines is ref cursor;
vp_line p_lines;
begin
select table_name bulk collect into vtb_tbName from user_tables;
for v_index in vtb_tbName.first .. vtb_tbName.last loop
--dbms_output.put_line( vtb_tbName(v_index));
v_sql:='select * from '||vtb_tbName(v_index)||' where rownum<=10';
execute immediate v_sql ...;
end loop;
end;
---------------execute immediate 替换下面似乎也不行--------------------

Open vp_line for v_sql loop
exit when vp_line%notfound;
fetch vp_line into ..... --- 由于每张表列名都是动态的,进一步处理字符串也很麻烦。
end loop;

写了半天发现做到上面那里卡住了,如果谁有比较简洁的办法输出行,问题应该就解决了。

我做了一个测试,把你的语句修改成这样:
declare
type tb_tbName is table of varchar2(1000);
vtb_tbName tb_tbName;
v_sql varchar2(500);
--type p_lines is ref cursor;
--vp_line p_lines;
begin
select table_name bulk collect into vtb_tbName from dba_tables WHERE owner = 'TEST';
for v_index in vtb_tbName.first .. vtb_tbName.last loop
--dbms_output.put_line( vtb_tbName(v_index));
v_sql:='select * from test.'||vtb_tbName(v_index)||' where rownum < 2';
execute immediate v_sql;
end loop;
end;

执行在不到1秒钟的时间就执行好了 ,但是窗口下面没有结果啊~如图:

在我的相像中 是应该有个查询结果才是啊~
PCCYC 2016-01-27
  • 打赏
  • 举报
回复

declare
type tb_tbName is table of varchar2(1000);
vtb_tbName tb_tbName;
v_sql varchar2(500);
type p_lines is ref cursor;
vp_line p_lines;
begin
select table_name bulk collect into vtb_tbName from user_tables;
for v_index in vtb_tbName.first .. vtb_tbName.last loop
   --dbms_output.put_line(  vtb_tbName(v_index));
   v_sql:='select * from '||vtb_tbName(v_index)||' where rownum<=10';
   execute immediate v_sql  ...;
end loop;
end;
---------------execute immediate 替换下面似乎也不行--------------------

   Open vp_line for v_sql loop
     exit when vp_line%notfound;
     fetch vp_line into  .....  --- 由于每张表列名都是动态的,进一步处理字符串也很麻烦。
   end loop;   
写了半天发现做到上面那里卡住了,如果谁有比较简洁的办法输出行,问题应该就解决了。
lhdz_bj 2016-01-27
  • 打赏
  • 举报
回复
引用 5 楼 kingofluo 的回复:
[quote=引用 4 楼 codeck 的回复:]

declare
type tb_tbName is table of varchar2(1000);
vtb_tbName tb_tbName;
v_sql varchar2(500);
type p_lines is ref cursor;
vp_line p_lines;
begin
select table_name bulk collect into vtb_tbName from user_tables;
for v_index in vtb_tbName.first .. vtb_tbName.last loop
   --dbms_output.put_line(  vtb_tbName(v_index));
   v_sql:='select * from '||vtb_tbName(v_index)||' where rownum<=10';
   execute immediate v_sql  ...;
end loop;
end;
---------------execute immediate 替换下面似乎也不行--------------------

   Open vp_line for v_sql loop
     exit when vp_line%notfound;
     fetch vp_line into  .....  --- 由于每张表列名都是动态的,进一步处理字符串也很麻烦。
   end loop;   
写了半天发现做到上面那里卡住了,如果谁有比较简洁的办法输出行,问题应该就解决了。
引用 4 楼 codeck 的回复:

declare
type tb_tbName is table of varchar2(1000);
vtb_tbName tb_tbName;
v_sql varchar2(500);
type p_lines is ref cursor;
vp_line p_lines;
begin
select table_name bulk collect into vtb_tbName from user_tables;
for v_index in vtb_tbName.first .. vtb_tbName.last loop
   --dbms_output.put_line(  vtb_tbName(v_index));
   v_sql:='select * from '||vtb_tbName(v_index)||' where rownum<=10';
   execute immediate v_sql  ...;
end loop;
end;
---------------execute immediate 替换下面似乎也不行--------------------

   Open vp_line for v_sql loop
     exit when vp_line%notfound;
     fetch vp_line into  .....  --- 由于每张表列名都是动态的,进一步处理字符串也很麻烦。
   end loop;   
写了半天发现做到上面那里卡住了,如果谁有比较简洁的办法输出行,问题应该就解决了。
我做了一个测试,把你的语句修改成这样:
declare
type tb_tbName is table of varchar2(1000);
vtb_tbName tb_tbName;
v_sql varchar2(500);
--type p_lines is ref cursor;
--vp_line p_lines;
begin
select table_name bulk collect into vtb_tbName from dba_tables WHERE owner = 'TEST';
for v_index in vtb_tbName.first .. vtb_tbName.last loop
   --dbms_output.put_line(  vtb_tbName(v_index));
   v_sql:='select * from test.'||vtb_tbName(v_index)||' where rownum < 2';
   execute immediate v_sql;
end loop;
end;
执行在不到1秒钟的时间就执行好了 ,但是窗口下面没有结果啊~如图: 在我的相像中 是应该有个查询结果才是啊~[/quote] 其实,这和上面楼主的方法差不多,只是代码实现不同而已,我说了,这里最大的难题是输出,你可以把语句挨个执行完,但输出就是个问题,因为每张表的字段数不同,每个字段的类型也不同,这个结果的输出是比较繁琐的。 楼主运行完了,每个SQL也执行完了,根本没输出,所以也就没结果,就是这样。
  • 打赏
  • 举报
回复
引用 2 楼 LHDZ_BJ 的回复:
楼主的需求还是有点问题的,每张表的前十行,每张表的字段数,字段类型都不一样,结果的输出都是个问题,所以,这个需求如果真的像楼主写的这样,不好实现。
就像在PL/SQL的一个窗口执行两条select语句(或者更多)一样,分两个窗口输出,我觉得这里可能不是问题。输出上,我也可以在循环里做一个将查询结果导出到平面文件的语句~ 但是该如何查出来哩?可以在一个表数量较少的用户下查查试试看~
lhdz_bj 2016-01-26
  • 打赏
  • 举报
回复
楼主的需求还是有点问题的,每张表的前十行,每张表的字段数,字段类型都不一样,结果的输出都是个问题,所以,这个需求如果真的像楼主写的这样,不好实现。
夜未眠风已息 2016-01-26
  • 打赏
  • 举报
回复
SELECT 'SELECT '''||owner||''' as 所属用户,'''||table_name||''' as 表名,T.* FROM '||owner||'.'||table_name||' T WHERE ROWNUM<10' FROM dba_tables WHERE owner NOT IN ('SYS','TEST','SYSMAN','SYSTEM'); 然后执行拼出来的语句就好啦

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧