Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在Oracle数据库中动态搜索2个值_Sql_Oracle - Fatal编程技术网

Sql 在Oracle数据库中动态搜索2个值

Sql 在Oracle数据库中动态搜索2个值,sql,oracle,Sql,Oracle,大家好 我试图在一定程度上解决这个问题,但还是有点困难 对于本例,我想在两列中找到两个值: 瓦查尔和日期 约翰1984-01-01 假设这是约翰的生日 我希望能够在2000个表中找到JOHN的值和DATE的值,让事情复杂化的是,列名不尽相同。数据类型为 下面将选择我需要的具有两个列名的所有表 SELECT A.TABLE_NAME, A.COLUMN_NAME, B.COLUMN_NAME FROM all_tab_columns A JOIN all_tab_columns

大家好

我试图在一定程度上解决这个问题,但还是有点困难

对于本例,我想在两列中找到两个值: 瓦查尔和日期 约翰1984-01-01

假设这是约翰的生日

我希望能够在2000个表中找到JOHN的值和DATE的值,让事情复杂化的是,列名不尽相同。数据类型为

下面将选择我需要的具有两个列名的所有表

SELECT A.TABLE_NAME, A.COLUMN_NAME, B.COLUMN_NAME
  FROM all_tab_columns A
       JOIN all_tab_columns B
          ON     A.TABLE_NAME = B.TABLE_NAME
             AND B.DATA_TYPE = 'DATE'
             AND A.COLUMN_NAME IN ('NAME', 'FULLNAME')
所以,现在我得到了我需要的表,它的数据类型是DATE,其中列名称和全名都存在

所以现在在2000个表中,我有300个符合我的标准。我想搜索日期为1984-01-01的JOHN表格,其中JOHN可以是全名或全名,1984-01-01可以是任何列名,即DTTM、BDAY、DATEFLD、DTFIELD等

我想要一个表名,这两个值在同一行中,没有别的

我已经看过这些类型的例子:

但问题不断。我错过了什么

DECLARE
   match_count       INTEGER;
   v_search_string   VARCHAR2 (11) := 'JOHN';
BEGIN
   FOR t
      IN (SELECT A.owner, A.table_name, A.column_name
            FROM all_tab_columns A
                 JOIN all_tab_columns B
                    ON     A.TABLE_NAME = B.TABLE_NAME
                       AND A.COLUMN_NAME IN ('NAME', 'FULLNAME')
                       AND B.DATA_TYPE = 'DATE'
                       AND A.TABLE_NAME LIKE 'DATA%')
   LOOP
      BEGIN
         EXECUTE IMMEDIATE
               'SELECT * FROM '
            || t.owner
            || '.'
            || 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
               );
         END IF;
      EXCEPTION
         WHEN OTHERS
         THEN
            DBMS_OUTPUT.put_line (
                  'Error encountered trying to read '
               || t.column_name
               || ' from '
               || t.owner
               || '.'
               || t.table_name);
      END;
   END LOOP;
END;
/

您可以尝试使用
all\u tab\u columns
中的select来构造where子句,并在动态where子句中查询相应的表

SET serveroutput ON 
DECLARE 
    v_count INTEGER; 
BEGIN 
    FOR r IN (SELECT a.table_name, 
                     ' WHERE ' 
                     || LISTAGG(CASE data_type 
                                  WHEN 'DATE' THEN column_name 
                                                   || ' = DATE ' 
                                                   || '''1984-01-01''' 
                                  ELSE column_name 
                                       || ' = ' 
                                       || '''JOHN''' 
                                END, ' or ') 
                          WITHIN GROUP( ORDER BY column_name ) AS where_clause 
              FROM   user_tab_columns a 
              WHERE  column_name IN ( 'NAME', 'FULLNAME' ) 
                      OR ( data_type = 'DATE' 
                           AND column_name IN ( 'DTTM', 'BDAY', 'DATEFLD', 
                                                'DTFIELD' 
                                              ) ) 
              GROUP  BY table_name) LOOP 
        EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '|| r.table_name|| 
        r.where_clause 
        INTO 
        v_count; 

        IF v_count > 0 THEN 
          dbms_output.Put_line(r.table_name); 
        END IF; 
    END LOOP; 
END; 

/ 
请注意,我给您的是一个示例,它为您提供了一些想法,您可以构造它并调整隐式游标循环的查询(在
r in()
)为了满足您的需要,可以使用
和/或/JOIN
条件
INTERSECT
操作符等,我这样做是为了从我的角度进行测试

编辑:另一个选项是蛮力方法,即使用动态where子句搜索数据库中的所有表,如果在表中找不到where子句中的列,则忽略异常

SET serveroutput ON 
DECLARE 
    v_count        NUMBER; 
    v_where_clause VARCHAR2(400) := 
    ' WHERE DTTM = DATE ''1984-01-01'' AND FULLNAME = ''JOHN'''; 
BEGIN 
    FOR r IN (SELECT owner, 
                     table_name 
              FROM   all_tables) LOOP 
        BEGIN 
            EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM '|| r.owner|| '.'|| 
            r.table_name 
            || 
            v_where_clause INTO v_count; 

            IF v_count > 0 THEN 
              dbms_output.put_line(r.owner||'.'||r.table_name); 
            END IF; 
        EXCEPTION 
            WHEN OTHERS THEN 
              NULL; --It is ok in this case as you know why it fails. 
        END; 
    END LOOP; 
END; 
/ 

我对你的代码做了一些小的修改:

DECLARE
   match_count       INTEGER;
   v_search_string   VARCHAR2 (11) := 'JOHN';
   v_search_date      DATE          := date '1984-01-01';
BEGIN
   FOR t IN (
     SELECT A.owner, A.table_name, A.column_name text_column_name, B.column_name date_column_name
     FROM   all_tab_columns A
            JOIN all_tab_columns B
               ON  A.TABLE_NAME = B.TABLE_NAME
               AND A.OWNER = B.OWNER
               AND A.COLUMN_NAME IN ('NAME', 'FULLNAME')
               AND B.DATA_TYPE = 'DATE'
               AND A.TABLE_NAME LIKE 'DATA%'
   ) LOOP
      BEGIN
         EXECUTE IMMEDIATE
               'SELECT count(*) FROM '
            || t.owner
            || '.'
            || t.table_name
            || ' WHERE '
            || t.text_column_name
            || ' = :1'
            || ' and '
            || t.date_column_name
            || ' = :2'
            INTO match_count
            USING v_search_string, v_search_date;

         IF match_count > 0
         THEN
            DBMS_OUTPUT.put_line (
                'Found! '||t.table_name
               );
         ELSE
            DBMS_OUTPUT.put_line (
                'No matches for '||t.table_name||'('||t.text_column_name||','||t.date_column_name||')'
               );
         END IF;
      EXCEPTION
         WHEN OTHERS
         THEN
            DBMS_OUTPUT.put_line (
                  'Error encountered trying to read from '
               || t.owner
               || '.'
               || t.table_name);
      END;
   END LOOP;
END;
/

“我已经看了…但一直有问题”什么问题?我们不知道。我不知道如何在链接发布后搜索两个值。它只适用于一个值。。。如何搜索两个值?这就是我的问题……好吧,在WHERE子句中使用AND运算符,并调整语句的定义,使之在两种数据类型中循环。告诉我们你尝试过什么。编辑包括我走了多远。请也包括你收到的错误。这个先生,工作非常好-结果我在这里和那里漏掉了一点。谢谢你的帮助!