Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Vipul.

Asked: September 29, 2016 - 2:15 pm UTC

Last updated: January 09, 2019 - 2:07 pm UTC

Version: 12c

Viewed 50K+ times! This question is

You Asked

Hi Tom,

I am trying to pull the count of tables in the particular schema. I am using pl/sql block for this. Looks like there is a error with EXECUTE IMMEDIATE INTO clause in this block. Can you please help on this?

DECLARE

l_session_name VARCHAR2(30) := 'UNDEFINED';
l_owner VARCHAR2(30) := 'SCOTT';
l_cnt NUMBER := NULL;
sql_stmt VARCHAR2(1000) := NULL;

BEGIN

SELECT SYS_CONTEXT('userenv','session_user') INTO l_session_name FROM DUAL;
DBMS_OUTPUT.PUT_LINE('CURRENT SESSION USER IS '||l_session_name);

FOR i IN (SELECT owner, object_name FROM all_objects WHERE object_type = 'TABLE' AND owner = l_owner AND secondary = 'N' ORDER BY object_name)
loop
sql_stmt := 'SELECT COUNT(1) FROM ' || i.owner ||'.' || i.object_name || ';';
dbms_output.put_line(sql_stmt);
EXECUTE IMMEDIATE sql_stmt INTO l_cnt;
dbms_output.put_line (i.owner || '.' || i.object_name || ': ' || l_cnt);
END loop;
END;
/

and Chris said...

You don't need to put the semi-colon at the end of the statement. i.e. this:

sql_stmt := 'SELECT COUNT(1) FROM ' || i.owner ||'.' || i.object_name || ';';


Should become this:

sql_stmt := 'SELECT COUNT(1) FROM ' || i.owner ||'.' || i.object_name


Giving:

declare
  l_session_name varchar2 ( 30 )   := 'UNDEFINED';
  l_owner        varchar2 ( 30 )   := 'SCOTT';
  l_cnt          number            := null;
  sql_stmt       varchar2 ( 1000 ) := null;
begin
  select sys_context ( 'userenv','session_user' )
  into l_session_name
  from dual;
  dbms_output.put_line ( 'CURRENT SESSION USER IS '||l_session_name ) ;
  for i in
  (select owner, object_name
  from all_objects
  where object_type = 'TABLE'
  and owner         = l_owner
  and secondary     = 'N'
  order by object_name
  )
  loop
    sql_stmt := 'SELECT COUNT(1) FROM ' || i.owner ||'.' || i.object_name;
    dbms_output.put_line ( sql_stmt ) ;
    execute immediate sql_stmt into l_cnt;
    dbms_output.put_line ( i.owner || '.' || i.object_name || ': ' || l_cnt ) ;
  end loop;
end;
/ 

CURRENT SESSION USER IS CHRIS
SELECT COUNT(1) FROM SCOTT.BONUS
SCOTT.BONUS: 0
SELECT COUNT(1) FROM SCOTT.DEPT
SCOTT.DEPT: 4
SELECT COUNT(1) FROM SCOTT.EMP
SCOTT.EMP: 14
SELECT COUNT(1) FROM SCOTT.SALGRADE
SCOTT.SALGRADE: 5

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Works

Vipul, September 30, 2016 - 12:34 pm UTC

Thanks Chris for your response. Your query works.

I added some little cosmetic changes if anyone else wants to use the query:

SET SERVEROUTPUT ON;
DECLARE

l_session_name VARCHAR2(30) := 'UNDEFINED';
l_owner VARCHAR2(30) := 'SCOTT';
l_cnt NUMBER := NULL;
sql_stmt VARCHAR2(1000) := NULL;

BEGIN

SELECT SYS_CONTEXT('userenv','session_user') INTO l_session_name FROM DUAL;
DBMS_OUTPUT.PUT_LINE('CURRENT SESSION USER IS: '||l_session_name);
DBMS_OUTPUT.PUT_LINE('CHECKING COUNTS AGAINST: '||l_owner);
SELECT LENGTH(l_owner) INTO l_cnt FROM DUAL;

dbms_output.put_line (chr(13)||chr(10)||rpad('TABLE OWNER', l_cnt+1, ' ') || rpad('TABLE NAME', 30, ' ')|| ': ' || 'ROW COUNT' || chr(13)||chr(10));
l_cnt := null;
FOR i IN (SELECT owner, object_name FROM all_objects WHERE object_type = 'TABLE' AND owner = l_owner AND secondary = 'N' ORDER BY object_name)
loop
sql_stmt := 'SELECT COUNT(1) FROM ' || i.owner ||'.' || i.object_name;
EXECUTE IMMEDIATE sql_stmt INTO l_cnt;
dbms_output.put_line (i.owner || '.' || rpad(i.object_name, 30, ' ') || ': ' || l_cnt);
END loop;
END;
/
Chris Saxon
October 01, 2016 - 1:32 am UTC

Thanks for the input.

INTO gives error when embedded into a select and assigned to a variable and later executed

Khalid Mehmood, January 09, 2019 - 5:50 am UTC

When i try to do it like this and assign count to v_count_of_rows variable. It gives me error.

</>
ORA-00905: missing keyword
ORA-06512: at "LBI_OGG_MK.PRC_VRG_MFS_REGISTRATIONS", line 90
ORA-06512: at line 2
</>
v_partition_name variable has the partition name from where i want to query data.

</>
v_SQL := 'SELECT count(*) into v_count_of_rows
FROM
lbi_ogg_mk.t_o_audit_identity partition ( ' || v_partition_name || ') a
LEFT JOIN lbi_edm_mk.t_e_customer cust
ON cust.customer_id = a.on_iden_id
LEFT JOIN lbi_ogg_mk.T_O_SCY_CREDENTIAL scy
on scy.identity_id = cust.customer_id
WHERE
end_time >= to_date(to_char(SYSDATE - 1,''yyyymmdd'') || ''000000'', ''yyyymmddhh24miss'')
AND end_time < to_date(to_char(SYSDATE - 1,''yyyymmdd'') || ''235959'', ''yyyymmddhh24miss'')
AND a.event_type IN (
''CREATE_CUSTOMER'',
''RESET_CUSTOMER_PIN'',
''CHANGE_CUSTOMER_PIN''
)'
;
dbms_output.put_line (v_SQL);
execute immediate (v_SQL);
</>

I Got the answer.

Khalid Mehmood, January 09, 2019 - 5:55 am UTC

I got the answer right after posting the query.


execute immediate v_sql into v_type;



Cheers. Thanks Chris
Chris Saxon
January 09, 2019 - 2:07 pm UTC

Glad you sorted this out :)

More to Explore

DBMS_OUTPUT

More on PL/SQL routine DBMS_OUTPUT here