Reputation: 1515
I'm trying to print a table via DBMS_OUTPUT.PUT_LINE
with dynamic SQL and loop, because my table name must be a variable because it will change each month, below, is my code,
I'm also confused about how how to store the data and how to put it inside the variable? shall the variable need to be a CURSOR? for testing purposes in my code below I'm using the demo employee
table in HR
schema
.
Also, the is there is another data type bigger than varchar2(4000) because I need to store my SQL statement into a variable to use execute immediately
and that variable needs to store a very big complex SQL query .
SET SERVEROUTPUT ON SIZE 1000000;
DECLARE
v_TBL_NAME varchar2(200):='EMPLOYEES';
v_sql varchar2(200):='IS select * from ' ||v_TBL_NAME;
CURSOR C1;
BEGIN
EXECUTE IMMEDIATE v_sql INTO C1;
FOR REC IN C1
LOOP
DBMS_OUTPUT.PUT_LINE(REC.EMPLOYEE_ID||' '||REC.FIRST_NAME);
END LOOP;
END;
/
Upvotes: 1
Views: 4307
Reputation: 191570
You could use the open ... for
cursor syntax:
declare
v_tbl_name varchar2(30) := 'EMPLOYEES'; -- assume this will be a parameter later
v_sql varchar2(32767) := 'select employee_id, first_name from ' || v_tbl_name;
-- if there is a static table you could use %rowtype, or your own type with column%type
type t_rec is record (employee_id number, first_name varchar2(20));
v_rec t_rec;
c1 sys_refcursor;
begin
open c1 for v_sql;
loop
fetch c1 into v_rec;
exit when c1%notfound;
dbms_output.put_line(v_rec.employee_id||' '||v_rec.first_name);
end loop;
end;
/
100 Steven
101 Neena
102 Lex
103 Alexander
104 Bruce
...
205 Shelley
206 William
PL/SQL procedure successfully completed.
Hopefully you are specifying the columns you actually want, and not using *
...
Depending on your application/client you could access the ref cursor directly; this syntax works in SQL*Plus, SQL Developer, SQLcl and possibly some third-party clients:
var rc refcursor;
declare
v_tbl_name varchar2(200) := 'EMPLOYEES'; -- assume this will be a parameter later
v_sql varchar2(200) := 'select * from ' || v_tbl_name;
begin
open :rc for v_sql;
end;
/
print rc
which produces output like:
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
----------- -------------------- ------------------------- ------------------------- -------------------- ---------- ---------- ---------- -------------- ---------- -------------
100 Steven King SKING 515.123.4567 1987-06-17 AD_PRES 24000 90
101 Neena Kochhar NKOCHHAR 515.123.4568 1989-09-21 AD_VP 17000 100 90
102 Lex De Haan LDEHAAN 515.123.4569 1993-01-13 AD_VP 17000 100 90
...
205 Shelley Higgins SHIGGINS 515.123.8080 1994-06-07 AC_MGR 12000 101 110
206 William Gietz WGIETZ 515.123.8181 1994-06-07 AC_ACCOUNT 8300 205 110
107 rows selected.
You can access the ref cursor from JDBC etc.
Upvotes: 1
Reputation: 1599
You can use a reference cursor and bulk collect into a nested table. Then loop over the table like this:
DECLARE
TYPE lt_record IS RECORD
(
empID INTEGER,
fname VARCHAR2(100)
);
TYPE lt_recordTable IS TABLE OF lt_record;
l_cTableCursor SYS_REFCURSOR;
l_sTableName VARCHAR2(1000) := 'TABLE NAME';
l_tRecords lt_recordTable;
BEGIN
OPEN l_cTableCursor FOR ('SELECT employee_id, first_name FROM '||l_sTableName);
LOOP
FETCH l_cTableCursor
BULK COLLECT INTO l_tRecords
LIMIT 1000;
EXIT WHEN l_tRecords.COUNT = 0;
FOR i IN 1..l_tRecords.LAST LOOP
dbms_output.put_line(l_tRecords(i).empID||' '||l_tRecords(i).fname);
END LOOP;
END LOOP;
CLOSE l_cTableCursor;
END;
/
Upvotes: 3