【问题标题】:Search All Fields In All Tables For A Specific Value (Oracle)在所有表中的所有字段中搜索特定值 (Oracle)
【发布时间】:2021-07-23 08:15:20
【问题描述】:

是否可以在每个表的每个字段中搜索 Oracle 中的特定值?

在某些表中有数百个包含数千行的表,因此我知道这可能需要很长时间才能查询。但我唯一知道的是,我想查询的字段的值是1/22/2008P09RR8

我尝试使用下面的这条语句根据我认为应该命名的列找到合适的列,但它没有返回任何结果。

SELECT * from dba_objects 
WHERE object_name like '%DTN%'

绝对没有关于这个数据库的文档,我不知道这个字段是从哪里提取的。

有什么想法吗?

【问题讨论】:

标签: sql oracle search plsql database-table


【解决方案1】:

Oracle LIKE 条件允许在 SELECT、INSERT、UPDATE 或 DELETE 语句的 WHERE 子句中使用通配符。

%:匹配任意长度的任意字符串

例如-

SELECT last_name
   FROM   customer_tab
   WHERE  last_name LIKE '%A%';

-: 匹配单个字符

例如-

SELECT last_name
   FROM   customer_tab
   WHERE  last_name LIKE 'A_t';

【讨论】:

    【解决方案2】:

    我找到了最好的解决方案,但它有点慢。 (它适用于所有 SQL IDE。)

    SELECT DISTINCT table_name, column_name, data_type
      FROM user_tab_cols,
      TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select '
      || column_name
      || ' from '
      || table_name
      || ' where lower('
      || column_name
      || ') like lower(''%'
      || 'your_text_here'
      || '%'')' ).extract ('ROWSET/ROW/*') ) ) a
      where table_name not in (
        select distinct table_name
          from user_tab_cols where data_type like 'SDO%'
          or data_type like '%LOB') AND DATA_TYPE = 'VARCHAR2'
      order by table_name, column_name;
    

    【讨论】:

    • LONG BINARY 列上中断 :(
    【解决方案3】:

    我在@Lalit Kumars 的回答中遇到了以下问题,

    ORA-19202: Error occurred in XML processing
    ORA-00904: "SUCCESS": invalid identifier
    ORA-06512: at "SYS.DBMS_XMLGEN", line 288
    ORA-06512: at line 1
    19202. 00000 -  "Error occurred in XML processing%s"
    *Cause:    An error occurred when processing the XML function
    *Action:   Check the given error message and fix the appropriate problem
    

    解决办法是:

    WITH  char_cols AS
      (SELECT /*+materialize */ table_name, column_name
       FROM   cols
       WHERE  data_type IN ('CHAR', 'VARCHAR2'))
    SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword",
           SUBSTR (table_name, 1, 14) "Table",
           SUBSTR (column_name, 1, 14) "Column"
    FROM   char_cols,
           TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select "'
           || column_name
           || '" from "'
           || table_name
           || '" where upper("'
           || column_name
           || '") like upper(''%'
           || :val
           || '%'')' ).extract ('ROWSET/ROW/*') ) ) t
    ORDER  BY "Table"
    / 
    

    【讨论】:

      【解决方案4】:

      this Blog post 借用、略微增强和简化以下简单的 SQL 语句似乎可以很好地完成这项工作:

      SELECT DISTINCT (:val) "Search Value", TABLE_NAME "Table", COLUMN_NAME "Column"
      FROM cols,
           TABLE (XMLSEQUENCE (DBMS_XMLGEN.GETXMLTYPE(
             'SELECT "' || COLUMN_NAME || '" FROM "' || TABLE_NAME || '" WHERE UPPER("'
             || COLUMN_NAME || '") LIKE UPPER(''%' || :val || '%'')' ).EXTRACT ('ROWSET/ROW/*')))
      ORDER BY "Table";
      

      【讨论】:

        【解决方案5】:

        修改代码以使用 LIKE 查询不区分大小写搜索,而不是查找完全匹配...

        DECLARE
          match_count INTEGER;
          -- Type the owner of the tables you want to search.
          v_owner VARCHAR2(255) :='USER';
          -- Type the data type you're looking for (in CAPS). Examples include: VARCHAR2, NUMBER, etc.
          v_data_type VARCHAR2(255) :='VARCHAR2';
          -- Type the string you are looking for.
          v_search_string VARCHAR2(4000) :='Test';
        BEGIN
          dbms_output.put_line( 'Starting the search...' );
          FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP
            EXECUTE IMMEDIATE 
            'SELECT COUNT(*) FROM '||t.table_name||' WHERE LOWER('||t.column_name||') LIKE :1'
            INTO match_count
            USING LOWER('%'||v_search_string||'%');
            IF match_count > 0 THEN
              dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count );
            END IF;
          END LOOP;
        END;
        

        【讨论】:

          【解决方案6】:

          我知道这是一个老话题。但我看到有一条评论询问是否可以在 SQL 中完成,而不是使用 PL/SQL。所以想发布一个解决方案。

          下面的演示是给Search for a VALUE in all COLUMNS of all TABLES in an entire SCHEMA:

          • 搜索 CHARACTER 类型

          让我们在SCOTT 架构中查找值KING

          SQL> variable val varchar2(10)
          SQL> exec :val := 'KING'
          
          PL/SQL procedure successfully completed.
          
          SQL> SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword",
            2    SUBSTR (table_name, 1, 14) "Table",
            3    SUBSTR (column_name, 1, 14) "Column"
            4  FROM cols,
            5    TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select '
            6    || column_name
            7    || ' from '
            8    || table_name
            9    || ' where upper('
           10    || column_name
           11    || ') like upper(''%'
           12    || :val
           13    || '%'')' ).extract ('ROWSET/ROW/*') ) ) t
           14  ORDER BY "Table"
           15  /
          
          Searchword  Table          Column
          ----------- -------------- --------------
          KING        EMP            ENAME
          
          SQL>
          
          • 搜索 NUMERIC 类型

          让我们在 SCOTT 架构中查找值 20

          SQL> variable val NUMBER
          SQL> exec :val := 20
          
          PL/SQL procedure successfully completed.
          
          SQL> SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword",
            2    SUBSTR (table_name, 1, 14) "Table",
            3    SUBSTR (column_name, 1, 14) "Column"
            4  FROM cols,
            5    TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select '
            6    || column_name
            7    || ' from '
            8    || table_name
            9    || ' where upper('
           10    || column_name
           11    || ') like upper(''%'
           12    || :val
           13    || '%'')' ).extract ('ROWSET/ROW/*') ) ) t
           14  ORDER BY "Table"
           15  /
          
          Searchword  Table          Column
          ----------- -------------- --------------
          20          DEPT           DEPTNO
          20          EMP            DEPTNO
          20          EMP            HIREDATE
          20          SALGRADE       HISAL
          20          SALGRADE       LOSAL
          
          SQL>
          

          【讨论】:

          • hrmm.... 使用 xml 看起来有点矫枉过正。另外:Error occurred in XML processing ORA-00932: inconsistent datatypes: expected NUMBER got BLOB
          • ORA-19202:在 XML 处理中发生错误 ORA-00932:不一致的数据类型:预期的 CHAR 得到了 BLOB ORA-06512:在“SYS.DBMS_XMLGEN”,第 288 行 ORA-06512:在第 1 行 19202。 00000 - “错误发生在 XML 处理%s” *原因:处理 XML 函数时发生错误 *操作:检查给定的错误消息并修复适当的问题
          • 有什么想法吗? ORA-19202:XML 处理中发生错误 ORA-22813:操作数值超出系统限制 ORA-06512:在“SYS.DBMS_XMLGEN”,第 288 行 ORA-06512:在第 1 行
          【解决方案7】:

          --运行完成--没有错误

              SET SERVEROUTPUT ON SIZE 100000
          
          DECLARE
             v_match_count     INTEGER;
             v_counter         INTEGER;
          
          
          
          
          v_owner           VARCHAR2 (255) := 'VASOA';
          v_search_string   VARCHAR2 (4000) := '99999';
          v_data_type       VARCHAR2 (255) := 'CHAR';
          v_sql             CLOB := '';
          
          BEGIN
             FOR cur_tables
                IN (  SELECT owner, table_name
                        FROM all_tables
                       WHERE     owner = v_owner
                             AND table_name IN (SELECT table_name
                                                  FROM all_tab_columns
                                                 WHERE     owner = all_tables.owner
                                                       AND data_type LIKE
                                                                 '%'
                                                              || UPPER (v_data_type)
                                                              || '%')
                    ORDER BY table_name)
             LOOP
                v_counter := 0;
                v_sql := '';
          
                FOR cur_columns
                   IN (SELECT column_name, table_name
                         FROM all_tab_columns
                        WHERE     owner = v_owner
                              AND table_name = cur_tables.table_name
                              AND data_type LIKE '%' || UPPER (v_data_type) || '%')
                LOOP
                   IF v_counter > 0
                   THEN
                      v_sql := v_sql || ' or ';
                   END IF;
          
                   IF cur_columns.column_name is not null
                   THEN
                      v_sql :=
                            v_sql
                         || 'upper('
                         || cur_columns.column_name
                         || ') ='''
                         || UPPER (v_search_string)||'''';
          
                      v_counter := v_counter + 1;
                   END IF;
          
                END LOOP;
          
                IF v_sql is  null
                THEN
                   v_sql :=
                         'select count(*) from '
                      || v_owner
                      || '.'
                      || cur_tables.table_name;
          
                END IF;
          
                IF v_sql is not null
                THEN
                   v_sql :=
                         'select count(*) from '
                      || v_owner
                      || '.'
                      || cur_tables.table_name
                      || ' where '
                      || v_sql;
                END IF;
          
                --v_sql := 'select count(*) from ' ||v_owner||'.'|| cur_tables.table_name ||' where '||  v_sql;
          
          
                --dbms_output.put_line(v_sql);
                --DBMS_OUTPUT.put_line (v_sql);
          
                EXECUTE IMMEDIATE v_sql INTO v_match_count;
          
                IF v_match_count > 0
                THEN
                  DBMS_OUTPUT.put_line (v_sql);
                  dbms_output.put_line('Match in ' || cur_tables.owner || ': ' || cur_tables.table_name || ' - ' || v_match_count || ' records');
                END IF;
          
             END LOOP;
          EXCEPTION
             WHEN OTHERS
             THEN
                DBMS_OUTPUT.put_line (
                      'Error when executing the following: '
                   || DBMS_LOB.SUBSTR (v_sql, 32600));
          END;
          /
          

          【讨论】:

            【解决方案8】:

            有一些免费工具可以进行此类搜索,例如,这个工具可以正常工作并且源代码可用: https://sites.google.com/site/freejansoft/dbsearch

            您需要 Oracle ODBC 驱动程序和 DSN 才能使用此工具。

            【讨论】:

              【解决方案9】:

              是的,你可以,但你的 DBA 会恨你,并且会发现你把你的鞋子钉在地板上,因为这会导致大量的 I/O,并在缓存清除时降低数据库性能。

              select column_name from all_tab_columns c, user_all_tables u where c.table_name = u.table_name;
              

              开始吧。

              我将从运行查询开始,使用v$sessionv$sqlarea。这根据 oracle 版本而变化。这将缩小空间并且不会击中所有内容。

              【讨论】:

                【解决方案10】:

                如果我们知道表和列的名称,但想找出每个模式中字符串出现的次数:

                Declare
                
                owner VARCHAR2(1000);
                tbl VARCHAR2(1000);
                cnt number;
                ct number;
                str_sql varchar2(1000);
                reason varchar2(1000);
                x varchar2(1000):='%string_to_be_searched%';
                
                cursor csr is select owner,table_name 
                from all_tables where table_name ='table_name';
                
                type rec1 is record (
                ct VARCHAR2(1000));
                
                type rec is record (
                owner VARCHAR2(1000):='',
                table_name VARCHAR2(1000):='');
                
                rec2 rec;
                rec3 rec1;
                begin
                
                for rec2 in csr loop
                
                --str_sql:= 'select count(*) from '||rec.owner||'.'||rec.table_name||' where CTV_REMARKS like '||chr(39)||x||chr(39);
                --dbms_output.put_line(str_sql);
                --execute immediate str_sql
                
                execute immediate 'select count(*) from '||rec2.owner||'.'||rec2.table_name||' where column_name like '||chr(39)||x||chr(39)
                into rec3;
                if rec3.ct <> 0 then
                dbms_output.put_line(rec2.owner||','||rec3.ct);
                else null;
                end if;
                end loop;
                end;
                

                【讨论】:

                  【解决方案11】:

                  引用:

                  我尝试使用下面的这个语句 找到一个合适的列基于 我认为它应该被命名,但它 没有返回任何结果。*

                  SELECT * from dba_objects WHERE
                  object_name like '%DTN%'
                  

                  列不是对象。如果您的意思是希望列名类似于“%DTN%”,那么您想要的查询是:

                  SELECT owner, table_name, column_name FROM all_tab_columns WHERE column_name LIKE '%DTN%';
                  

                  但如果“DTN”字符串只是您的猜测,那可能无济于事。

                  顺便说一句,您有多确定“1/22/2008P09RR8”是直接从单个列中选择的值?如果您根本不知道它来自哪里,它可能是多个列的串联,或者某个函数的结果,或者位于嵌套表对象中的值。因此,您可能会大吃一惊,试图检查每一列的值。你能不能从显示这个值的任何客户端应用程序开始,并尝试找出它使用什么查询来获取它?

                  无论如何,diciu 的回答提供了一种生成 SQL 查询以检查每个表的每一列的值的方法。您还可以使用 PL/SQL 块和动态 SQL 在一个 SQL 会话中完全完成类似的工作。这是一些仓促编写的代码:

                      SET SERVEROUTPUT ON SIZE 100000
                  
                      DECLARE
                        match_count INTEGER;
                      BEGIN
                        FOR t IN (SELECT owner, table_name, column_name
                                    FROM all_tab_columns
                                    WHERE owner <> 'SYS' and data_type LIKE '%CHAR%') LOOP
                  
                          EXECUTE IMMEDIATE
                            'SELECT COUNT(*) FROM ' || t.owner || '.' || t.table_name ||
                            ' WHERE '||t.column_name||' = :1'
                            INTO match_count
                            USING '1/22/2008P09RR8';
                  
                          IF match_count > 0 THEN
                            dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count );
                          END IF;
                  
                        END LOOP;
                  
                      END;
                      /
                  

                  还有一些方法可以提高效率。

                  在这种情况下,给定您要查找的值,您可以清楚地消除任何 NUMBER 或 DATE 类型的列,这将减少查询次数。甚至可能将其限制为类型类似于 '%CHAR%' 的列。

                  您可以像这样为每个表构建一个查询,而不是每列一个查询:

                  SELECT * FROM table1
                    WHERE column1 = 'value'
                       OR column2 = 'value'
                       OR column3 = 'value'
                       ...
                       ;
                  

                  【讨论】:

                  • 您应该将其限制为 char、varchar 和 varchar2 列,因为数字和日期列不可能包含该字符串。
                  • @ammoQ -- 就像我在倒数第二段中所说的那样?
                  • 我在 9i 上运行了这个,我得到 column_name unknown 错误。有人能告诉我在 9i 上运行它需要什么修改吗?
                  • @Regmi -- 抱歉,这实际上是我的代码中的一个错误,而不是版本问题。循环应该由all_tab_columns 而不是all_tables 驱动。我已经修好了。
                  • @DaveCosta - 感谢您的修复,但我仍然在第 6 行收到“表或视图不存在”错误。第 6 行是“立即执行”。
                  【解决方案12】:

                  我修改了 Flood 的脚本,使其对每个表执行一次,而不是对每个表的每一列执行一次,以加快执行速度。它需要 Oracle 11g 或更高版本。

                      set serveroutput on size 100000
                  
                  declare
                      v_match_count integer;
                      v_counter integer;
                  
                      -- The owner of the tables to search through (case-sensitive)
                      v_owner varchar2(255) := 'OWNER_NAME';
                      -- A string that is part of the data type(s) of the columns to search through (case-insensitive)
                      v_data_type varchar2(255) := 'CHAR';
                      -- The string to be searched for (case-insensitive)
                      v_search_string varchar2(4000) := 'FIND_ME';
                  
                      -- Store the SQL to execute for each table in a CLOB to get around the 32767 byte max size for a VARCHAR2 in PL/SQL
                      v_sql clob := '';
                  begin
                      for cur_tables in (select owner, table_name from all_tables where owner = v_owner and table_name in 
                                         (select table_name from all_tab_columns where owner = all_tables.owner and data_type like '%' ||  upper(v_data_type) || '%')
                                         order by table_name) loop
                          v_counter := 0;
                          v_sql := '';
                  
                          for cur_columns in (select column_name from all_tab_columns where 
                                              owner = v_owner and table_name = cur_tables.table_name and data_type like '%' || upper(v_data_type) || '%') loop
                              if v_counter > 0 then
                                  v_sql := v_sql || ' or ';
                              end if;
                              v_sql := v_sql || 'upper(' || cur_columns.column_name || ') like ''%' || upper(v_search_string) || '%''';
                              v_counter := v_counter + 1;
                          end loop;
                  
                          v_sql := 'select count(*) from ' || cur_tables.table_name || ' where ' || v_sql;
                  
                          execute immediate v_sql
                          into v_match_count;
                  
                          if v_match_count > 0 then
                              dbms_output.put_line('Match in ' || cur_tables.owner || ': ' || cur_tables.table_name || ' - ' || v_match_count || ' records');
                          end if;
                      end loop;
                  
                      exception
                          when others then
                              dbms_output.put_line('Error when executing the following: ' || dbms_lob.substr(v_sql, 32600));
                  end;
                  /
                  

                  【讨论】:

                    【解决方案13】:

                    搜索整个数据库的过程:

                        CREATE or REPLACE PROCEDURE SEARCH_DB(SEARCH_STR IN VARCHAR2, TAB_COL_RECS OUT VARCHAR2) IS
                          match_count integer;
                          qry_str varchar2(1000);
                          CURSOR TAB_COL_CURSOR IS 
                              SELECT TABLE_NAME,COLUMN_NAME,OWNER,DATA_TYPE FROM ALL_TAB_COLUMNS WHERE DATA_TYPE in ('NUMBER','VARCHAR2') AND OWNER='SCOTT';
                              BEGIN  
                                FOR TAB_COL_REC  IN TAB_COL_CURSOR
                                LOOP
                                  qry_str := 'SELECT COUNT(*) FROM '||TAB_COL_REC.OWNER||'.'||TAB_COL_REC.TABLE_NAME|| 
                                  ' WHERE '||TAB_COL_REC.COLUMN_NAME;
                                   IF TAB_COL_REC.DATA_TYPE = 'NUMBER' THEN
                                          qry_str := qry_str||'='||SEARCH_STR; 
                                   ELSE
                                           qry_str := qry_str||' like '||SEARCH_STR; 
                                   END IF;
                                           --dbms_output.put_line( qry_str );
                                    EXECUTE IMMEDIATE  qry_str  INTO match_count;
                                    IF match_count > 0 THEN          
                                       dbms_output.put_line( qry_str );
                                      --dbms_output.put_line( TAB_COL_REC.TABLE_NAME ||' '||TAB_COL_REC.COLUMN_NAME ||' '||match_count);     
                                        TAB_COL_RECS := TAB_COL_RECS||'@@'||TAB_COL_REC.TABLE_NAME||'##'||TAB_COL_REC.COLUMN_NAME;
                                    END IF; 
                              END LOOP;
                         END SEARCH_DB;    
                    

                    执行语句

                      DECLARE
                        SEARCH_STR VARCHAR2(200);
                        TAB_COL_RECS VARCHAR2(200);
                        BEGIN
                          SEARCH_STR := 10;
                          SEARCH_DB(
                            SEARCH_STR => SEARCH_STR,
                            TAB_COL_RECS => TAB_COL_RECS
                          );
                         DBMS_OUTPUT.PUT_LINE('TAB_COL_RECS = ' || TAB_COL_RECS);
                         END;
                    

                    示例结果

                    Connecting to the database test.
                    SELECT COUNT(*) FROM SCOTT.EMP WHERE DEPTNO=10
                    SELECT COUNT(*) FROM SCOTT.DEPT WHERE DEPTNO=10
                    TAB_COL_RECS = @@EMP##DEPTNO@@DEPT##DEPTNO
                    Process exited.
                    Disconnecting from the database test.
                    

                    【讨论】:

                    • 错误报告 - ORA-00933:SQL 命令未正确结束 ORA-06512:在“TBOWNER.SEARCH_DB”,第 17 行 ORA-06512:在“TBOWNER.SEARCH_DB”,第 17 行 ORA-06512:在第 6 行 00933. 00000 -“SQL 命令未正确结束”
                    • 我在运行程序时遇到了上述错误。像这样运行 DECLARE SEARCH_STR VARCHAR2(200); TAB_COL_RECS VARCHAR2(200); BEGIN SEARCH_STR := 'REQ000000839496'; SEARCH_DB(SEARCH_STR => SEARCH_STR,TAB_COL_RECS => TAB_COL_RECS); DBMS_OUTPUT.PUT_LINE('TAB_COL_RECS = ' || TAB_COL_RECS);结束;
                    【解决方案14】:

                    这是另一个修改版本,它将比较较低的子字符串匹配。这适用于 Oracle 11g。

                    DECLARE
                      match_count INTEGER;
                    -- Type the owner of the tables you are looking at
                      v_owner VARCHAR2(255) :='OWNER_NAME';
                    
                    -- Type the data type you are look at (in CAPITAL)
                    -- VARCHAR2, NUMBER, etc.
                      v_data_type VARCHAR2(255) :='VARCHAR2';
                    
                    -- Type the string you are looking at
                      v_search_string VARCHAR2(4000) :='%lower-search-sub-string%';
                    
                    BEGIN
                      FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP
                    
                        EXECUTE IMMEDIATE 
                        'SELECT COUNT(*) FROM '||t.table_name||' WHERE lower('||t.column_name||') like :1'
                        INTO match_count
                        USING v_search_string;
                    
                        IF match_count > 0 THEN
                          dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count );
                        END IF;
                    
                      END LOOP;
                    END;
                    /
                    

                    【讨论】:

                      【解决方案15】:

                      我会做这样的事情(生成您需要的所有选择)。 您可以稍后将它们提供给 sqlplus:

                      echo "select table_name from user_tables;" | sqlplus -S user/pwd | grep -v "^--" | grep -v "TABLE_NAME" | grep "^[A-Z]" | while read sw;
                      do echo "desc $sw" | sqlplus -S user/pwd | grep -v "\-\-\-\-\-\-" | awk -F' ' '{print $1}' | while read nw;
                      do echo "select * from $sw where $nw='val'";
                      done;
                      done;
                      

                      它产生:

                      select * from TBL1 where DESCRIPTION='val'
                      select * from TBL1 where ='val'
                      select * from TBL2 where Name='val'
                      select * from TBL2 where LNG_ID='val'
                      

                      它的作用是 - 对于来自 user_tables 的每个 table_name 获取每个字段(来自 desc)并从字段等于 'val' 的表中创建一个 select *。

                      【讨论】:

                        【解决方案16】:

                        如果您只在一个所有者中搜索,我对上述代码进行了一些修改,以使其更快地运行。 您只需更改 3 个变量 v_owner、v_data_type 和 v_search_string 以适应您正在搜索的内容。

                        SET SERVEROUTPUT ON SIZE 100000
                        
                        DECLARE
                          match_count INTEGER;
                        -- Type the owner of the tables you are looking at
                          v_owner VARCHAR2(255) :='ENTER_USERNAME_HERE';
                        
                        -- Type the data type you are look at (in CAPITAL)
                        -- VARCHAR2, NUMBER, etc.
                          v_data_type VARCHAR2(255) :='VARCHAR2';
                        
                        -- Type the string you are looking at
                          v_search_string VARCHAR2(4000) :='string to search here...';
                        
                        BEGIN
                          FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP
                        
                            EXECUTE IMMEDIATE 
                            'SELECT COUNT(*) FROM '||t.table_name||' WHERE '||t.column_name||' = :1'
                            INTO match_count
                            USING v_search_string;
                        
                            IF match_count > 0 THEN
                              dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count );
                            END IF;
                        
                          END LOOP;
                        END;
                        /
                        

                        【讨论】:

                        • 我必须注释第一行才能运行此查询。我也无法删除所有者过滤器并运行查询。
                        • 我需要在表名/列名周围加上双引号,以避免在需要引用时出现问题:'SELECT COUNT(*) FROM "'||t.table_name||'" WHERE "'||t.column_name||'" = :1'
                        • 注意 all_tab_cols 也包含视图,尽管有名称
                        • dbms_output 到底是什么?因为查询在 DataGrip 中成功执行,但之后我没有看到任何结果。
                        • 我知道这有点老了,但是当我运行它时,我只得到“匿名块完成”的脚本输出
                        【解决方案17】:

                        我没有关于 SQL 提示的简单解决方案。但是有很多工具,例如 toad 和 PL/SQL Developer,它们有一个 GUI,用户可以在其中输入要搜索的字符串,它会返回找到的表/过程/对象。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2016-10-26
                          • 2020-08-21
                          • 2021-07-25
                          • 2010-12-20
                          • 2017-07-04
                          相关资源
                          最近更新 更多