I have a procedure for sending emails to customers once the data loaded by them has been processed using the inbuilt procedure for sending mails. It takes the recipient of the mail,the subject and the message as input parameters.
I have to create another procedure for taking the input parameters from 2 different tables. I want to do something like the below mentioned :
To: Email of user loaded the data thru portal.
Subject : Your application “&APP_Name” has been Published.
Message : Your application “&APP_Name” has been Published. Please visit the link : XXXXXXXXXX
I have to get the recipient and app_name from two different tables? What is the best way of doing that?
Is this what you are looking for? Just select the values you need.
DECLARE
v_r VARCHAR2(100);
v_app VARCHAR2(100);
PROCEDURE email(p_receipent IN VARCHAR2, p_app_name IN VARCHAR2) IS
BEGIN
dbms_output.put_line('send to:' || p_receipent || ' subject:' || p_app_name || ' message: ' || p_app_name);
END;
BEGIN
SELECT 'demo#mydemo.so' INTO v_r FROM dual; --table1
SELECT 'app1' INTO v_app FROM dual; --table2;
email(v_r, v_app);
END;
Related
I have a table (my_tab) that contains a STATUS column against a specific ID in this same table.
I need a means of being alerted via a DBMS_ALERT process of when the STATUS column changes value.
I was looking at using a trigger to kick off the ALERT, i.e.:
create or replace trigger my_tab_upd after update of status on my_tab for each row
begin
dbms_alert.signal('mystatusalert', 'changed from '||:old.status||' to '||:new.status||'.');
end;
/
With this, how do I now get alerted/notified that this STATUS change has occurred within a PL/SQL procedure to now go off and perform another operation based on this STATUS change?
Further to the above, with my application setup, there will be multiple users. Based on this, how can I target the alert for specific users/sessions so that the correct user gets their alert only and not someone else's.
I am looking at checking the alert from a web based application (Oracle APEX), so don't want to lock the front-end up so any recommendations on this would be good.
An example would be great.
I'd send an e-mail to myself. For example:
create or replace trigger my_tab_upd
after update of status on my_tab
for each row
begin
utl_mail.send (sender => 'me#company.com',
recipients => 'me#company.com',
subject => 'MY_TAB status changed',
message => 'old = ' || :old.status ||', new = ' || :new.status
);
end;
DBMS_ALERT example: in Scott's schema, I want to notify my stored procedure that something has changed in the EMP table and then do something (I'll just display the message).
First, create a triggger; alert name is alert_emp and will be used later in the stored procedure:
SQL> create or replace trigger trg_au_emp
2 after update on emp
3 for each row
4 begin
5 dbms_alert.signal
6 ('alert_emp', 'Salary changed for ' || :new.ename ||
7 ' from ' || :old.sal ||
8 ' to ' || :new.sal);
9 end;
10 /
Trigger created.
The procedure:
SQL> create or replace procedure p_test is
2 l_msg varchar2(200);
3 l_status number;
4 begin
5 dbms_alert.register ('alert_emp');
6 dbms_alert.waitone ('alert_emp', l_msg, l_status);
7 dbms_output.put_line(l_msg ||': '|| l_status);
8 end;
9 /
Procedure created.
Now, execute the procedure:
SQL> exec p_test;
Here, it is just waiting for something to happen in the EMP table. In another session I'm updating the table. Commit is obligatory; otherwise, nothing happens. p_test will still be waiting.
update emp set sal = 1000 where empno = 7369;
commit;
In the first session, once commit is being executed, screen shows this:
PL/SQL procedure successfully completed.
Salary changed for SMITH from 800 to 1000: 0
PL/SQL procedure successfully completed.
SQL>
I have a stored procedure proc1 without parameters. I want to extract data from this stored procedure. How can I get that? Could you help me?
Stored procedure:
create procedure proc1
as
begin
select e_id, e_nm, e_sal
from emp
where e_id like 'e%';
end proc1;
You can do this in Oracle 12.1 or above:
create or replace procedure demo
as
rc sys_refcursor;
begin
open rc for select * from dual;
dbms_sql.return_result(rc);
end demo;
This requires an Oracle 12.1 or later client/driver to handle the implicit result set.
For more details, see Implicit Result Sets in the Oracle 12.1 New Features Guide, Tom Kyte's Blog, Oracle Base etc.
Here's one possible solution:
Declaration:
create procedure proc1 (emp_row IN OUT emp%rowtype)
as
begin
select * --e_id, e_nm, e_sal
into emp_row
from emp
where e_id like 'e%';
end proc1;
Use case:
DECLARE
l_emp_row emp%rowtype;
BEGIN
proc1(l_emp_row);
-- Here you can access every column of table "emp", like so:
-- dbms_output.put_line('e_id: ' || to_char(l_emp_row.e_id));
-- dbms_output.put_line('e_nm: ' || to_char(l_emp_row.e_nm));
-- dbms_output.put_line('e_sal: ' || to_char(l_emp_row.e_sal));
END;
Is there anything special that you need to get out of the Procedure?
Cheers
you create a view this query. (recomended)
Oracle procedure is not return any data. So, you do not see any result. Your result get buffer but not print screen. if You need a procedure, insert all data another table.
create procedure proc1
as
begin
insert into new_table select e_id, e_nm, e_sal from emp where e_id like 'e%';
end proc1;
Another way; You create a function. Because function outputs and inputs. This function;
for example Create an Oracle function that returns a table
I have created a Function from Oralce DB and used it as input to Spotfire report. The reason why i used a function instead of view is because the parameters had some complex logic operations and i was not able to get that done in a view.
Coming to the report i have built. Currently i am using 2 parameters in the function and i am taking both the values from Spotfire text area in Data on Demand mode. Issue is that unless i enter values for both parameters i wont get the output. My requirement is that i need to add few more parameters for the report which i can but i need to set up the function and the settings in Spotfire such that if 5 parameters are there , if users enters one value for just one parameter report should run for that parameter. So the Functions needs to be in such a way that if value is entered that should be taken and if its left empty then that should not be considered. leaving the Spotfire part if the Function is built with the specifics mentioned by me i can implement it directly.
I have got different solutions from everywhere and i am not able to implement anything properly. I am updating all the examples and need help in figuring out the right one and correcting it or to do it in a completely different manner
Code Type 1:
create or replace function Function_test(p1 varchar2='',p2 varchar2='',p3 varchar2)
return SYS_REFCURSOR as
my_cursor SYS_REFCURSOR;
begin
open my_cursor for
select distinct
x.c1
x.c2
x.c3
from x
where x.c1=p3
and (p1='' or x.c2=p1)
and (p2='' or x.c3=p2);
return my_cursor;
end;
The above code seems to be an example from MSSQL and i am able to get the logic but dont know the right way to implement in Oracle. When i tried i just got lot of errors.
Code Type 2:
create or replace function Function_delete(param1 Varchar2, param2 varchar2)
RETURN Varchar2 IS
ssql varchar2(3000);
test varchar2(1000);
begin
ssql := 'select col1,col2 from table_x';
if param1 is null and param2 is not null then
ssql := ssql || ' Where col2='''|| param2 ||'''';
end if;
if param1 is not null and param2 is null then
ssql := ssql || ' Where col3= ''' || param1 ||'''';
end if;
if param1 is not null and param2 is not null then
ssql := ssql || ' Where col3 = ''' || param1 || ''' and col2='''|| param2 ||'''';
end if;
dbms_output.put_line(ssql);
execute immediate ssql into test;
return test;
--EXCEPTION
-- WHEN OTHERS THEN
-- return 'Hello';
end Function_delete;
In the above example i am not able to implement the logic right in Spotfire cos it requires columns to get the data. Ultimately i need a code that accepts no of parameters that are given by the user rather than working only when all parameters are given. It needs to have columns visibly displayed since that way i can implement the same in Spotfire Reports.
you can try this:
create or replace function Function_test(p1 in varchar2,p2 in varchar2,p3 in varchar2)
return SYS_REFCURSOR as
my_cursor SYS_REFCURSOR;
begin
open my_cursor for
select
1
from
dual
where 1=1
and '1'=p1
and '2'=p2
and '3'=p3 ;
return my_cursor;
end;
This is my first (edited) stackoverflow question, so please bear with me.
In Oracle 11g, I have a need to describe/interrogate the underlying columns of a reference cursor returned from a procedure call on another database over a dblink, in which the actual SQL is not always "explicit", but sometimes dynamically generated.
For example:
declare
v_ref_cur sys_refcursor;
v_cur_num number;
v_col_count number;
v_col_table dbms_sql.desc_tab3;
begin
myProc#myDblink(v_ref_cur, 'myvalue');
v_cur_num := dbms_sql.to_cursor_number(v_ref_cur);
dbms_sql.describe_columns3(v_cur_num, v_col_count, v_col_table);
...
end
If myProc() on the other database has an "explicit" SQL statement like:
open cursor for select * from foo where bar = myParam;
The cursor conversion and description (still) work just fine - I can determine the column names, types, lengths, etc returned by the procedure.
BUT, if myProc() on the other database involves dynamic SQL, like:
v_sql := 'select * from foo where bar = ''' || myParam || '''';
open cursor for v_sql;
I get an ORA-01001 invalid cursor error when attempting to call dbms_sql.to_cursor_number().
Is there a way to convert/describe a reference cursor derived from dynamic SQL as called from a remote procedure? If so, how? If not, why not?
Thanks for any/all assistance!
Using DBMS_SQL across a database link raises many different errors, at least some of which are Oracle bugs. Those problems can be avoided by putting all of the logic in a function compiled on the remote server. Then call that function remotely.
--Create and test a database link
create database link myself connect to <schema> identified by "<password>"
using '<connect string or service name>';
select * from dual#myself;
--myProc
create procedure myProc(p_cursor in out sys_refcursor, p_value varchar2) is
begin
--open p_cursor for select * from dual where dummy = p_value;
open p_cursor for 'select * from dual where dummy = '''||p_value||'''';
end;
/
--Simple function that counts and displays the columns. Expected value is 1.
create or replace function count_columns return number is
v_ref_cur sys_refcursor;
v_cur_num number;
v_col_count number;
v_col_table dbms_sql.desc_tab3;
begin
--ORA-01001: invalid cursor
--myProc#myself(v_ref_cur, 'myvalue');
myProc(v_ref_cur, 'myvalue');
--ORA-03113: end-of-file on communication channel
--v_cur_num := dbms_sql.to_cursor_number#myself(v_ref_cur);
v_cur_num := dbms_sql.to_cursor_number(v_ref_cur);
--Compilation error: PLS-00306:
-- wrong number or types of arguments in call to 'DESCRIBE_COLUMNS3'
--dbms_sql.describe_columns3#myself(v_cur_num, v_col_count, v_col_table);
dbms_sql.describe_columns3(v_cur_num, v_col_count, v_col_table);
return v_col_count;
end;
/
begin
dbms_output.put_line('Number of columns: '||count_columns#myself());
end;
/
Number of columns: 1
See the sample Timesten procedure below.
CREATE OR REPLACE PROCEDURE test_proc(employee_id IN NUMBER) AS
salary NUMBER;
BEGIN
SELECT emp_sal INTO salary FROM employee where emp_id = employee_id;
DBMS_OUTPUT.PUT_LINE('Employee Id:' || employee_id || ' Annual Income:' || salary*12);
END;
/
If I call the procedure from Command line interface(ttisql), dbms_output.put_line logs gets printed there only.
But I want to collect such debug logs to somewhere else in a log file. Whenever procedure get executed it should append these content to a file. Is there any possible way to do that?
If you are calling your procedure from ttisql as you've said you can use spool filepath and spool off to log any messages appeared on the screen. To append new information to the already existed log file just use APPEND option after filepath
spool c:\logfile.log append