为什么我没有从这个查询中得到任何输出(在数据库中搜索字符串)?

Why do I get no output from this query (searching database for string)?

我是一名 Oracle/PL/SQL 开发新手,我正在努力弄清楚如何查看此查询的输出:

DECLARE
  ncount NUMBER;
  vwhere VARCHAR2(1000) := '';
  vselect VARCHAR2(1000) := ' select count(1) from ';
  vsearchstr VARCHAR2(1000) := '1301 250 Sage Valley Road NW';
  vline VARCHAR2(1000) := '';
  istatus INTEGER;
BEGIN
  DBMS_OUTPUT.ENABLE;
  FOR k IN (SELECT a.table_name, a.column_name FROM user_tab_cols a WHERE a.data_type LIKE '%VARCHAR%')
  LOOP
    vwhere := ' where ' || k.column_name || ' = :vsearchstr ';
    EXECUTE IMMEDIATE vselect || k.table_name || vwhere
      INTO ncount
      USING vsearchstr;
    IF (ncount > 0)
    THEN
      dbms_output.put_line(k.column_name || ' ' || k.table_name);
    ELSE
      dbms_output.put_line('no output');
    END IF;
  END LOOP;
  dbms_output.get_line(vline, istatus);
END;

我从 https://community.oracle.com/tech/developers/discussion/2572717/how-to-search-a-particular-string-in-whole-schema 那里得到了这个脚本。它应该在整个数据库中找到一个字符串 (vsearchstr)。当我在 PL/SQL Developer 14.0.6 中 运行 这个时,它没有吐出任何错误,说它花了 0.172 秒,但我没有看到任何输出。我希望输出显示在“输出”选项卡下:

我知道数据库中存在字符串“1301 250 Sage Valley Road NW”,因此应该可以找到它。即使没有,ELSE 块也应该输出 'no output'.

据我了解,dbms_output.put_line() 将给定的字符串添加到缓冲区,然后 dbms_output.get_line() 将其打印到输出目标(无论它设置为什么)。我知道 dbms_output 需要启用(因此 DBMS_OUTPUT.ENABLE 行)并且 dbms_output.get_line() 只会在 BEGIN/END 块完成后 运行 (我不知道这是否意味着它必须放在 BEGIN/END 块之外,但我每次都无法避免某些错误。

我已经通读了有关此问题的各种 Whosebug 帖子,以及一些外部站点:

https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68001/dbms_out.htm#1000449 https://www.tutorialspoint.com/plsql/plsql_dbms_output.htm

...但似乎没有任何效果。

我怎样才能看到输出,或者如果上面的查询有问题,你能告诉我是什么吗?

谢谢。

要在 PL/SQL 中启用来自 DBMS_OUTPUT 的输出,请参阅

I'm looking for an alternative keyword to user_tab_cols for all schemas in the DB

使用 ALL_TAB_COLS 并在您没有​​足够的权限读取 table 时捕获异常(并使用带引号的标识符来匹配 user/table/column 名称的大小写):

DECLARE
  found_row  PLS_INTEGER;
  vsearchstr VARCHAR2(1000) := '1301 250 Sage Valley Road NW';
BEGIN
  FOR k IN (SELECT owner,
                   table_name,
                   column_name
            FROM   all_tab_cols t
            WHERE  data_type LIKE '%VARCHAR%'
            -- Ignore columns that are too small
            AND    data_length >= LENGTH(vsearchstr)
            -- Ignore all oracle maintained tables
            -- Not supported on earlier Oracle versions
            AND    NOT EXISTS (
                     SELECT 1
                     FROM   all_users u
                     WHERE  t.owner = u.username
                     AND    u.oracle_maintained = 'Y'
                   )
           )
  LOOP
    DECLARE
      invalid_privileges EXCEPTION;
      PRAGMA EXCEPTION_INIT(invalid_privileges, -1031);
    BEGIN
      EXECUTE IMMEDIATE 'SELECT 1 FROM "' || k.owner || '"."' || k.table_name || '" WHERE "' || k.column_name || '" = :1 AND ROWNUM = 1' 
        INTO  found_row
        USING vsearchstr;

      dbms_output.put_line('Found: ' || k.table_name || '.' || k.column_name);
    EXCEPTION
      WHEN invalid_privileges THEN
        NULL;
      WHEN NO_DATA_FOUND THEN
        dbms_output.put_line('Not found: ' || k.table_name || '.' || k.column_name);
    END;
  END LOOP;
END;
/