How to call a function inside a cursor in pl/sql? - plsql

I have declared a function which is returning some string as
function(varchar2) return varchar2;
I want this function to be called from inside of a cursor like
open p-cursor for select * from employee where emp_name = function(ssn).
But it throws some error.
The query being used in cursor is working fine when executed separately.

When you say you have "declared" a function do you mean like this?
declare
function f (p varchar2) return varchar2
is
begin
...
end;
begin
open p_cursor for select * from employee where emp_name = function(ssn);
...
end;
You can't use a function like that in SQL. You would have to create the function in the database so that it can be used outside the PL/SQL program - for example:
create or replace function f (p varchar2) return varchar2
is
begin
...
end;
Or if you are creating a package then you can make the packaged function public like this:
create or replace package pkg is
function f (p varchar2) return varchar2;
...
end;
Then it can be used in other code like this:
open p_cursor for select * from employee where emp_name = pkg.f(ssn);

I am pretty sure you cannot use a group function in a where clause. But this function(ssn) being not a group function cannot also be used here.
You can use it as a sub query, serves the purpose.
open p-cursor for select * from employee where emp_name = (select package_name.function_name(ssn) from dual);

Related

How to return two table in PostgreSQL

I'm new in POSTGRESQL and I am creating PostgreSQL functions, and now I want to create a function which returns two table output, I created and it does not work
my function
CREATE FUNCTION getData() RETURNS setof refcursor AS
$$
DECLARE c_top_items refcursor;
DECLARE c_shopping_cart refcursor;
BEGIN
OPEN c_top_items FOR
SELECT t.name
FROM employee t
LIMIT 10;
RETURN NEXT c_top_items;
OPEN c_shopping_cart FOR
SELECT c.name
FROM employee c
LIMIT 5;
RETURN NEXT c_shopping_cart;
END;
$$ LANGUAGE plpgsql;
Please help!!
When you call getData you get two cursors, fetch all from them. I modified the example in the documentation and fetched the data with:
select * from getData();
fetch all in "<unnamed portal 1>";
fetch all in "<unnamed portal 2>";
But you would probably be better off by changing the signature of the function according to the return multiple cursors-example in the documentation. This is that example:
CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$
BEGIN
OPEN $1 FOR SELECT * FROM table_1;
RETURN NEXT $1;
OPEN $2 FOR SELECT * FROM table_2;
RETURN NEXT $2;
END;
$$ LANGUAGE plpgsql;
-- need to be in a transaction to use cursors.
BEGIN;
SELECT * FROM myfunc('a', 'b');
FETCH ALL FROM a;
FETCH ALL FROM b;
COMMIT;
See: Returning Cursors

trying to implement dynamic sql via function call

I am recently implementing the dynamic sql in my cide and quite new to the concept. I was trying with the following function that will take the column name and update the value via dynamic function call.However the function gives out an error while compiling.Please find the code as below:
function upd_tab(col_name in varchar2,val in number)
return pls_integer
is
BEGIN
EXECUTE IMMEDIATE 'UPDATE EMPLOYEE1 SET '||col_name||'= :THE_VALUE WHERE EMP_NAME IN(:NAME1,:Nme2)'
using val,john,aaron;
RETURN SQL%ROWCOUNT;
END;
Thank you in advance for your help.
Here you have to declare variables in the using clause. Hope below snippet helps.
FUNCTION upd_tab(
col_name IN VARCHAR2,
val IN NUMBER)
RETURN pls_integer
IS
BEGIN
EXECUTE IMMEDIATE 'UPDATE EMPLOYEE1 SET '||col_name||'= :THE_VALUE WHERE EMP_NAME IN(:NAME1,:Nme2)' USING val,'john','aaron';
RETURN SQL%ROWCOUNT;
END;

expression is of wrong type

I am trying to create a function that returns all values of the emp table Why do I get the error?
create or replace FUNCTION EMP_value
RETURN VARCHAR2
is
CURSOR a is select * from emp;
v_all emp%rowtype;
begin
open a;
LOOP
fetch a into v_all;
exit when a%notfound;
dbms_output.put_line(v_all.empno|| ' ' ||v_all.ename|| ' ' ||v_all.sal);
RETURN V_ALL;
end loop;
close a;
end;
Try to simplify your code as much as possible. If you want to return all the attributes of cursor from function, try using BULK collect and return it as complex data type. Here in this case its nested table type. Hope it helps.
--Create a schema level nested table type function
CREATE OR REPLACE TYPE emp_obj IS OBJECT
(
EMPNO NUMBER,
ENAME VARCHAR2(100),
SAL NUMBER,
MGR_NO NUMBER,
HIREDATE DATE
)
/
CREATE OR REPLACE TYPE emp_tab IS TABLE OF emp_obj
/
--Funtion to return all attributes from EMP tab
CREATE OR REPLACE FUNCTION EMP_value
RETURN emp_tab
AS
e_tab emp_tab;
begin
SELECT * BULK COLLECT INTO e_tab
FROM EMP;
RETURN e_tab;
end;
/

Invalid Object Name Error in Function in SQL

I have following function defined
alter FUNCTION [dbo].[GetXMLValues](#business_id int, #id varchar(30))
RETURNS varchar(30)
AS
BEGIN
declare #xmlValue varchar(30)
set #xmlValue = (SELECT top 1000 T.Content.value('(/XmlDataPairDocument/dataitem[#id=sql:variable("#id")]/#value)[1]', 'VARCHAR(100)')
FROM tblApplications T where t.business_id =#business_id)
return #xmlValue
END
WHen i hit F5 command Executes Successfully/...
but when i try to execute it using following query :
select * from [GetXMLValues](1,'sadfj')
it shows an error saying : Invalid object name 'GetXMLValues'.
what is the reason ? and what is error??
This is a Scalar function, not a Table-Valued function.
select dbo.[GetXMLValues](1,'sadfj')
should work.
You can't treat this like a table, i.e. select * ..., you need to just select the result directly as above.
See Types of Functions for more details.
As mentioned by t-clausen.dk and Ian Preston, it's because you have a Scalar function and not a table valued function.
I just wanted to extend on t-clausen.dk's post which switches your function to a multi-statement table valued function. I would take this a step further and actually use an inline table valued function:
ALTER FUNCTION [dbo].[GetXMLValues](#business_id int, #id varchar(30))
RETURNS TABLE
AS
RETURN (
SELECT top 1000 T.Content.value('(/XmlDataPairDocument/dataitem[#id=sql:variable("#id")]/#value)[1]', 'VARCHAR(100)')
FROM tblApplications T where t.business_id =#business_id
)
Which you then use in the same way:
select xmlValue from dbo.[GetXMLValues](1,'sadfj')
Check out:
Query performance and multi-statement table valued functions
your function is not returning a table, it is returning a varchar(30). The correct syntax to use your function would be:
select [dbo].[GetXMLValues](1,'sadfj')
Try function this instead:
ALTER FUNCTION [dbo].[GetXMLValues](#business_id int, #id varchar(30))
RETURNS #t table (xmlValue varchar(30))
AS
BEGIN
insert #t (xmlValue)
SELECT top 1000 T.Content.value('(/XmlDataPairDocument/dataitem[#id=sql:variable("#id")]/#value)[1]', 'VARCHAR(100)')
FROM tblApplications T where t.business_id =#business_id
return
end
Then you can call your function this way:
select xmlValue from dbo.[GetXMLValues](1,'sadfj')
Or if you do want a table function, try changing your function to be something like this - then you can use select * from...
ALTER FUNCTION [dbo].[GetXMLValues](#business_id int, #id varchar(30))
RETURNS
#outputTbl_xmlValue table
(
xmlValue varchar(30)
)
AS
BEGIN
INSERT #outputTbl_xmlValue SELECT top 1000 T.Content.value('(/XmlDataPairDocument/dataitem[#id=sql:variable("#id")]/#value)[1]', 'VARCHAR(100)')
FROM tblApplications T where t.business_id =#business_id)
return
END
GO
ALTER FUNCTION Isnulldate(#maxdate1 DATETIME,
#maxdate2 DATETIME,
#maxdate3 DATETIME)
returns DATETIME
AS
BEGIN
DECLARE #date DATETIME
IF #maxdate3 IS NOT NULL
BEGIN
SET #date=#maxdate3
RETURN #date
END
IF #maxdate2 IS NOT NULL
BEGIN
SET #date=#maxdate2
RETURN #date
END
IF #maxdate1 IS NOT NULL
BEGIN
SET #date=#maxdate1
RETURN #date
END
RETURN #date
END
## Execution ##
DECLARE #dateim DATETIME=Getdate()
SELECT dbo.Isnulldate(NULL, NULL, #dateim)

How can I create and return a cursor from a plsql function?

I created a plsql function and I want to create a cursor and return this cursor from the function. Then I want to call this function in a Java class and retrieve data from the cursor. Note: the cursor returns one row.
I wrote something like this,,
CREATE OR REPLACE
FUNCTION FUNCTION1 ( emp_id IN NUMBER)RETURN cursor AS
cursor newCursor(e_id number) is
select * from table1 where employee_id = e_id;
type refCursor is ref cursor;
BEGIN
open newCursor(emp_id);
loop
exit when newCursor%notfound;
fetch newCursor into refCursor;
end loop;
RETURN refCursor;
END FUNCTION1;
What return type should I use if I want to return a cursor?
Model it after the following function which works
create or replace function getemps return sys_refcursor is
v_curs sys_refcursor;
begin
open v_curs for select ename from emp;
return v_curs;
end;
/
sys_refcursor is oracle's generic implicit cursor
use EXPLICITE cursor instead

Resources