执行PLSQL中的每个表

Raj*_*ore 5 oracle foreach plsql

我想知道所有表中符合特定名称条件的记录数.这是我构建的SQL

Declare SQLStatement VARCHAR (8000) :='';
BEGIN
  SELECT 'SELECT COUNT (*) FROM ' || Table_Name || ';'
  INTO SQLStatement
  FROM All_Tables
  WHERE 1=1
    AND UPPER (Table_Name) LIKE UPPER ('MSRS%');

  IF SQLStatement <> '' THEN
    EXECUTE IMMEDIATE SQLStatement;
  END IF;
END;
/
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

Error at line 1
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 3
Script Terminated on line 1.
Run Code Online (Sandbox Code Playgroud)

如何修改它以便它运行所有匹配的表?

更新:

根据收到的答案,我尝试了以下但我在DBMS_OUTPUT中没有得到任何结果

declare 
  cnt number;
begin
  for r in (select table_name from all_tables) loop
    dbms_output.put_line('select count(*) from CDR.' || r.table_name);
  end loop;
end;
/
Run Code Online (Sandbox Code Playgroud)

Ren*_*ger 9

declare 
  cnt number;
begin
  for r in (select owner, table_name from all_tables
             where upper(table_name) like ('%MSRS%')) loop

    execute immediate 'select count(*) from "'
            || r.owner || '"."'
            || r.table_name || '"'
            into cnt;

    dbms_output.put_line(r.owner || '.' || r.table_name || ': ' || cnt);
  end loop;
end;
/
Run Code Online (Sandbox Code Playgroud)

如果您从中进行选择,all_tables则不能指望获得从表名中选择所需的补助金.因此,您应该检查ORA-00942: table or view does not exist抛出的错误.

至于你的错误的原因:你得到这个错误,因为select语句返回一个包含多行的结果集(每个表一行),你不能将这样的结果集分配给varchar2.

顺便说一句,确保SET SERVEROUT ON在执行此块之前启用dbms_output .

  • 此解决方案忽略了两个表具有相同名称但不同所有者的可能性. (4认同)