3

我正在尝试通过下面的匿名块生成一个假脱机文件,以便找出特定表上的视图。

declare
cursor c1 is select view_name,text from users_view;
rt c1%rowtype;
begin
open c1;
loop
fetch c1 into rt;
exit when c1%notfound;
dbms_output.put_line(rt.view_name || '|' || rt.text);
end loop;
end;

当我运行它时,我收到类似“数字或值错误”的错误,但是如果我从光标定义中删除 text(LONG) 列,则该块将通过而没有任何错误。

我知道我们不能在 where 子句中使用 LONG 数据类型,但它是否也不能在游标中获取?如果是,在这种情况下还有什么替代方案?

4

2 回答 2

2

不是直接解决这个long问题,但是如果你想找出哪些视图引用了一个特定的表,而不是搜索视图源,你可以查询数据字典:

select owner, type, name
from all_dependencies
where referenced_type = 'TABLE'
and referenced_owner = user -- or a specific schema
and referenced_name = '<my_table_name>';

这还将列出表上的所有触发器等,因此如果您只对视图感兴趣,您可以添加and type = 'VIEW'.

当然,这可能只是为您提供一个较小的视图列表,以便更详细地检查表是如何被每个视图使用的,但它比手动搜索所有 300 个视图更容易......这可能意味着您不t 需要获取long首先导致问题的超过 32k 个字符的大视图的文本。

于 2013-07-26T19:04:42.303 回答
2

在这种情况下,错误表明您已达到缓冲区限制 -dbms_output.put_line不会处理如此大量的数据。

在更仔细地查看问题之后,这不是dbms_output.put_line问题,还不是问题,正如 Alex Poole 在对您的问题的评论中指出的那样,这是光标问题。所以我建议你使用简单的 Select 语句(答案中的选项#2)。如果您寻求解决方法

create table <<name>> as 
  select view_name
       , to_lob(text) 
   from user_views 

例如,您将能够使用光标,但随后dbms_output.put_line会阻止您

要生成假脱机文件,您至少有两个选项:

  1. 使用UTL_FILE包将数据写入文件。
  2. 让 SQL*PLUS 完成这项工作。例如:

    set feedback off;
    set termout off;
    set colsep "|";
    set long 20000;   -- increase the size if it's not enough
    set heading off;
    set linesize 150; -- increase the size if it's not enough
    
    
    spool <<file path\file name>>
    
    select view_name
         , text
      from user_views
    
    spool off;
    

最后,您的<<file path\file name>>文件中将有类似的输出:

ALL_APPLY_CONFLICT_COLUMNS    |select c.object_owner, 
                              |       c.object_name,
                              |       c.method_name,
                              |       c.resolution_column, c.column_name,
                              |       c.apply_database_link
                              |  from all_tab_columns o, 
                              |       dba_apply_conflict_columns c
                              | where c.object_owner = o.owner
                              |   and c.object_name = o.table_name   
                              |   and c.column_name = o.column_name  
于 2013-07-26T13:42:17.403 回答