I am trying to call my procedure inside a trigger.
The trigger is created successfully but the procedure is calling being called.
I am using oracle 10g with SQL developer tool.
I have tried to see the dbms_output but nothing shows in DBMS_OUTPUT console except"set serveroutput on" when i update the table.
My trigger is
create or replace
TRIGGER trig_sample
AFTER UPDATE
ON sample_table
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
SAMPLE_PROC(:NEW.PARAM1, :NEW.PARAM2 ,:NEW.PRAMA3);
END;
procedure is
CREATE or REPLACE Procedure SAMPLE_PROC(PARAM1 NUMBER,PARAM2 NUMBER,PARAM3 varchar2)
BEGIN
DBMS_OUTPUT.put_line('test : '||test);
UPDATE SAMPLE_TABLE SET STATUS = 'VA'
WHERE SAMPLE_ID = '2012';
END;
In my procedure i have used DBMS_OUTPUT.put_line('test : '||test);
but could not see any output. Please provide any suggestions to view the DBMS output in console and how to check the trigger is called or not?
Related
I would like to audit specific procedure for specific user.
For example i have a stored procedure prc_user_error and i have user which name of Ktd.
When the Ktd user execute prc_user_error procedure should be audited.
I cant use trigger. Also fine grained auditing cant use for execute.
Can you please help me ?
Thanks,
How about setting up your procedure like this and test for the name(s) and exit without doing anything in your procedure. If coded correctly than nothing should be printed in my example
create or replace procedure sp as
v_user varchar2(32) := SYS_CONTEXT( 'USERENV', 'SESSION_USER' );
begin dbms_output.put_line(v_user);
end;
/
begin
sp;
end;
IDK how you want to audit it, but assume to insert a record into some table:
create table myAudit( auditTime TIMESTAMP, auditUser VARCHAR2(30));
in procedure:
insert into myAudit values (SYSTIMESTAMP, SYS_CONTEXT ('USERENV','SESSION_USER') );
I am using SQL developer. I have a stored procedure that is running a long time. I need to trace what happens during that run time.
I tried with DBMS_output.put_line('trace');. But it print after the stored procedure has completed. Also I can't use DBMS_trace (might be older version I am using).
So I came up with idea. I would like to insert into table during stored procedure run time. How can I Commit only that insert query in stored procedure?
I see two possibilities.
Either you write a procedure which inserts log messages into a table. Declare this procedure with PRAGMA AUTONOMOUS_TRANSACTION:
CREATE OR REPLACE PROCEDURE WriteLogMsg(LogMessage IN VARCHAR2) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO T_LOG_ENTRIES (LOG_DATE, LOG_MESSAGE)
VALUES (CURRENT_TIMESTAMP, LogMessage);
COMMIT;
END WriteLogMsg;
Or use the DBMS_APPLICATION_INFO package:
PROCEDURE LONG_RUNNING_PROCEDURE IS
BEGIN
DBMS_APPLICATION_INFO.SET_MODULE('LONG_RUNNING_PROCEDURE', 'Starting');
...
DBMS_APPLICATION_INFO.SET_ACTION('Still working, please be patient');
...
DBMS_APPLICATION_INFO.SET_ACTION('Finished');
-- DBMS_APPLICATION_INFO.SET_MODULE(NULL, NULL); -> removes entries for MODULE and ACTION
END;
While the procedure is running you can query information with
SELECT USERNAME, MODULE, ACTION
from V$SESSION
where USERNAME = ...;
In this case you have to use the Pragma Autonomous transactions.
Create a new procedure with Pragma Autonomous.
PROCEDURE test_autonomous
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
insert ....
commit;
END test_autonomous;
now call this procedure in your code. this will do your trick. You can all use the parameters to pas some data you want to insert.
I am using sqlplus and have a table named users from which I wish to retrieve all values with the help of a stored procedure in oracle. Here is what I am trying to do -
create or replace procedure getall(prc out sys_refcursor)
is
begin
open prc for select * from users
end;
/
When I hit return after this, I get the following error -
Warning: Procedure created with compilation errors.
Why does this happen? And how do I get the desired output? Help much appreciated!
To see the compilation errors use the show errors SQL*Plus command (which also works in SQL Developer), or query the user_errors view which works with any client. You can also query all_errors to see problems with objects that are not in your schema.
But you are just missing a semicolon after the select:
create or replace procedure getall(prc out sys_refcursor)
is
begin
open prc for select * from users;
end;
/
You'll need a bind variable to be able to see the output in SQL*Plus, e.g.:
variable rc refcursor;
exec getall(:rc);
print rc
Notice the colon before the rc in the procedure call, which shows it's a bind variable reference. And exec is a shorthand anonymous block.
You might find it simpler to have a function that returns a ref cursor, or a pipelined function; or just query the table directly of course.
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
I'm trying to code a stored procedure in Oracle. I don't have a ton of experience with it and I'm running to an issue. The end goal of the procedure is to take data from one DB and put it into another in a different form. I have most of the procedure working it seems but I'm having issues with something that seems like it should be simple. At the beginning of the code, I would like to check to make sure a DB link is created. If not, then I want to create the db link.
This is what I put inside my procedure:
IF (select count(1) from ALL_DB_LINKS where db_link = 'DB_LINK.NAME.COM') = 0 THEN
CREATE DATABASE LINK LINK_NAME
CONNECT TO username IDENTIFIED BY password
USING 'SID';
END IF;
I know the link works because I've done it outside this and did a lookup with it. The error I get when I try to compile is this:
Encountered the symbol "CREATE" when expecting one of the following:
I've done all the googling I think I can do and I cannot figure out what I am doing wrong. To head off the other question I have, I've also tried to do it by putting in:
DECLARE test_count number;
select count(1) into test_count from ALL_DB_LINKS where db_link = 'DB_LINK.NAME.COM';
BEGIN
IF test_count = 0 THEN
CREATE DATABASE LINK LINK_NAME
CONNECT TO username IDENTIFIED BY password
USING 'SID';
END IF;
END;
But I get the same error. I'm also not sure if having a begin inside a begin will work. Any help would be a great... well, help.
Oracle compiles packages and in order to do that all objects referenced in code need to already exist. This includes objects referenced over a database link. Things will get marked invalid if the referenced objects don't exist. Usually a DBA will create and maintain such an environment using PL/SQL scripts and not stored procedures.
If you really want to anyway:
EXECUTE IMMEDIATE q'[ CREATE DATABASE LINK LINK_NAME
CONNECT TO username IDENTIFIED BY password
USING 'SID']';
If you really need to do this, you can create the link using dynamic SQL as Ed Gibbs suggested and Brian showed, as long as the link already exists at the point the procedure is created:
create database link test_link
connect to scott identified by oracle
using 'ORCL';
Database link created.
create or replace procedure p42 as
l_count number;
l_dummy dual.dummy%type;
begin
select count(*) into l_count
from all_db_links
where db_link = 'TEST_LINK';
if l_count = 0 then
execute immediate q'[
create database link test_link
connect to scott identified by oracle
using 'ORCL'
]';
end if;
select dummy into l_dummy from dual#test_link;
dbms_output.put_line('Value from remote database: ' || l_dummy);
end;
/
Procedure created.
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.
But the procedure won't compile if the link doesn't already exist:
drop database link test_link;
create or replace procedure p42 as
...
end;
/
Warning: Procedure created with compilation errors.
show errors
Errors for PROCEDURE P42:
LINE/COL ERROR
-------- -----------------------------------------------------------------
16/5 PL/SQL: SQL Statement ignored
16/5 PL/SQL: ORA-00942: table or view does not exist
Curiously it doesn't object if you create the procedure while the link exists, and then drop the link; the procedure stays valid, the dynamic SQL works to recreate the link, and the procedure runs successfully:
drop database link test_link;
Database link dropped.
select object_type, object_name, status from all_objects
where object_type = 'PROCEDURE' and object_name = 'P42';
OBJECT_TYPE OBJECT_NAME STATUS
--------------- --------------- ---------------------
PROCEDURE P42 VALID
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.
I would have expected dropping the link to invalidate the procedure, but apparently not, despite it appearing in all_dependencies. You can't recompile the procedure though:
drop database link test_link;
Database link dropped.
alter procedure p42 compile;
Warning: Procedure altered with compilation errors.
show errors
Errors for PROCEDURE P42:
LINE/COL ERROR
-------- -----------------------------------------------------------------
16/5 PL/SQL: SQL Statement ignored
16/5 PL/SQL: ORA-00942: table or view does not exist
In order to let you compile (or recompile) while the link does not exist, you'd need to reference the link using dynamic SQL as well:
drop database link test_link;
drop database link test_link
*
ERROR at line 1:
ORA-02024: database link not found
create or replace procedure p42 as
....
execute immediate 'select dummy from dual#test_link' into l_dummy;
dbms_output.put_line('Value from remote database: ' || l_dummy);
end;
/
Procedure created.
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.
drop database link test_link;
Database link dropped.
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.
drop database link test_link;
Database link dropped.
alter procedure p42 compile;
Procedure altered.
exec p42;
Value from remote database: X
PL/SQL procedure successfully completed.