【问题标题】:Why do I get no output from this query (searching database for string)?为什么我没有从此查询中得到任何输出(搜索数据库中的字符串)?
【发布时间】:2022-01-07 18:21:08
【问题描述】:

我是 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 块也应该输出“无输出”。

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

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

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

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

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

谢谢。

【问题讨论】:

  • 您是否使用SET SERVEROUTPUT ON 使服务器能够将缓冲区返回给客户端?首先在会话中运行一次,然后运行您的脚本。除此之外,您的代码似乎可以工作db<>fiddle
  • 另外,你谈到了“数据库”。您的代码在 USER_TAB_COLS 之后运行,它仅循环遍历您连接到的架构中的所有列(以及表)。并非数据库中的所有模式。
  • 而且你不需要使用DBMS_OUTPUT.ENABLEdb<>fiddle
  • @MT0 是的,我试过了,但显然这不是在 PL/SQL Developer 中这样做的方法。相反,DBMS_OUTPUT.ENABLE 是这样做的方法(就在BEGIN 之后)。您可能是对的,我不需要它,因为“输出”选项卡显示它默认启用。 @Hermann 我正在为数据库中的所有模式寻找user_tab_cols 的替代关键字,但我没有找到任何东西。另外,我如何判断我连接到哪个模式?如何改变它?如何查看所有模式?谢谢你们的帮助。

标签: oracle output plsqldeveloper dbms-output


【解决方案1】:

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

我正在为数据库中的所有模式寻找 user_tab_cols 的替代关键字

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

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;
/

【讨论】:

  • 感谢 MT0,该脚本成功了。
猜你喜欢
  • 2021-02-07
  • 2013-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
相关资源
最近更新 更多