fetch table name from a column for from clause - sql

I have a view t with me which has a column for table name and another column which has where clause condition.
id| name|table_in| where_clause
1 | Sam | t1 | age = 22
2 | John| t2 | age = 23 and sex = 'male'
and so on...
Now, I have put the records in a cursor and I want to run each query.
create or replace procedure create_cursor
is
CURSOR v_records is
select * from t ;
begin
FOR temp IN v_records LOOP
INSERT INTO myTable (id, name)
select temp.id, temp.name
from temp.table where temp.where_clause;
END LOOP;
end;
/
myTable is another table in which I want to put the records for next purpose.

#Akshay,
Please find the code below for your reference.
Create or replace procedure create_cursor is
l_statement varchar2(32767);
cursor v_records is
select * from t;
begin
for temp in v_records
loop
l_statement := 'INSERT INTO myTable (id, name) select '||temp.id||','
||temp.name|| ' from ' || temp.table1
|| ' where ' || temp.where_clause;
execute immediate l_statement;
end loop;
end;
/

You need dynamic sql to do this:
CREATE OR REPLACE PROCEDURE create_cursor
IS
l_statement VARCHAR2(32767);
CURSOR v_records
IS
SELECT * FROM t;
BEGIN
FOR temp IN v_records
LOOP
l_statement := 'INSERT INTO myTable (id, name)
select id, name from ' || temp.table ||
' where ' || temp.where_clause;
EXECUTE immediate l_statement;
END LOOP;
END;
/

Related

Oracle PL/SQL How to store and fetch a dynamic multi column query

I am trying hard dynamic PL/SQL thing here.
I don't manage to fetch a column dynamic Query.
I am iterating on the name of the column to concatenate a full query in order to be executed on another table.
sql_req := 'select ';
for c in (SELECT name_col from TAB_LISTCOL)
loop
sql_req := sql_req || 'sum(' || c.name_col || '),';
end loop;
sql_req := sql_req || ' from ANOTHER_TAB ';
And when i try to execute it with EXECUTE IMMEDIATE or cursors or INTO/BULK COLLECT thing or just to fetch, i don't manage to iterate on the result.
I tried a lot.
Can you help me plz ? Or maybe it is not possible ?
ps : i know the coma is wrong but my code is more complexe than this : i didn't want to put more things
If you only want to get string columns, you can use listagg
select listagg(name_col, ',') WITHIN GROUP (ORDER BY null) from TAB_LISTCOL
Please see if this helps
In the absence of actual table structure and requirement, I'm creating dummy tables and query to illustrate an example:
SQL> create table another_tab
as
select 10 dummy_value1, 100 dummy_value2, 1000 dummy_value3 from dual union all
select 11 dummy_value1, 101 dummy_value2, 1001 dummy_value3 from dual union all
select 12 dummy_value1, 102 dummy_value2, 1003 dummy_value3 from dual
;
Table created.
SQL> create table tab_listcol
as select column_name from dba_tab_cols where table_name = 'ANOTHER_TAB'
;
Table created.
To reduce complexity in the final block, I'm defining a function to generate the dynamic sql query. This is based on your example and will need changes according to your actual requirement.
SQL> create or replace function gen_col_based_query
return varchar2
as
l_query varchar2(4000);
begin
l_query := 'select ';
for cols in ( select column_name cname from tab_listcol )
loop
l_query := l_query || 'sum(' || cols.cname || '), ' ;
end loop;
l_query := rtrim(l_query,', ') || ' from another_tab';
return l_query;
end;
/
Function created.
Sample output from the function will be as follows
SQL> select gen_col_based_query as query from dual;
QUERY
--------------------------------------------------------------------------------
select sum(DUMMY_VALUE1), sum(DUMMY_VALUE2), sum(DUMMY_VALUE3) from another_tab
Below is a sample block for executing a dynamic cursor using DBMS_SQL. For your ease of understanding, I've added comments wherever possible. More info here.
SQL> set serveroutput on size unlimited
SQL> declare
sql_stmt clob;
src_cur sys_refcursor;
curid number;
desctab dbms_sql.desc_tab; -- collection type
colcnt number;
namevar varchar2 (50);
numvar number;
datevar date;
l_header varchar2 (4000);
l_out_rows varchar2 (4000);
begin
/* Generate dynamic sql from the function defined earlier */
select gen_col_based_query into sql_stmt from dual;
/* Open cursor variable for this dynamic sql */
open src_cur for sql_stmt;
/* To fetch the data, however, you cannot use the cursor variable, since the number of elements fetched is unknown at complile time.
Therefore you use DBMS_SQL.TO_CURSOR_NUMBER to convert a REF CURSOR variable to a SQL cursor number which you can then pass to DBMS_SQL subprograms
*/
curid := dbms_sql.to_cursor_number (src_cur);
/* Use DBMS_SQL.DESCRIBE_COLUMNS to describe columns of your dynamic cursor, returning information about each column in an associative array of records viz., desctab. The no. of columns is returned in colcnt variable.
*/
dbms_sql.describe_columns (curid, colcnt, desctab);
/* Define columns at runtime based on the data type (number, date or varchar2 - you may add to the list)
*/
for indx in 1 .. colcnt
loop
if desctab (indx).col_type = 2 -- number data type
then
dbms_sql.define_column (curid, indx, numvar);
elsif desctab (indx).col_type = 12 -- date data type
then
dbms_sql.define_column (curid, indx, datevar);
else -- assuming string
dbms_sql.define_column (curid, indx, namevar, 100);
end if;
end loop;
/* Print header row */
for i in 1 .. desctab.count loop
l_header := l_header || ' | ' || rpad(desctab(i).col_name,20);
end loop;
l_header := l_header || ' | ' ;
dbms_output.put_line(l_header);
/* Loop to retrieve each row of data identified by the dynamic cursor and print output rows
*/
while dbms_sql.fetch_rows (curid) > 0
loop
for indx in 1 .. colcnt
loop
if (desctab (indx).col_type = 2) -- number data type
then
dbms_sql.column_value (curid, indx, numvar);
l_out_rows := l_out_rows || ' | ' || rpad(numvar,20);
elsif (desctab (indx).col_type = 12) -- date data type
then
dbms_sql.column_value (curid, indx, datevar);
l_out_rows := l_out_rows || ' | ' || rpad(datevar,20);
elsif (desctab (indx).col_type = 1) -- varchar2 data type
then
dbms_sql.column_value (curid, indx, namevar);
l_out_rows := l_out_rows || ' | ' || rpad(namevar,20);
end if;
end loop;
l_out_rows := l_out_rows || ' | ' ;
dbms_output.put_line(l_out_rows);
end loop;
dbms_sql.close_cursor (curid);
end;
/
PL/SQL procedure successfully completed.
Output
| SUM(DUMMY_VALUE1) | SUM(DUMMY_VALUE2) | SUM(DUMMY_VALUE3) |
| 33 | 303 | 3004 |
You have to use EXECUTE IMMEDIATE with BULK COLLECT
Below is an example of the same. For more information refer this link
DECLARE
TYPE name_salary_rt IS RECORD (
name VARCHAR2 (1000),
salary NUMBER
);
TYPE name_salary_aat IS TABLE OF name_salary_rt
INDEX BY PLS_INTEGER;
l_employees name_salary_aat;
BEGIN
EXECUTE IMMEDIATE
q'[select first_name || ' ' || last_name, salary
from hr.employees
order by salary desc]'
BULK COLLECT INTO l_employees;
FOR indx IN 1 .. l_employees.COUNT
LOOP
DBMS_OUTPUT.put_line (l_employees (indx).name);
END LOOP;
END;
If I understand correctly, you want to create a query and execute it and return the result to another function or some calling app. As the resulting query's columns are note before-known, I'd return a ref cursor in this case:
create function get_sums return sys_refcur as
declare
my_cursor sys_refcursor;
v_query varchar2(32757);
begin
select
'select ' ||
listagg('sum(' || name_col || ')', ', ') within group (order by name_col) ||
' from another_tab'
into v_query
from tab_listcol;
open my_cursor for v_query;
return v_query;
end get_sums;

Errors in PLSQL -

Morning,
I'm trying to write a script that will convert Unload tables (UNLD to HDL files) creating a flat file using PLSQL. I keep getting syntax errors trying to run it and would appreciate some help from an expert out there!
Here are the errors:
Error(53,21): PLS-00330: invalid use of type name or subtype name
Error(57,32): PLS-00222: no function with name 'UNLDTABLE' exists in this scope
Our guess is that the unldTable variable is being treated as a String, rather than a database table object (Not really expereinced in PLSQL)
CREATE OR REPLACE PROCEDURE UNLD_TO_HDL (processComponent IN VARCHAR2)
IS
fHandle UTL_FILE.FILE_TYPE;
concatData VARCHAR2(240);
concatHDLMetaTags VARCHAR2(240);
outputFileName VARCHAR2(240);
TYPE rowArrayType IS TABLE OF VARCHAR2(240);
rowArray rowArrayType;
emptyArray rowArrayType;
valExtractArray rowArrayType;
hdlFileName VARCHAR2(240);
unldTable VARCHAR2(240);
countUNLDRows Number;
dataType VARCHAR2(240);
current_table VARCHAR2(30);
value_to_char VARCHAR2(240);
BEGIN
SELECT HDL_FILE_NAME
INTO hdlFileName
FROM GNC_HDL_CREATION_PARAMS
WHERE PROCESS_COMPONENT = processComponent;
SELECT UNLD_TABLE
INTO unldTable
FROM GNC_HDL_CREATION_PARAMS
WHERE PROCESS_COMPONENT = processComponent
FETCH NEXT 1 ROWS ONLY;
SELECT LISTAGG(HDL_META_TAG,'|')
WITHIN GROUP(ORDER BY HDL_META_TAG)
INTO concatHDLMetaTags
FROM GNC_MIG_CONTROL
WHERE HDL_COMP = processComponent;
SELECT DB_FIELD
BULK COLLECT INTO valExtractArray
FROM GNC_MIG_CONTROL
WHERE HDL_COMP = processComponent
ORDER BY HDL_META_TAG;
fHandle := UTL_FILE.FOPEN('./', hdlFileName, 'W');
UTL_FILE.PUTF(fHandle, concatHDLMetaTags + '\n');
SELECT num_rows INTO countUNLDRows FROM user_tables where table_name = unldTable;
FOR row in 1..countUNLDRows LOOP
rowArray := emptyArrayType;
FOR value in 1..valExtractArray.COUNT LOOP
rowArray.extend();
SELECT data_type INTO dataType FROM all_tab_columns where table_name = unldTable AND column_name = valExtractArray(value);
IF dataType = 'VARCHAR2' THEN (SELECT valExtractArray(value) INTO value_to_char FROM current_table WHERE ROWNUM = row);
ELSIF dataType = 'DATE' THEN (SELECT TO_CHAR(valExtractArray(value),'YYYY/MM/DD') INTO value_to_char FROM current_table WHERE ROWNUM = row);
ELSIF dataType = 'NUMBER' THEN (SELECT TO_CHAR(valExtractArray(value)) INTO value_to_char FROM current_table WHERE ROWNUM = row);
ENDIF;
rowArray(value) := value_to_char;
END LOOP;
concatData := NULL;
FOR item in 1..rowArray.COUNT LOOP
IF item = rowArray.COUNT
THEN concatData := (COALESCE(concatData,'') || rowArray(item));
ELSE concatData := (COALESCE(concatData,'') || rowArray(item) || '|');
END IF;
END LOOP;
UTL_FILE.PUTF(fHandle, concatData + '/n');
END LOOP;
UTL_FILE.FCLOSE(fHandle);
END;
Thanks,
Adam
I believe it is just an overlook in your code. You define unldTable as a varchar, which is used correctly until you try to access it as if it were a varray on line 51
rowArray(value) := unldTable(row).valExtractArray(value);
Given that you have not defined it as a varray, unldTable(row) is making the interpreter believe that you are referring to a function.
EDIT
Now that you have moved on, you should resolve the problem of invoking SELECT statements on tables that are unknown at runtime. To do so you need to make use of Dynamic SQL; you can do it in several way, the most direct being an Execute immediate statement in your case:
mystatement := 'SELECT valExtractArray(value) INTO :value_to_char FROM ' || current_table || ' WHERE ROWNUM = ' || row;
execute immediate mystatement USING OUT value_to_char;
It looks like you need to generate a cursor as
select [list of columns from GNC_MIG_CONTROL.DB_FIELD]
from [table name from GNC_HDL_CREATION_PARAMS.UNLD_TABLE]
Assuming setup like this:
create table my_table (business_date date, id integer, dummy1 varchar2(1), dummy2 varchar2(20));
create table gnc_hdl_creation_params (unld_table varchar2(30), process_component varchar2(30));
create table gnc_mig_control (db_field varchar2(30), hdl_comp varchar2(30), hdl_meta_tag integer);
insert into my_table(business_date, id, dummy1, dummy2) values (date '2018-01-01', 123, 'X','Some more text');
insert into gnc_hdl_creation_params (unld_table, process_component) values ('MY_TABLE', 'XYZ');
insert into gnc_mig_control (db_field, hdl_comp, hdl_meta_tag) values ('BUSINESS_DATE', 'XYZ', '1');
insert into gnc_mig_control (db_field, hdl_comp, hdl_meta_tag) values ('ID', 'XYZ', '2');
insert into gnc_mig_control (db_field, hdl_comp, hdl_meta_tag) values ('DUMMY1', 'XYZ', '3');
insert into gnc_mig_control (db_field, hdl_comp, hdl_meta_tag) values ('DUMMY2', 'XYZ', '4');
You could build a query like this:
select unld_table, listagg(expr, q'[||'|'||]') within group (order by hdl_meta_tag) as expr_list
from ( select t.unld_table
, case tc.data_type
when 'DATE' then 'to_char('||c.db_field||',''YYYY-MM-DD'')'
else c.db_field
end as expr
, c.hdl_meta_tag
from gnc_hdl_creation_params t
join gnc_mig_control c
on c.hdl_comp = t.process_component
left join user_tab_columns tc
on tc.table_name = t.unld_table
and tc.column_name = c.db_field
where t.process_component = 'XYZ'
)
group by unld_table;
Output:
UNLD_TABLE EXPR_LIST
----------- --------------------------------------------------------------------------------
MY_TABLE to_char(BUSINESS_DATE,'YYYY-MM-DD')||'|'||ID||'|'||DUMMY1||'|'||DUMMY2
Now if you plug that logic into a PL/SQL procedure you could have something like this:
declare
processComponent constant gnc_hdl_creation_params.process_component%type := 'XYZ';
unloadSQL long;
unloadCur sys_refcursor;
text long;
begin
select 'select ' || listagg(expr, q'[||'|'||]') within group (order by hdl_meta_tag) || ' as text from ' || unld_table
into unloadSQL
from ( select t.unld_table
, case tc.data_type
when 'DATE' then 'to_char('||c.db_field||',''YYYY/MM/DD'')'
else c.db_field
end as expr
, c.hdl_meta_tag
from gnc_hdl_creation_params t
join gnc_mig_control c
on c.hdl_comp = t.process_component
left join user_tab_columns tc
on tc.table_name = t.unld_table
and tc.column_name = c.db_field
where t.process_component = processComponent
)
group by unld_table;
open unloadCur for unloadSQL;
loop
fetch unloadCur into text;
dbms_output.put_line(text);
exit when unloadCur%notfound;
end loop;
close unloadCur;
end;
Output:
2018/01/01|123|X|Some more text
2018/01/01|123|X|Some more text
Now you just have to make that into a procedure, change dbms_output to utl_file and add your meta tags etc and you're there.
I've assumed there is only one distinct unld_table per process component. If there are more you'll need a loop to work through each one.
For a slightly more generic approach, you could build a cursor-to-csv generator which could encapsulate the datatype handling, and then you'd only need to build the SQL as select [columns] from [table]. You might then write a generic cursor to file processor, where you pass in the filename and a cursor and it does the lot.
Edit: I've updated my cursor-to-csv generator to provide file output, so you just need to pass it a cursor and the file details.

ORACLE SQL CURSOR / FOR LOOP

I need to verify converted data, distinct values and records counts. I would like to write statements so that I can enter a table name, then retrieve it's columns and use them in a query to get its distinct values (the actual values, not just a count of how many distinct) and their count.
I think I need to a CURSOR or CURSOR FOR LOOP and create something like this:
declare
cursor field_name
is
select COLUMN_NAME
from user_tab_cols
where table_name='TABLE1'
c_field_name field_name%ROWTYPE;
BEGIN
OPEN field_name
loop
fetch field_name INTO c_field_name;
exit when field_name%NOTFOUND;
end loop;
CLOSE field_name;
end;
Then run a query using that above in something like
select field_name, count(*)
from table1
group by field_name
Do I need to create 2 loop statements? I've not yet created one and can't quite get the context to get my results so far.
BEGIN
FOR myrow in (select field_name, count(*) as "count" from table1 group by field_name)
loop
dbms_output.put_line(myrow.field_name);
dbms_output.put_line(myrow.count);
end loop;
end;
Considering you will be giving the table name as parameter below code will print all the values of all the columns one by one along with the count of the values
create or replace PROCEDURE PR_PREP(
P_TABLE_NAME IN VARCHAR2)
IS
CURSOR CUR_COLUMNS (PA_TABLE_NAME VARCHAR2)
IS
SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = PA_TABLE_NAME;
COL_NAMES CUR_COLUMNS%ROWTYPE;
TYPE TYP_RECORD
IS
RECORD
(
FIELD_NAME VARCHAR2(255),
CNT INT);
TYPE TYP_OP_TABLE
IS
TABLE OF TYP_RECORD;
OP_TABLE TYP_OP_TABLE;
I INT;
V_SQL VARCHAR2(2000);
BEGIN
FOR COL_NAMES IN CUR_COLUMNS(P_TABLE_NAME)
LOOP
V_SQL := 'SELECT ' || COL_NAMES.COLUMN_NAME || ' AS FIELD_NAME ,
COUNT(*) AS CNT FROM ' ||
P_TABLE_NAME || ' GROUP BY ' || COL_NAMES.COLUMN_NAME ;
-- DBMS_OUTPUT.PUT_LINE (V_SQL);
EXECUTE IMMEDIATE V_SQL BULK COLLECT INTO OP_TABLE;
dbms_output.put_line('columna name = ' ||COL_NAMES.COLUMN_NAME);
FOR I IN OP_TABLE.FIRST .. OP_TABLE.LAST
LOOP
DBMS_OUTPUT.PUT_LINE('FIELD VALUE '||OP_TABLE(I).FIELD_NAME || ' COUNT = ' || OP_TABLE(I).CNT);
END LOOP;
DBMS_OUTPUT.PUT_LINE('ONE FILED ENDED , NEXT STARTED');
END LOOP;
END;

How to put string of values with IN clause using dynamic PL/SQL?

Using Oracle PL/SQL, how can I populate the bind variable :b3 with more than one value for the IN clause? (This code is for demo purposes only -- it may not compile but it does clarify the question if any is needed)
declare
type work_rec is record (
work_status varchar2(50),
work_cd varchar2(50));
type work_tab is table of work_rec index by pls_integer;
t_work_tab work_tab;
sql_stmt varchar2(400);
begin
select case
when status_desc like '%Employed%' then 'Employed'
else 'Unknown'
end as work_status
,case
when status_cd between '1' and '9' then '1,2,3,4'
else '0'
end as work_cd
bulk collect into t_work_tab
from employee_table;
for i in t_work_tab.first..t_work_tab.last
loop
sql_stmt := 'insert into employee_hist
select name,
employer
from tax_table
where employment_cd in (:b3)'; --< how to populate this with '1','2','3','4'
execute immediate sql_stmt using t_work_tab(i).work_cd;
commit;
end loop;
end;
/
When you loop through the values, keep appending the string with ' and , as required to make up the part of in. Then you can use that string as part of your sql statement.
Example
temp = "'"
Loop through values a,b,c,d as str
temp = temp + str + "'",
End Loop
temp = substr(temp,0,length(temp)) // this is to trim the last , character
Hope it helps!
You need to prepare the in list inside the loop using another variable and then the statement outside it. Something like this may help:
declare
type work_rec is record (
work_status varchar2(50),
work_cd varchar2(50));
type work_tab is table of work_rec index by pls_integer;
t_work_tab work_tab;
sql_stmt VARCHAR2(400);
v_in_str varchar2(100);_
begin
select case
when status_desc like '%Employed%' then 'Employed'
else 'Unknown'
end as work_status
,case
when status_cd between '1' and '9' then '1,2,3,4'
else '0'
end as work_cd
bulk collect into t_work_tab
from employee_table;
for i in t_work_tab.first..t_work_tab.last
loop
v_in_str := v_in_str || t_work_tab(i).work_cd || ',';
END loop;
v_in_str :=rtrim(v_in_str, ',');
sql_stmt := 'insert into employee_hist
select name,
employer
from tax_table
where employment_cd in ('||v_in_str||')';
execute immediate sql_stmt;
commit;
end;
you could use a plsql collection as bind variable, this seems the nicer solution to me:
declare
type t_nbr_tbl is table of number;
type work_rec is record (
work_status varchar2(50),
work_cd t_nbr_tbl;
type work_tab is table of work_rec index by pls_integer;
t_work_tab work_tab;
sql_stmt varchar2(400);
begin
select case
when status_desc like '%Employed%' then 'Employed'
else 'Unknown'
end as work_status
,case
when status_cd between '1' and '9' then t_nbr_tbl(1,2,3,4)
else t_nbr_tbl(0)
end as work_cd
bulk collect into t_work_tab
from employee_table;
for i in t_work_tab.first..t_work_tab.last
loop
sql_stmt := 'insert into employee_hist
select name,
employer
from tax_table
where employment_cd in (select column_value from table(:b3))'; --< how to populate this with '1','2','3','4'
execute immediate sql_stmt using t_work_tab(i).work_cd;
commit;
end loop;
end;
/
Better solution (at least to my issue) - don't use a bind variable but instead concatenate the string of values (code segment shown only):
for i in t_work_tab.first..t_work_tab.last
loop
sql_stmt := 'insert into employee_hist
select name,
employer
from tax_table
where employment_cd in (' || t_work_tab(i).work_cd || ')';
execute immediate sql_stmt;
...
You get the idea. Thanks for all your input.

Cursor and table cannot be found

I have a procedure that will select MAX from some tables, but for some reason it is not able to find these tables. Could anybody help me?
declare
varible1 varchar2 (255);
temp varchar2 (255);
last_val number(9,0);
cursor c1 is Select distinct table_name from user_tab_cols order by table_name;
begin
FOR asd in c1
LOOP
temp := asd.table_name;
varible1 := '"'||temp||'"';
select max("id") into last_val from varible1 ;
END LOOP;
end;
For example, the first table name is acceptance_form and for select I need to use "acceptance_form".
Code after edit:
declare
varible1 varchar2 (255);
temp varchar2 (255);
last_val number(9,0);
cursor c1 is Select distinct table_name from user_tab_cols where column_name = 'id';
begin
FOR asd in c1
LOOP
temp := asd.table_name;
execute immediate 'select NVL(max('||'id'||'),0) from "'||varible1||'"' into last_val;
END LOOP;
end;
Can't cuz db is Case sensitive Oracle express 10g tables and rows was created like this
CREATE TABLE "ADMINMME"."acceptance_form"
(
"group_id" NUMBER(9, 0),
"id" NUMBER(4, 0) DEFAULT '0' NOT NULL ,
"is_deleted" NUMBER(4, 0),
"name" NVARCHAR2(30) NOT NULL
);
Can u tell me how to handle exception sequence dosn't exist for this;
Nevermind exception was in wrong block :)
declare
temp varchar2 (255);
last_val number(9,0);
cursor c1 is Select distinct table_name from user_tab_cols where column_name = 'id';
begin
FOR asd in c1
LOOP
temp := asd.table_name;
execute immediate 'select NVL(max("id"),0)+1 from "'||temp||'"' into last_val;
begin
EXECUTE IMMEDIATE 'drop sequence "seq_'|| temp||'"';
EXECUTE IMMEDIATE 'create SEQUENCE "seq_'|| temp ||'" MINVALUE '||last_val||'MAXVALUE 999999999999999999999999999 INCREMENT BY 1 NOCACHE';
EXECUTE IMMEDIATE 'select '||temp||'.nextval from dual';
EXECUTE IMMEDIATE 'ALTER SEQUENCE "seq_'||temp||'" INCREMENT BY 1';
exception when others then
null;
end;
END LOOP;
end;
Dynamic sql doesn't work in that way.
declare
varible1 varchar2 (255);
temp varchar2 (255);
last_val number(9,0);
cursor c1 is Select distinct table_name from user_tab_cols order by table_name;
begin
FOR asd in c1
LOOP
temp := asd.table_name;
begin
execute immediate 'select max(id) from '||temp into last_val;
dbms_output.put_line('max(id) for table: ' ||temp||' = '||last_val);
exception when others then
dbms_output.put_line('Failed to get max(id) for table: ' ||temp);
end;
END LOOP;
end;
You can't use a variable for the table name.
What you can do is creating the complete sql statement as a string and use execute immediate
Here are some examples how to do that: http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/dynamic.htm#CHDGJEGD