查询Oracle数据库视图中特定文本的所有视图

问题描述 投票:0回答:2

我想知道是否有人有一个查询,可以搜索所有视图以查找特定文本。我们使用的数据库版本是Oracle Database 12c。这只会在我们的开发/测试数据库中运行。

我是公司的新人,对这个数据库结构不熟悉,对使用 Oracle 也不熟悉。我过去只使用过 MSSQL。我找不到数据字典,并且总是不得不询问某些内容的含义或它所在的位置,这让我感觉很糟糕。

在提问之前我试图调查一些。我试图了解所有列的含义以及所有数据的连接位置。我愿意接受其他建议。

对于 SQL,我有一个可以在视图和列中搜索数据的方法,而且速度相当快。我没有确切的时间。但是,我认为这与在 Oracle 中运行它类似,除非数据库与运行类似内容的数据库略有不同,可能不会那么快返回。我发现一些 Oracle 查询可以搜索所有表,但我无权访问任何表。我们如何获得访问权限的过程是:其他用户 > 用户 > 视图 > 然后查询该视图。

我发现这个链接我认为可能有用 - Oracle Search all table all columns for string

当我在接受的答案中运行第一个查询时,出现此错误:

Error report -ORA-00932: inconsistent datatypes: expected - got CHAR
ORA-06512: at line 6
00932. 00000 - "inconsistent datatypes: expected %s got %s"
*Cause:
*Action:"` 

我正在搜索的字符串包含数字和字母。前任。

123ABC

当我运行第二个查询时,我让它运行了四个小时,但仍然没有返回任何结果。有什么办法可以加快速度吗?

我愿意接受任何其他疑问、建议和帮助,为我指明正确的方向。

谢谢!

sql oracle-database oracle12c
2个回答
0
投票

您必须了解,在整个数据库中搜索所有 CHAR (及其变体)数据类型列(因为“123ABC”是一个字符串)是一个繁琐且长时间运行的过程。在几张相对较小的桌子上不需要花时间;但是,在大型数据库上,这确实需要很长时间。您无法使用任何索引,所以......请耐心等待。

另请注意,代码(该链接后面)搜索

ALL_TAB_COLUMNS
视图,该视图不仅包含表的列(由您拥有),还包含您有权访问的所有内容,并且包含各种用户。看看吧;这是我在笔记本电脑上的 11gXE 数据库:

SQL> select owner, count(*) from all_tab_columns group by owner;

OWNER                            COUNT(*)
------------------------------ ----------
MDSYS                                 736
CTXSYS                                320
SYSTEM                                 54
APEX_040000                          3327
SCOTT                                  69
XDB                                    35
SYS                                 15211

7 rows selected.

SQL> select count(*) from user_tab_columns;

  COUNT(*)
----------
        69

SQL>

看到区别了吗?使用

ALL_TAB_COLUMNS
,您将搜索约 20.000 列。在我自己的模式中(和
USER_TAB_COLUMNS
),这只是其中的 70 个。

因此,请考虑切换到

USER_TAB_COLUMNS
(如果这样做,请删除所有
OWNER
列引用)。


PL/SQL 过程(在这种情况下(关于您从发布链接的问题中获取的代码),匿名 PL/SQL 块)在结束之前不会显示 任何内容

或者,您可以创建一个“日志”表,一个自治事务存储过程(以便您可以插入日志表和

commit
),以便您可以“跟踪”另一个会话的执行。像这样的东西:

日志表和过程:

SQL> create table search_log (table_name varchar2(30), column_name varchar2(30));

Table created.

SQL> create or replace procedure p_log (par_table_name in varchar2,
  2                                     par_column_name in varchar2)
  3  is
  4    pragma autonomous_transaction;
  5  begin
  6    insert into search_log (table_name, column_name)
  7      values (par_table_name, par_column_name);
  8    commit;
  9  end;
 10  /

Procedure created.

您发布的链接中的代码;切换到

USER_TAB_COLUMNS
,搜索包含
'KING'
字符串的表/列:

SQL> DECLARE
  2    match_count integer;
  3    v_search_string varchar2(4000) := 'KING';
  4  BEGIN
  5    FOR t IN (SELECT table_name, column_name
  6              FROM user_tab_columns
  7              WHERE data_type like '%CHAR%'
  8             )
  9    LOOP
 10      EXECUTE IMMEDIATE
 11        'SELECT COUNT(*) FROM '|| t.table_name||
 12        ' WHERE '||t.column_name||' = :1'
 13         INTO match_count
 14        USING v_search_string;
 15      IF match_count > 0 THEN
 16        --dbms_output.put_line( t.owner || '.' || t.table_name ||' '||t.column_name||' '||match_count );
 17        p_log(t.table_name, t.column_name);
 18      END IF;
 19    END LOOP;
 20  END;
 21  /

PL/SQL procedure successfully completed.

SQL> select * From search_log;

TABLE_NAME                     COLUMN_NAME
------------------------------ ------------------------------
EMP                            ENAME

SQL>

仅找到一张桌子;

EMP
及其
ENAME
列。


0
投票

此 PL/SQL 脚本迭代指定模式中的所有视图,并在视图定义中搜索给定文本或关键字。它使用 DBMS_METADATA.GET_DDL 提取每个视图的 DDL,并使用 DBMS_LOB.INSTR 执行不区分大小写的搜索。此方法有助于通过利用 CLOB 输出来解决处理 LONG 数据类型的问题,从而允许更直接的文本处理。将 &owner 替换为架构名称,将 &inputtext 替换为您要搜索的关键字。

-- To search for text in view definition
 
DECLARE
    v_view_name VARCHAR2(200); 
    v_ddl       CLOB;          
BEGIN
    -- Loop through all views in a given schema
    FOR rec IN (SELECT view_name FROM all_views WHERE owner = '&owner' ORDER BY view_name) LOOP
        v_view_name := rec.view_name;
        
        v_ddl := DBMS_METADATA.GET_DDL('VIEW', v_view_name);
        
        -- INPUT THE SEARCH STRING/KEYWORD BELOW
        IF DBMS_LOB.INSTR(UPPER(v_ddl), UPPER('&inputtext')) > 0 THEN
 
          DBMS_OUTPUT.PUT_LINE('View Name: ' || v_view_name);
          --DBMS_OUTPUT.PUT_LINE('DDL: ' || TO_CHAR(v_ddl));
          --DBMS_OUTPUT.PUT_LINE('--------------------------------------------');
        
        END IF;
    END LOOP;
END;
/
© www.soinside.com 2019 - 2024. All rights reserved.