Query on Triggers - oracle

Created One Trigger in Oracle..
SQL> CREATE OR REPLACE TRIGGER student_after_insert
2 AFTER INSERT
3 ON student
4 FOR EACH ROW
5 BEGIN
6 #hello.pl
9 END student_after_insert;
10 /
Contents of hello.pl are:-
BEGIN
DBMS_OUTPUT.PUT_LINE('hello world');
END;
And.. the result is pretty good, as the content of hello.pl is displayed on screen while inserting a record..
Now, the query is -- When i change the content of the hello.pl file, after exiting from oracle, and then logging again, It doesn't shows the updated contents, instead it shows the previous content..
I noticed that, if i drop the trigger and create it again, then it is working fine.. Why is it happening so.. And what is the solution to this problem..

It happens because the # works much like the #include in a c/c++ preprocessor, that is, SQL*Plus inserts the content of the file hellp.pl at compile time.
If you want to output the content of a file when the trigger is fired, you might want to look into utl_file.
But it's probably easier for you to create a package similar to
create or replace package trigger_content as
text varchar2(100);
end;
/
You can then dynamically alter the value of text:
exec trigger_content.text := 'hello world';
and print the value of text with
dbms_output.put_line(trigger_content.text);
However, the latter "solution" doesn't work across sessions.

#hello.pl simply includes the text of hello.pl in the body of the CREATE...TRIGGER command. There is no link from Oracle to the file.
Note that, in the general case, the Oracle server is on another machine and has no access to the contents of your hard drive.

Look into EXECUTE IMMEDIATE and DBMS_SQL for dynamic coding.

Related

Error 500 returned from ORDS when creating a procedure that uses APEX_JSON within APEX's SQL Commands

The test case is as follows:
CREATE OR REPLACE PROCEDURE TEST IS
BEGIN
APEX_JSON.OPEN_OBJECT();
APEX_JSON.CLOSE_OBJECT();
END;
I get a 500 error from ORDS running it from APEX's SQL Commands or SQL Scripts. I'm not sure if there's something else needed here or the recommendation is simply do not use APEX_JSON in procedures. I hope someone can chime in.
Just to clarify: I'm running this on an Oracle Cloud ATP instance, this seems to work fine in on-premise instances but not here.
EDIT 1
I had already tried something similar to Ergi Nushi's answer but to no avail. I even thought my code was wrong and tried his instead but it didn't work either (See screenshot below)
EDIT 2
So far what I have done to get my project going is to use the 12c JSON APIs instead like in:
-- ...
L_JSON := JSON_OBJECT(
KEY 'test' VALUE L_TEST_VALUE
NULL ON NULL
RETURNING VARCHAR2(32767)
);
-- ...
I know this is not the answer I was looking for but hopefully, it helps someone to get going.
First you need to initialize your APEX_JSON with:
APEX_JSON.initialize_clob_output();
After building your object you should get output with
APEX_JSON.get_clob_output();
and then free output in order to use it for other objects:
APEX_JSON.free_output();
Full code:
CREATE OR REPLACE PROCEDURE TEST IS
output CLOB;
BEGIN
APEX_JSON.initialize_clob_output();
APEX_JSON.OPEN_OBJECT();
APEX_JSON.CLOSE_OBJECT();
output := APEX_JSON.get_clob_output(); --> pass the output to a variable
APEX_JSON.free_output();
END;

Oracle 11g - sys_refcursor

I am working on a system where Oracle 11g is the back end database.
I have very limited permissions on the database and as such all I can do is call procedures that reside in packages.
Gerally, these procedure return their result set via an OUT parameter of type sys_refcursor.
I can call them fine in C# and get data from the cursor via the C# OracleDataset type.
Here is my question.
I want to be able to run these procedures and see the results via SQL Developer.
I can execute the procedure fine, but seeing the contents of the sys_refcursor OUT parameter is boggling me.
I've done some gooling and people ar saying about creating type and other solutions I simply do not have the permissions to persue.
So, how can I possibly see the result set contained in a sys_refcursor?
So say I have a procedure with this signature....
procedure an_oracle_Proc(p_ref IN varchar2,
p_result_set OUT sys_refcursor);
I call it like this....
DECLARE
l_ref VARCHAR2(10);
l_result_set sys_refcursor;
BEGIN
oracle_pkg.an_oracle_Proc(p_ref => l_ref,
p_result_set => l_result_set);
--How to select from l_result_set with limited permissions
END
How can I look at the contents of l_result_Set?
This is repeating the answer I linked to before really but specifically for your code:
VARIABLE result_set refcursor;
DECLARE
l_ref VARCHAR2(10);
BEGIN
l_ref := 'whatever';
oracle_pkg.an_oracle_Proc(p_ref => l_ref,
p_result_set => :result_set);
END;
/
PRINT result_set
... and run all of that as a script from an SQL Worksheet. The contents of the ref cursor will be shown in the script output window.
Thought I'd have another look and found this - amazing what stepping away from the computer can do. ;)
I just have to select the appropriate variable on the left pane.
http://www.thatjeffsmith.com/archive/2011/12/sql-developer-tip-viewing-refcursor-output/
Still - it would be nice to write my own SQL to do this rather than using the execute window.
Sys_refcursor form an anonymous block is bit tricky. Use the sql-developer, explore the package or procedure , right click and execute the procedure/package.
Sql-developer will open an input/output UI where you can key in values. And you can see the output on the same UI as well. Let me know if you need more details. I was actually debugging the same a couple of weeks back successfully.

How do I pass a cursor value when calling a stored procedure?

This is only my second time diagnosing a PL/SQL procedure. I need to test the code in the stored procedure, and I'm trying to call it in SQL Developer. I have run the error details report, and the code has no obvious bugs in it.
So now I am trying to run it through a test window so I can see if the output is correct. However I can't seem to get the right argument for the 3 parameter. Here are the parameters in the the procedure.
CREATE OR REPLACE PROCEDURE ADVANCE.WW_DEATHDATE_REPORT(begindate varchar2, enddatevarchar2, RC1 IN OUT du_refCUR_PKG.RC) AS
Here is the Code I am trying to use to call the procedure. What do I need to do to get it to run correct? I keep getting error messages saying I'm using a wrong value in the parameter.
BEGIN
ADVANCE.WW_DEATHDATE_REPORT('20100101','20150101',du_refcur_pkg);
END;
There are multiple ways to do this, one way is like the below,
DECLARE
du_refcur_pkg SYS_REFCURSOR;
BEGIN
OPEN du_refcur_pkg FOR SELECT ... ;
ADVANCE.WW_DEATHDATE_REPORT('20100101','20150101',du_refcur_pkg);
END;
Another way would be,
BEGIN
ADVANCE.WW_DEATHDATE_REPORT( '20100101','20150101', CURSOR (SELECT ... ) );
END;

Creating a trigger in Oracle Express

I was trying to do something like auto-increment in Oracle 11g Express and SQL Developer.
I know very little about Oracle and I am also new to triggers.
I tried running this, but I don't know how to do it properly.
CREATE TABLE theschema.thetable
(id NUMBER PRIMARY KEY,
name VARCHAR2(30));
CREATE SEQUENCE theschema.test1_sequence
START WITH 1
INCREMENT BY 1;
create or replace trigger insert_nums
before insert on theschema.thetable
for each row
begin
select test1_sequence.nextval into :new.id from dual;
end;
/
When I try to create the trigger, I get a screen which asks me for some "binds".
The dialog box has only one check box "null". What does this mean and how do I make
a script that works properly?
Any precautions to take while doing this kind of "auto-increment" ?
It seems that SQL Developer thinks that you are running a plain DML (data manipulation) script, not a DDL (data definition). It also thinks that :new.id is a bindable variable.
Why this happens, I don't know; I can't reproduce it in Oracle SQL Developer 2.1.
Try to open a new SQL worksheet window in the theschema schema and execute a "whole" script (not a statement) by pressing F5 (not F9).
This is how I have solved this problem, put "set define off;" before the command:
set define off;
create or replace trigger [...]
[...]
end;
/
Then highlight both commands and press F9 to run.
Or you could run all the commands with F5.
It seems, that if the commands are executed separetly with F9, then the set define off does not take affect.
For my case, solution was entering "newrow" for 'new' and "oldrow" for 'old' as values for the binds...
I am a novice at this so keep that in mind as I give my answer.
I think the issue is that the code
create or replace trigger insert_nums
before insert on theschema.thetable
for each row
begin
select test1_sequence.nextval into :new.id from dual;
end;
Is actually a script and not straight forward SQL statement. Hence you have to run the "Run Script". I discovered that when I had a worksheet open in SQL Developer that if I had anywhere in the worksheet the any code for trigger like above then even I just tried to run a statement that SQL Developer would look back in the worksheet and try to run the script. To stop that from happening I had to comment out the code.
And If I did want to run the code for the trigger than I had to open a new worksheet, place the code there and do a RUN SCRIPT.

Quick-n-dirty results: View results of Procedure OUT cursor in SQL Worksheet?

Platform: Oracle
Language: PL/SQL
Issue: Want to output a procedure OUT cursor into the SQLDeveloper SQLWosksheet.
Anyone know how to use the Oracle "Select * from Table( PipelinedFunction( Param ) ) " to check procedure code output cursors?
I am using Crsytal Reports off of an Oracle stored procedure. Crystal requires that a procedure return a cursor, which it fetchs and reads.
The procedure code I have is currently working, but I want to find the easiest way to view the effects of changes to the procedure code. I have SQLDeveloper available, and I'm doing my creation and sql testing in that. I would like to get a quick result visible in the SQL Developer Query Result window ("SQL Worksheet").
Is there a (simple) way to use a Function to read the cursor from the procedure? (and pipe that out to the Table function?)
Convoluted, I know, but I deal best when I can just see the results of code changes. If I can view the record results directly, it will speed up development of the report.
I know of the Table function and a little about pipelining in Oracle. I know a little about cursors in general and sys_refcursor. I know diddly about types and why I need them. (Isn't sys_regCursor supposed to get us away from that?)
The current procedure does an adequate but ungraceful series of queries, inserts to global temp tables (GTT), joins from GTT and original tables, more inserts, and more self-joins and then SELECTS the results into the OUT cursor. I might be able to do better relying on just cursors and such, but the current method is good enough to get results to the report.
I think I can handle SQL pretty well (for our purposes), but I am not an Oracle-specific developer... but I need help.
Anybody run across this? The whole idea was to speed my development for the procedure code, but I've spent a couple of days looking for a way to just get at the output... not what I had in mind.
Update:
I have tried some hare-brained schemes based on slivers that I've seen on the web... such as
Create or replace FUNCTION GET_BACKPLANE (
Node VARCHAR2 ) RETURN SYS_REFCURSOR
AS
RESULTS SYS_REFCURSOR;
BEGIN
Open Results for
Select Backplane(Results, Node) from Dual ;
... etc.
and
Create or replace Function GET_BACKPLANE (
NODE VARCHAR2 ) RETURN My_Table_Stru%ROWTYPE PIPELINED
AS
BEGIN ...
I don't think that Oracle is even considering letting me re-reference the output cursor from the procedure ("Results" is a sys_refcursor that holds the results of the last SELECT in the procedure). I don't know how to define it, open it, and reference it from the procedure.
I never got to the place where I could try
SELECT * FROM TABLE(GET_BACKPLANE( ... etc )
Sorry for any typos and bad Oracle Grammar... it's been a long several days.
SQL Developer allows us to use SQL*Plus commands in the Worksheet. So all you need to do is define a variable to hold the output of the ref cursor.
I may have misinterpreted the actual code you want to run but I'm assuming your actual program is a procedure Backplane(Results, Node) where results is an OUT parameter of datatype sys_refcursor and node is some input parameter.
var rc refcursor
exec Backplane(results=>:rc, Node=>42)
print rc
The output of the print statement is written to the Script Output pane.
Note that the use of SQL*Plus commands means we have to use the Run Script option F5 rather than execute statement.
Thanks for the help. In the end, I wound up brute-force-ing it...
Step by step:
Make a query, test a query,
create a global temp table from the structure,
add code to make another query off of that GTT, test the query,
create a global temp table from the structure,
etc.
In the end, I wound up running (anonymous block) scripts and checking the GTT contents at every stage.
The last part was to use the same last query from the original procedure, stuffing everything into the Cursor that crystal likes...
tomorrow, I test that.
But, I'll just force it through for the next procedure, and get it done in a day and a half instead of 2+ weeks (embarrassed).
Thanks,
Marc

Resources