视图的 Oracle 搜索文本

Oracle search text of views

我有超过 1000 个视图,我想 运行 搜索将显示在 SQL 中包含字符串 abc 的视图的名称。如何搜索所有已存储的 procedures/SQL,包括我的观点?当我 运行 命令时:

SELECT *
FROM   all_source
WHERE  text LIKE '%abc%'

它 returns 我的源代码,其中存在字符串 abc。但这不包括视图。

Select ALL_VIEWS 代替(列名也是 TEXT)。

不过,您更愿意使用 UPPERLOWER 函数之一作为

select *
from all_views
where lower(text) like '%abc%'

因为有一次你可能把它写成 'abc',另一次可能写成 'ABC',等等

[编辑,因为 ORA-00932]

哦,是的 - 在 ALL_VIEWS 中,TEXT 列是 LONG 数据类型(而在 ALL_SOURCE 中它是 VARCHAR2,所以 LIKE 不适用于 ALL_VIEWS。

一个选项是创建一个包含所有视图的 "temporary" table 并在 TEXT 列上应用 TO_LOB 函数,然后从中应用 select:

SQL> create or replace view my_emp as select empno, ename xxx_ename, job from emp;

View created.

SQL> create table my_all_views as
  2  select owner, view_name, to_lob(text) text
  3  from all_views;

Table created.

SQL> select owner, view_name
  2  from my_all_views
  3  where lower(text) like '%xxx%';

OWNER                          VIEW_NAME
------------------------------ ------------------------------
SYS                            USER_SCHEDULER_JOB_DESTS
SYS                            ALL_SCHEDULER_JOB_DESTS
SYS                            USER_XML_SCHEMAS
SYS                            ALL_XML_SCHEMAS
SYS                            ALL_XML_SCHEMAS2
SCOTT                          MY_EMP

6 rows selected.

SQL>

它的缺点是不能缩放;如果创建新视图,则必须重新创建 table.

或者,您可以创建自己的函数来执行该搜索。例如:

SQL> create or replace function f_search_view (par_string in varchar2)
  2    return sys.odcivarchar2list
  3    pipelined
  4  is
  5  begin
  6    for cur_r in (select view_name, text from all_views
  7                  where text_length < 32767)
  8    loop
  9      if instr(cur_r.text, par_string) > 0 then
 10         pipe row(cur_r.view_name);
 11      end if;
 12    end loop;
 13
 14    return;
 15  end;
 16  /

Function created.

SQL> select * from table(f_search_view('xxx'));

COLUMN_VALUE
--------------------------------------------------------------------------------
USER_XML_SCHEMAS
ALL_XML_SCHEMAS
ALL_XML_SCHEMAS2
MY_EMP

SQL>

这在 12c 中变得更容易,您可以在其中使用

select *
from   all_views v
where  lower(v.text_vc) like '%abc%';

这假定您要查找的文本字符串在前 4000 个字符中。您还可以让报告包括 text_length 大于 4000 的任何视图以及警告。

在早期版本中(或者为了避免 4000 个字符的限制),您可以尝试这样的 PL/SQL 循环:

begin
    dbms_output.put_line('Owner                          View name');
    dbms_output.put_line('------------------------------ -------------------------------');

    for r in (
        select v.owner, v.view_name, v.text
        from   all_views v
        where  v.owner <> 'SYS'
    )
    loop
        if lower(r.text) like '%abc%' then
            dbms_output.put_line(rpad(r.owner,31) || r.view_name);
        end if;
    end loop;
end;

PL/SQL 将 SQL LONG 值隐式转换为 32K PL/SQL 字符串。

(在我在 12.2.0.1.0 中的测试中,当我的光标包含 SYS.DBA_SCHEDULER_RUNNING_JOBSSYS."_user_stat" 时,select 语句中的 ORA-06502: PL/SQL: numeric or value error 失败了,即使其他带有较长文本的视图已成功处理,我不确定为什么。这可能有一些我没有看到的问题。)