问题
I want to print data of Cursor_pkg.c1.row_emp
, for ex:Cursor_pkg.c1.row_emp.last_name
that would be exist in Cursor_pkg.row_emp
after Cursor_pkg_func.Print_Cur
procedure would work. How can I do it?
- I create PACKAGE with cursor and rec
- I create PACKAGE with procedure that fetch cursor data in rec
- I want to output fetched data. How?
There is two questions: I want to output data from package emp_rec
(row) and I want to output it directly from PACKAGE Cursor_pkg_func
procedure
P.S. The main idea is storing data and procedure/function for fetching and selecting data
CREATE OR REPLACE PACKAGE Cursor_pkg AUTHID DEFINER IS
CURSOR C1 IS
SELECT last_name, job_id FROM employees
WHERE job_id LIKE '%CLERK%' AND manager_id > 120
ORDER BY last_name;
row_emp C1%ROWTYPE;
END Cursor_pkg;
/
CREATE OR REPLACE PACKAGE Cursor_pkg_func IS
PROCEDURE Print_Cur;
END Cursor_pkg_func;
/
CREATE OR REPLACE PACKAGE BODY Cursor_pkg_func IS
PROCEDURE Print_Cur IS
BEGIN
OPEN Cursor_pkg.C1;
LOOP
FETCH Cursor_pkg.C1 INTO Cursor_pkg.row_emp;
EXIT when Cursor_pkg.C1%NOTFOUND;
DBMS_OUTPUT.put_line(Cursor_pkg.row_emp.last_name);
END LOOP;
CLOSE Cursor_pkg.C1;
END;
END;
/
BEGIN
Cursor_pkg_func.Print_Cur;
END;
But I want to select and print from Cursor_pkg.row_emp PACKAGE without created function. And how to print not only last_name but all row? Errors start with: What's wrong with last three statements?
CREATE OR REPLACE PACKAGE Cursor_pkg_func IS
TYPE outrec_typ IS RECORD (
var_char2 VARCHAR2(30)
);
TYPE outrecset IS TABLE OF outrec_typ;
FUNCTION f_trans (p in number ) RETURN outrecset PIPELINED;
END Cursor_pkg_func;
/
CREATE OR REPLACE PACKAGE BODY Cursor_pkg_func IS
FUNCTION f_trans (p in number) RETURN outrecset PIPELINED IS
out_rec outrec_typ;
BEGIN
OPEN Cursor_pkg.C1;
LOOP
FETCH Cursor_pkg.C1 INTO Cursor_pkg.row_emp;
EXIT when Cursor_pkg.C1%NOTFOUND;
END LOOP;
LOOP
out_rec.var_char2 := Cursor_pkg.row_emp.last_name;
PIPE ROW(out_rec);
DBMS_OUTPUT.put_line(out_rec.var_char2);
END LOOP;
CLOSE Cursor_pkg.C1;
RETURN;
END f_trans;
END Cursor_pkg_func;
/
begin
Cursor_pkg_func.f_trans(5);
end;
/
回答1:
You have defined a pipelined function, and this is not the way to call it:
SQL> begin
2 Cursor_pkg_func.f_trans(5);
3 end;
4 /
Cursor_pkg_func.f_trans(5);
*
ERROR at line 2:
ORA-06550: line 2, column 1:
PLS-00221: 'F_TRANS' is not a procedure or is undefined
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored
SQL>
You need to use a TABLE() function. Although then you will discover the bug in your code:
SQL> select * from table(Cursor_pkg_func.f_trans(5))
2 /
SMITH
SMITH
SMITH
''''
SMITH
SMITH
SMITH
SMITH
ERROR:
ORA-00028: your session has been killed
273660 rows selected.
SQL>
Note I had to kill that session from another session, otherwise it would still be running. So let's simplify the function and get rid of that pointless second loop ....
CREATE OR REPLACE PACKAGE BODY Cursor_pkg_func IS
FUNCTION f_trans (p in number) RETURN outrecset PIPELINED IS
out_rec outrec_typ;
BEGIN
OPEN Cursor_pkg.C1;
LOOP
FETCH Cursor_pkg.C1 INTO Cursor_pkg.row_emp;
EXIT when Cursor_pkg.C1%NOTFOUND;
out_rec.var_char2 := Cursor_pkg.row_emp.last_name;
PIPE ROW(out_rec);
END LOOP;
CLOSE Cursor_pkg.C1;
RETURN;
END f_trans;
END Cursor_pkg_func;
/
.... then lo!
SQL> select * from table(Cursor_pkg_func.f_trans(5))
2 /
VAR_CHAR2
------------------------------
ADAMS
JAMES
MILLER
SMITH
SQL>
"When I add begin and end; select not work"
You have created a pipelined function. Why did you do that? The reason you ought to have done that was because you wanted a PL/SQL function which could be used in the FROM clause of a SELECT statement. That is the use case for pipelined functions. So putting the call into an anonymous PL/SQL block really doesn't make sense.
But anyway.
Please read the documentation. It is quite comprehensive, it is online and free. The pertinent section in the PL/SQL Reference is the chapter on Static SQL. It makes clear that SELECT statements in PL/SQL must always fetch records into a variable of some description. Anonymous PL/SQL blocks are just the same as stored procedures in this regard. Find out more.
来源:https://stackoverflow.com/questions/18035778/select-data-from-cursor-of-package-print-it