如何在 all_mviews 脚本中搜索关键字?

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

我正在尝试在用于创建materialisd视图的脚本中搜索关键字

CUSTOMER
。我通过搜索表
QUERY
all_mviews
列来完成此操作。所以理论上这个说法

SELECT *
FROM ALL_MVIEWS
WHERE UPPER(QUERY) LIKE '%CUSTOMER%';

应该可以。但是,因为查询不是 CHAR 数据类型,所以我无法执行此操作。我尝试过使用

TO_CHAR(QUERY)
DMBS_LOB.INSTR(QUERY, 'CUSTOMER')
TO_LOB(QUERY)
。似乎什么都不起作用。理想情况下,我想用普通 SQL 而不是 PL/SQL 来完成此操作。

sql oracle clob materialized-views
3个回答
0
投票

您当然可以使用纯 SQL 进行查询,但您将无法摆脱在幕后使用 PL/SQL。那是因为 LONG 只能由 PL/SQL 操作。

要实现此目的,您必须编写一个 PL/SQL 函数来包装相关字典视图(此处为

all_mviews
),将
LONG
数据类型转换为
CLOB
,并发出替换行。然后,您可以使用纯 SQL 查询来查询该函数,并像平常一样对其应用搜索谓词。这是适用于 19c 中可用列的版本:

        CREATE OR REPLACE TYPE dba_mviews_rectype IS OBJECT (
        CONTAINER_NAME  VARCHAR2(128),
        QUERY   CLOB,
        QUERY_LEN   NUMBER,
        UPDATABLE   VARCHAR2(1),
        UPDATE_LOG  VARCHAR2(128),
        MASTER_ROLLBACK_SEG VARCHAR2(128),
        MASTER_LINK VARCHAR2(128),
        REWRITE_ENABLED VARCHAR2(1),
        REWRITE_CAPABILITY  VARCHAR2(9),
        REFRESH_MODE    VARCHAR2(9),
        REFRESH_METHOD  VARCHAR2(8),
        BUILD_MODE  VARCHAR2(9),
        FAST_REFRESHABLE    VARCHAR2(18),
        LAST_REFRESH_TYPE   VARCHAR2(8),
        LAST_REFRESH_DATE   DATE,
        LAST_REFRESH_END_TIME   DATE,
        STALENESS   VARCHAR2(19),
        AFTER_FAST_REFRESH  VARCHAR2(19),
        UNKNOWN_PREBUILT    VARCHAR2(1),
        UNKNOWN_PLSQL_FUNC  VARCHAR2(1),
        UNKNOWN_EXTERNAL_TABLE  VARCHAR2(1),
        UNKNOWN_CONSIDER_FRESH  VARCHAR2(1),
        UNKNOWN_IMPORT  VARCHAR2(1),
        UNKNOWN_TRUSTED_FD  VARCHAR2(1),
        COMPILE_STATE   VARCHAR2(19),
        USE_NO_INDEX    VARCHAR2(1),
        STALE_SINCE DATE,
        NUM_PCT_TABLES  NUMBER,
        NUM_FRESH_PCT_REGIONS   NUMBER,
        NUM_STALE_PCT_REGIONS   NUMBER,
        SEGMENT_CREATED VARCHAR2(3),
        EVALUATION_EDITION  VARCHAR2(128),
        UNUSABLE_BEFORE VARCHAR2(128),
        UNUSABLE_BEGINNING  VARCHAR2(128),
        DEFAULT_COLLATION   VARCHAR2(100),
        ON_QUERY_COMPUTATION    VARCHAR2(1)
        )
        /
        CREATE OR REPLACE TYPE dba_mviews_tabtype IS TABLE OF dba_mviews_rectype
        /
        CREATE OR REPLACE FUNCTION f_dba_mviews_ext (in_owner IN varchar2, in_mview_name IN varchar2)
          RETURN dba_mviews_tabtype PIPELINED
        AS  
          var_cursor binary_integer;
          var_query varchar2(4000);
          res pls_integer;
          tab_desc dbms_sql.desc_tab;
          var_column_count pls_integer;
          rec_dummy_mview dba_mviews_rectype;
          var_owner dba_mviews.owner%TYPE;
          var_mview_name dba_mviews.mview_name%TYPE;
        BEGIN
          var_query := 'SELECT *
                          FROM dba_mviews
                         WHERE owner = :owner
                           AND mview_name = :mview_name';
                           
          var_cursor := dbms_sql.open_cursor;
          dbms_sql.parse(var_cursor,var_query,dbms_sql.native);
          dbms_sql.bind_variable(var_cursor,'owner',in_owner);
          dbms_sql.bind_variable(var_cursor,'mview_name',in_mview_name);
          
          dbms_sql.define_column(var_cursor,1,var_owner,128);
          dbms_sql.define_column(var_cursor,2,var_mview_name,128);
          dbms_sql.define_column(var_cursor,3,rec_dummy_mview.container_name,128);
          dbms_sql.define_column_long(var_cursor,4);

          dbms_sql.define_column(var_cursor,5,rec_dummy_mview.query_len);
          dbms_sql.define_column(var_cursor,6,rec_dummy_mview.updatable,1);
          dbms_sql.define_column(var_cursor,7,rec_dummy_mview.update_log,128);
          dbms_sql.define_column(var_cursor,8,rec_dummy_mview.master_rollback_seg,128);
          dbms_sql.define_column(var_cursor,9,rec_dummy_mview.master_link,128);
          dbms_sql.define_column(var_cursor,10,rec_dummy_mview.rewrite_enabled,1);
          dbms_sql.define_column(var_cursor,11,rec_dummy_mview.rewrite_capability,9);
          dbms_sql.define_column(var_cursor,12,rec_dummy_mview.refresh_mode,9);
          dbms_sql.define_column(var_cursor,13,rec_dummy_mview.refresh_method,8);
          dbms_sql.define_column(var_cursor,14,rec_dummy_mview.build_mode,9);
          dbms_sql.define_column(var_cursor,15,rec_dummy_mview.fast_refreshable,18);
          dbms_sql.define_column(var_cursor,16,rec_dummy_mview.last_refresh_type,8);
          dbms_sql.define_column(var_cursor,17,rec_dummy_mview.last_refresh_date);
          dbms_sql.define_column(var_cursor,18,rec_dummy_mview.last_refresh_end_time);
          dbms_sql.define_column(var_cursor,19,rec_dummy_mview.staleness,19);
          dbms_sql.define_column(var_cursor,20,rec_dummy_mview.after_fast_refresh,19);
          dbms_sql.define_column(var_cursor,21,rec_dummy_mview.unknown_prebuilt,1);
          dbms_sql.define_column(var_cursor,22,rec_dummy_mview.unknown_plsql_func,1);
          dbms_sql.define_column(var_cursor,23,rec_dummy_mview.unknown_external_table,1);
          dbms_sql.define_column(var_cursor,24,rec_dummy_mview.unknown_consider_fresh,1);
          dbms_sql.define_column(var_cursor,25,rec_dummy_mview.unknown_import,1);
          dbms_sql.define_column(var_cursor,26,rec_dummy_mview.unknown_trusted_fd,1);
          dbms_sql.define_column(var_cursor,27,rec_dummy_mview.compile_state,19);
          dbms_sql.define_column(var_cursor,28,rec_dummy_mview.use_no_index,1);
          dbms_sql.define_column(var_cursor,29,rec_dummy_mview.stale_since);
          dbms_sql.define_column(var_cursor,30,rec_dummy_mview.num_pct_tables);
          dbms_sql.define_column(var_cursor,31,rec_dummy_mview.num_fresh_pct_regions);
          dbms_sql.define_column(var_cursor,32,rec_dummy_mview.num_stale_pct_regions);
          dbms_sql.define_column(var_cursor,33,rec_dummy_mview.segment_created,3);
          dbms_sql.define_column(var_cursor,34,rec_dummy_mview.evaluation_edition,128);
          dbms_sql.define_column(var_cursor,35,rec_dummy_mview.unusable_before,128);
          dbms_sql.define_column(var_cursor,36,rec_dummy_mview.unusable_beginning,128);
          dbms_sql.define_column(var_cursor,37,rec_dummy_mview.default_collation,100);
          dbms_sql.define_column(var_cursor,38,rec_dummy_mview.on_query_computation,1);
          
          
          res := dbms_sql.execute(var_cursor);
          
          WHILE dbms_sql.fetch_rows(var_cursor) > 0
          LOOP
            DECLARE
              var_query_clob clob;
              var_offset pls_integer := 0;
              var_buffer_length pls_integer := 32760;
              var_value_length pls_integer := 0;
              var_long_piece long;
              rec_mview dba_mviews_rectype := dba_mviews_rectype(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
            BEGIN
              dbms_sql.column_value(var_cursor,3,rec_mview.container_name);
                      
              dbms_lob.createtemporary(var_query_clob, false, dbms_lob.call);
                
              LOOP
                dbms_sql.column_value_long(c => var_cursor,
                                           position => 4,
                                           length => var_buffer_length,
                                           offset => var_offset,
                                           value => var_long_piece,
                                           value_length => var_value_length);
                                           
                EXIT WHEN var_value_length = 0;
                
                dbms_lob.append(var_query_clob, var_long_piece);
                var_offset := var_offset + var_value_length;
              END LOOP;
              
              rec_mview.query := var_query_clob;
              
          dbms_sql.column_value(var_cursor,5,rec_mview.query_len);
          dbms_sql.column_value(var_cursor,6,rec_mview.updatable);
          dbms_sql.column_value(var_cursor,7,rec_mview.update_log);
          dbms_sql.column_value(var_cursor,8,rec_mview.master_rollback_seg);
          dbms_sql.column_value(var_cursor,9,rec_mview.master_link);
          dbms_sql.column_value(var_cursor,10,rec_mview.rewrite_enabled);
          dbms_sql.column_value(var_cursor,11,rec_mview.rewrite_capability);
          dbms_sql.column_value(var_cursor,12,rec_mview.refresh_mode);
          dbms_sql.column_value(var_cursor,13,rec_mview.refresh_method);
          dbms_sql.column_value(var_cursor,14,rec_mview.build_mode);
          dbms_sql.column_value(var_cursor,15,rec_mview.fast_refreshable);
          dbms_sql.column_value(var_cursor,16,rec_mview.last_refresh_type);
          dbms_sql.column_value(var_cursor,17,rec_mview.last_refresh_date);
          dbms_sql.column_value(var_cursor,18,rec_mview.last_refresh_end_time);
          dbms_sql.column_value(var_cursor,19,rec_mview.staleness);
          dbms_sql.column_value(var_cursor,20,rec_mview.after_fast_refresh);
          dbms_sql.column_value(var_cursor,21,rec_mview.unknown_prebuilt);
          dbms_sql.column_value(var_cursor,22,rec_mview.unknown_plsql_func);
          dbms_sql.column_value(var_cursor,23,rec_mview.unknown_external_table);
          dbms_sql.column_value(var_cursor,24,rec_mview.unknown_consider_fresh);
          dbms_sql.column_value(var_cursor,25,rec_mview.unknown_import);
          dbms_sql.column_value(var_cursor,26,rec_mview.unknown_trusted_fd);
          dbms_sql.column_value(var_cursor,27,rec_mview.compile_state);
          dbms_sql.column_value(var_cursor,28,rec_mview.use_no_index);
          dbms_sql.column_value(var_cursor,29,rec_mview.stale_since);
          dbms_sql.column_value(var_cursor,30,rec_mview.num_pct_tables);
          dbms_sql.column_value(var_cursor,31,rec_mview.num_fresh_pct_regions);
          dbms_sql.column_value(var_cursor,32,rec_mview.num_stale_pct_regions);
          dbms_sql.column_value(var_cursor,33,rec_mview.segment_created);
          dbms_sql.column_value(var_cursor,34,rec_mview.evaluation_edition);
          dbms_sql.column_value(var_cursor,35,rec_mview.unusable_before);
          dbms_sql.column_value(var_cursor,36,rec_mview.unusable_beginning);
          dbms_sql.column_value(var_cursor,37,rec_mview.default_collation);
          dbms_sql.column_value(var_cursor,38,rec_mview.on_query_computation);
            
              PIPE ROW(rec_mview);
            END;
          END LOOP;

          dbms_sql.close_cursor(var_cursor);
          
          RETURN;
        EXCEPTION 
          WHEN OTHERS THEN
            dbms_output.put_line(SQLERRM);

            IF dbms_sql.is_open(var_cursor)
            THEN
              dbms_sql.close_cursor(var_cursor);
            END IF;
            
            RAISE;
        END;
        /

        CREATE OR REPLACE VIEW dba_mviews_ext
        AS
        SELECT v.owner,
               v.mview_name,
               x.*
          FROM dba_mviews v
               CROSS APPLY TABLE(f_dba_mviews_ext(v.owner,v.mview_name)) x
         ORDER BY owner,mview_name
        /
        CREATE OR REPLACE VIEW all_mviews_ext
        AS
        SELECT v.owner,
               v.mview_name,
               x.*
          FROM all_mviews v
               CROSS APPLY TABLE(f_dba_mviews_ext(v.owner,v.mview_name)) x
         ORDER BY owner,mview_name
        /
        CREATE OR REPLACE VIEW user_mviews_ext
        AS
        SELECT USER owner,
               v.mview_name,
               x.*
          FROM user_mviews v
               CROSS APPLY TABLE(f_dba_mviews_ext(USER,v.mview_name)) x
         ORDER BY mview_name
        /

        GRANT select ON DBA_MVIEWS_EXT TO select_catalog_role;
        GRANT select ON ALL_MVIEWS_EXT TO public;
        GRANT select ON USER_MVIEWS_EXT TO public;
        CREATE PUBLIC SYNONYM DBA_MVIEWS_EXT FOR DBA_MVIEWS_EXT;
        CREATE PUBLIC SYNONYM ALL_MVIEWS_EXT FOR ALL_MVIEWS_EXT;
        CREATE PUBLIC SYNONYM USER_MVIEWS_EXT FOR USER_MVIEWS_EXT;

现在您可以简单地使用常规 SQL 进行查询:

SELECT *
  FROM all_mviews_ext
 WHERE UPPER(query) LIKE '%CUSTOMER%'

相同的技术可用于

dba_views
。对于其他更短的
LONG
,永远不会超过 4KB,就像您在
dba_tab_partitions/subpartitions
dba_tab_columns
dba_ind_expressions
等中找到的那样。您可以通过将
LONG
转换为
varchar2(4000)
来简化,这可以通过以下方式完成简单的 PL/SQL 变量赋值,因此不需要
dbms_sql
。该代码要短得多,但适用相同的原则:使用 PL/SQL 转换为可搜索数据类型并使用包装该函数的替换视图。


0
投票

LONG
数据类型在 SQL 中使用时有很多限制,因此您不能直接对
LONG
应用任何函数或使用除 null 测试之外的任何谓词(尽管 Oracle Corporation strongly 建议您将 LONG 列转换为LOB 列至少从版本 8.2(24 年)开始,并且尽快版本 9.2(21 年)开始,但他们仍然在数据字典中保留这种类型)。

但是可以通过 XML 传递此数据类型并反序列化为

CLOB
,这将允许公开
CLOB
的所有 SQL 功能。您可以使用
DBMS_XMLGEN
包来实现此目的。

create view v_test as
select 'some text' as res
from dual
select
  v.owner,
  v.view_name,
  v.text,
  v.text_length
from all_views v
  join xmltable(
    '/ROWSET/ROW'
    passing dbms_xmlgen.getxmltype('
      select view_name, owner, text
      from all_views
      where text is not null')

    columns
      view_name varchar2(200),
      owner varchar2(200),
      text clob
  ) flt
  on v.view_name = flt.view_name
  and v.owner = flt.owner
where flt.text like '%some%text%'
业主 VIEW_NAME 文字 TEXT_LENGTH
FIDDLE_SHCEJNRFMOROSMIQCFFB V_测试 从双
选择“某些文本”作为资源
35

小提琴


0
投票

sys_dburigen 应该为你完成这项工作。 它需要一个 LONG 并将返回一个 CLOB

选择我的所有者 , m.mview_name , sys_dburigen( 所有者 , mview_name, 查询, 'text()').getclob() mview_query_text 来自 all_mviews m

© www.soinside.com 2019 - 2024. All rights reserved.