Oracle Stored Procedure view sys_refcursor - oracle

I have an oracle stored procedure that is called from a third party reporting tool. The stored procedure is not returning any rows when it's executing.
I know for a fact the query returns results, it's just something is going wrong in the where clause with the parameters being passed from the website.
I'm trying to see the query that is being executed but the logs do not show the query, only that it's calling the stored procedure. I don't have access to the website code to do a response write and display the stored procedure or the parameters. Can you please provide guidance on how I can view the sys_refcursor from the stored procedure below? I'm using TOAD and when I use the toad script runner I don't see any results
Code
create or replace procedure dolphin.report_four
( p_1 char,
P_2 date,
p_recordset out sys_refcursor)
AS
Begin
Select
column_1,
column_2,
column_3
from dolphin.tank
where
column_1 = 'BAIT' and
column_2 = 'p_2'
end report_four;

Create a table for logging this procedure calls, and add INSERT statement within the procedure to add a row with parameters passed. Remember to COMMIT; after that.
Set the procedure query to:
select /*+ monitor MY_KEY_765746573*/
f1, f2, ...
from ...
Make the app to invoke the procedure.
Then run
select sql_id, sql_fulltext from v$sql where sql_fulltext like '%MY_KEY_'||'765746573%';
Then place SQL_ID found into the call:
select dbms_sqltune.report_sql_monitor('YOUR SQL_ID HERE') from dual;
I hope logging table records along with SQL monitor report give you a clue.

"The stored procedure is not returning any rows when it's executing."
The code as posted executes a select statement but does not pass anything to the REF CURSOR. If this was a real procedure it would through an error when you attempted to run it. Presumably you've made a bish of editing the source for publication on StackOverflow so it's hard to tell whether this situation is a reflection of your actual code, but it ought to do something like this:
create or replace procedure dolphin.report_four
( p_1 char,
P_2 date,
p_recordset out sys_refcursor)
AS
Begin
open p_recordset for
Select
column_1,
column_2,
column_3
from dolphin.tank
where
column_1 = p_1 and
column_2 = p_2;
end report_four;
Opening the REF CURSOR associates the parameter with the query result set.

Related

oracle sql developer ora-00904 stored procedure execution error

I have wrote simple stored procedure in Oracle SQL Developer but found, attached ,error on execution/run step.
Here is my code:
CREATE OR REPLACE PROCEDURE EMP_NAME (EMP_ID_IN IN VARCHAR2,
EMP_NAME_OUT OUT VARCHAR2)
AS
BEGIN
SELECT first_name
INTO EMP_NAME_OUT
FROM employee
WHERE emp_id = EMP_ID_IN;
END EMP_NAME;
It also shows this error
The procedure itself seems to be OK. However, its execution is somewhat strange.
I suggest you to run it from the Worksheet itself, such as
declare
l_out employee.first_name%type;
begin
emp_name(100, l_out);
dbms_output.put_line('Result = ' || l_out);
end;
/
Though, why is it a procedure? Wouldn't a function be a better choice? E.g.
create or replace function emp_name (emp_id_in in varchar2)
return employee.first_name%type
is
retval employee.first_name%type;
begin
select first_name
into retval
from employee
where emp_id = emp_id_in;
return retval;
end;
/
You'd run it in a simple manner, as
select emp_name(100) from dual;
There's something wrong with your data dictionary. edit: you're on DB 10g, I'm guessing object_id isn't in the all arguments view. When we go to execute a stored procedure, we ask the database for some information about your code.
SELECT data_type, argument_name name
FROM all_arguments a, all_objects o
WHERE a.object_id=o.object_id
AND o.object_name=? and o.owner=? and a.package_name is NULL
order by position
The error about an invalid object_id - that's coming from this query. What version Oracle Database are you running? Can you see your PL/SQL object in ALL_OBJECTS and do your arguments show up in ALL_ARGUMENTS?
I've taken your code and modified it for the HR.EMPLOYEES table.
It works as expected.
We run some code to be able to show you the two parameters.
I put in a value of '101' for employee number or ID, and hit OK.
Then the OUT parameter is displayed below in the Log panel.
If you open your log panel (view -> log), you'll see a 'Statements' page as well. It's there that you can see ALL the code we execute on the database. That's where I went to get the SQL that's failing for you on the OBJECT_ID. Go look at that, and walk the code and confirm what's not working.
To fix this, go find an OLD copy of SQLDev that supports 10g..like maybe 2.1, OR upgrade your DB to at least 11.2.0.4.

Create temporary tables in Oracle stored procedure to show in Crystal Reports

In SQL Server I can create stored procedures which creates a temp table, insert values into it, and then return a select from that temp table to be the result set for a composite Crystal Report.
I have no idea how to perform it in Oracle stored procedures.
I know I can create a string variable and then execute immediate. But then I don't know how to insert values, and that the result set will be the Crystal Report source.
You may try it using plsql procedure as follows.
CREATE PROCEDURE testRS (lcout OUT sys_refcursor) AS
BEGIN
OPEN lcout
FOR
SELECT object_name, object_type
FROM user_objects;
END testRS;
sys_refcursor is a weak cursor, meaning it can point to any query, and no type is enforced.
To execute under sqlplus (similar API should be available under crystal report), you will need to define a sqlplus variable, which holds resultset from cursor inside the procedure.
-- Define sqlplus variable
SQL> var ncc refcursor;
-- Call to procedure.
SQL> exec TESTPKG.testRS( :ncc );
PL/SQL procedure successfully completed.
-- Display the resultset.
SQL> print :ncc;
Hope it helps,
Dhimant

Log In procedure not working in oracle 11g

My table contain only two row. When i am giving empid and password of another row stil login is done. This is my procedure
CREATE OR REPLACE PROCEDURE prco_LoginCheck(Emp_Id IN number,
Cpassword In varchar2,
cur_out out Types.cursor_type) AS
BEGIN
open cur_out for
select count(*) from TBL_REGISTRATION a
where a.confirm_password= Cpassword and a.emp_id=Emp_Id;
END prco_LoginCheck;
Aside from the fact that storing a password in a table is a horribly insecure design (you should only be storing a hash of the password plus some random salt), and the fact that it doesn't make a lot of sense to define your own weak ref cursor type rather than using the built-in sys_refcursor (unless you really need to work with ancient versions of Oracle), and that returning a cursor from a procedure seems like a really odd way to do a login rather than writing a function that returns a boolean or some indicator, the problem is one of naming conventions.
When you write the SQL statement
select count(*)
from TBL_REGISTRATION a
where a.confirm_password= Cpassword
and a.emp_id=Emp_Id;
I assume that your intention is to compare the emp_id column in tbl_registration to the emp_id parameter. That is not actually what is happening, however. Your unqualified emp_id is resolved as a column in the table not the parameter. Normally, people use a naming convention to ensure that parameter names don't match column names. I, for example, generally use a p_ prefix for parameters and l_ for local variables. That would look something like
CREATE OR REPLACE PROCEDURE prco_LoginCheck(p_Emp_Id IN number,
p_password In varchar2,
p_cur_out out Types.cursor_type) AS
BEGIN
open p_cur_out for
select count(*)
from TBL_REGISTRATION a
where a.confirm_password= p_password
and a.emp_id=p_Emp_Id;
END prco_LoginCheck;
It is also possible to use your existing parameter names and just fully qualify the emp_id to force it to resolve to the parameter name
CREATE OR REPLACE PROCEDURE prco_LoginCheck(Emp_Id IN number,
Cpassword In varchar2,
cur_out out Types.cursor_type) AS
BEGIN
open cur_out for
select count(*)
from TBL_REGISTRATION a
where a.confirm_password= Cpassword
and a.emp_id=prco_LoginCheck.Emp_Id;
END prco_LoginCheck;

create trigger for copying values between tables in oracle

I am new to the sql. I want to create a trigger for copying values between tables.
basically, the task I want to finish is forwarding students' message table values to specific staff_maibox
here is the code.
drop trigger forward_msg_to_staff;
create or replace trigger forward_msg_to_staff
update on message
for each row
declare
message_id VARCHAR2(10);
client_id NUMBER(10);
staff_id NUMBER(5);
message_date DATE;
message_title VARCHAR2(20);
staff_mailbox VARCHAR2(255);
begin
insert into staff_mailbox(message_id, client_id, staff_id, message_date, message_title, staff_mailbox)
values(:new.message_id, :new.client_id, :new.staff_id, :sysdate, :new.message_title, :old.staff_mailbox)
end;
/
is this code correct?
Please advise. thanks in advance.
You're getting an error because you're missing either the BEFORE or AFTER keyword from the CREATE TRIGGER statement.
These are required as indicated in the documentation:
Additionally:
There's no need to declare all the variables, you're not using them
:sysdate is incorrect, you're not binding it. You can just use sysdate instead as you would in standard SQL or PL/SQL.
You're missing a semi-colon after the VALUES clause of the INSERT statement.
Putting this together your trigger may look like this
create or replace trigger forward_msg_to_staff
after update on message
for each row
begin
insert into staff_mailbox( message_id, client_id, staff_id, message_date
, message_title, staff_mailbox )
values ( :new.message_id, :new.client_id, :new.staff_id, sysdate
, :new.message_title, :old.staff_mailbox );
end forward_msg_to_staff;
/
Note that I've used the trigger name in the END as well. This is for convenience only, it makes it obvious where the trigger ends...
If you want to see what errors your're getting when you're creating a trigger use show errors as a_horse_with_no_name suggests. This shows any compilation errors, which is invaluable for tracking them down.

Populate an oracle collection type using a SYS_REFCURSOR and close the cursor

In my stored procedure, I have a code snippet like this:
OPEN p_result FOR
SELECT *
FROM TABLE (CAST ( l_data AS Rpt_mapping_TableType));
COMMIT;
p_result is an IN OUT parameter of type SYS_REFCURSOR.Rpt_mapping_TableType is a user defined collection type.
So this cursor will just populate the Rpt_mapping_TableType and then the program that calls this proc will read the results from Rpt_mapping_TableType.
My question is what is the use of COMMIT in this snippet? The code author says it is a way of closing the cursor. Is it right? My other question is if I just want to populate the collection , do I even need to do OPEN p_result FOR. After all I am not reading anything from the cursor so :
SELECT * FROM TABLE (CAST ( l_data AS Rpt_mapping_TableType));
should suffice.
No?
A commit will not close a cursor. If it did, then your code wouldn't work. (Although it could unlock rows from a FOR UPDATE, causing other problems.) Here's an example of a commit not closing a cursor:
SQL> variable test refcursor
SQL> begin
2 open :test for select 1 from dual;
3 end;
4 /
PL/SQL procedure successfully completed.
SQL> commit;
Commit complete.
SQL> print test;
1
----------
1
SQL>
If you just want to populate a collection, you're probably better off using something like SELECT ... BULK COLLECT INTO ... instead. (And possibly using a LIMIT.) The keyword CURSOR is frequently over-used. Unless you're passing data to another program, implicit cursors and bulk collects are usually much simpler and faster.

Resources