TaiwanTimmy
TaiwanTimmy

Reputation: 187

Executing a table of dynamic SQL statements

I built a script using SQL Server that went through each table in a database and built a dynamic statement that when executed, displayed the column name, type, number of filled values, and total row for each column.

I am now trying to build the same thing with Oracle but I am running into problems. The following code gets me a table that is filled with all of the appropriate statements, but how can I execute and display them?

>SELECT
    'SELECT ''' || atc.column_name || ''', ''' || atc.table_name || ''', ''' ||     atc.data_type || ''', 
SUM(CASE WHEN temp.'|| atc.column_name || ' IS NULL THEN 0 ELSE 1 END)  "Filled     Values", 
    COUNT(temp.' || atc.column_name || ') "Total Records" 
    FROM all_tab_columns atc 
    JOIN '|| atc.table_name || ' temp ON atc.column_name = ''' || 
    atc.column_name ||''' AND atc.table_name = ''' || atc.table_name || '''' AS SQLRow 
FROM all_tab_columns atc;

This is an example of the statement that is produced from the above code:

>SELECT 'INITIAL_EXTENT', 'ALL_ALL_TABLES', 'NUMBER', 
SUM(CASE WHEN temp.INITIAL_EXTENT IS NULL THEN 0 ELSE 1 END)  "Filled Values", 
COUNT(temp.INITIAL_EXTENT) "Total Records" 
FROM all_tab_columns atc 
JOIN ALL_ALL_TABLES temp ON atc.column_name = 'INITIAL_EXTENT' AND atc.table_name =     'ALL_ALL_TABLES'

Upvotes: 1

Views: 124

Answers (1)

Emmanuel
Emmanuel

Reputation: 14209

Here is a try:

declare
  myCol1 varchar2(1000);
  myCol2 varchar2(1000);
  myCol3 varchar2(1000);
  myCol4 number;
  myCol5 number;
begin
  for line in
  (
    SELECT
        'SELECT ''' || atc.column_name || ''', ''' || atc.table_name || ''', ''' ||     atc.data_type || ''', 
    SUM(CASE WHEN temp.'|| atc.column_name || ' IS NULL THEN 0 ELSE 1 END)  "Filled     Values", 
        COUNT(temp.' || atc.column_name || ') "Total Records" 
        FROM all_tab_columns atc 
        JOIN '|| atc.table_name || ' temp ON atc.column_name = ''' || 
        atc.column_name ||''' AND atc.table_name = ''' || atc.table_name || '''' AS SQLRow 
    FROM all_tab_columns atc
  )
  loop
    dbms_output.put_line(myCol1 || ' | ' || myCol2 || ' | ' || myCol3 || ' | ' || myCol4 || ' | ' || myCol5);
    execute immediate line.Sqlrow into myCol1, myCol2, myCol3, myCol4, myCol5;
  end loop;
end;
/

This is using package DBMS_OUTPUT to display the results as strings; if you want the results as a query set, consider using pipelined functions.

EDIT : If you use SQL Developer, you could use this link to see the results; for SQL*Plus, try this one. Thanks to this buffer output, you could see what is the failing table for LONG datatype (note that in the solution above, I switched the dbms_output and the execute immediate lines to have the table displayed before the execution).

You can also find the restrictions on LONG datatype here.

Upvotes: 3

Related Questions