【问题标题】:How to pass schema name and table name as input then get memory size and row_count as output in plsql如何将模式名称和表名称作为输入传递,然后在 plsql 中获取内存大小和 row_count 作为输出
【发布时间】:2021-08-22 20:40:14
【问题描述】:

我正在尝试创建一个动态返回行数和表大小(以字节为单位)的过程。 我想要的是传递模式和表名作为输入,然后获取内存大小和输出行数。这是我的代码:

set serveroutput on
create or replace procedure get_table_count4 (table_name IN varchar2,schema_name IN varchar2
)
is
  table_count number;
  byte_count number;
  
begin
  execute immediate 'select count(*) from ' || table_name into table_count;
  dbms_output.put_line(table_count);
  select bytes from dba_segments into byte_count 
  where owner = schema_name and segment_name = UPPER(table_name);
  dbms_output.put_line(byte_count);

end;

我收到此错误:

Procedure GET_TABLE_COUNT4 compiled

LINE/COL  ERROR
--------- -------------------------------------------------------------
10/3      PL/SQL: SQL Statement ignored
10/34     PL/SQL: ORA-00933: SQL komutu tam doğru olarak sona ermedi
Errors: check compiler log

Procedure GET_TABLE_COUNT4 compiled

LINE/COL  ERROR
--------- -------------------------------------------------------------
10/3      PL/SQL: SQL Statement ignored
10/34     PL/SQL: ORA-00933: SQL command not ended properly
Errors: check compiler log

我该如何解决这个问题?

【问题讨论】:

  • 只需将子句intofrom 的顺序更改为into byte_count from user_segments,而不是当前状态下的from dba_segments into byte_count
  • 可以在不访问表本身的情况下检索近似行数,因为如果您的数据库是健康的,那么您已经拥有最新的统计信息并且可能会使用它。也可以通过将块数乘以块大小来计算近似表大小
  • 谨防 SQL 注入。您编写的代码不会阻止它。
  • 只是对术语进行评论,dba_segments 报告已用空间(存储),而不是内存。

标签: sql oracle plsql


【解决方案1】:

不完全使用 COUNT(),但 NUM_ROWS 应该这样做:

CREATE OR REPLACE PROCEDURE GET_TABLE_COUNT4(TABLE_NAME  IN VARCHAR2,
                                             SCHEMA_NAME IN VARCHAR2) IS
  TABLE_COUNT NUMBER;
  BYTE_COUNT  NUMBER;
BEGIN
  SELECT DB.NUM_ROWS
    INTO TABLE_COUNT
    FROM DBA_TABLES DB
   WHERE DB.TABLE_NAME = UPPER(TABLE_NAME);

  DBMS_OUTPUT.PUT_LINE(TABLE_COUNT);

  SELECT BYTES
    INTO BYTE_COUNT
    FROM DBA_SEGMENTS
   WHERE OWNER        = UPPER(SCHEMA_NAME)
     AND SEGMENT_NAME = UPPER(TABLE_NAME);

  DBMS_OUTPUT.PUT_LINE(BYTE_COUNT);
END;
/

【讨论】:

  • 好答案。但是这两个查询都需要稍作更改,因为数据字典表都是大写的,并且多个模式可能包含相同的表名使用:where owner = upper(schema_name) and <NAME> = upper(table_name) 替换为 table_name 或 segment_name 。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 2012-08-19
  • 2012-03-29
  • 1970-01-01
  • 2013-10-16
  • 1970-01-01
相关资源
最近更新 更多