Oracle trigger to call Stored Procedure - sql

I have an SP that needs to be called by an "after update" trigger. This Sp writes out a document to the mounted oracle directory for the host application to pick up. The SP has the following parameters :
CREATE OR REPLACE test_sp_mbinfo
(out_status OUT VARCHAR2,
out_dir OUT VARCHAR2,
in_contract IN VARCHAR2)
The in_contract parameter would be sent in by the triggering event. The trigger code i have so far that i have a hard time compiling is :
CREATE OR REPLACE TRIGGER mbinfo_trig
AFTER UPDATE OF tsta_cncontst ON kndtsta
FOR EACH ROW
BEGIN
IF (:new.tsta_cncontst IN ('02','06'))
THEN
test_sp_mbinfo(:new.tsta_cncclipu);
END IF;
END
;
How do i pass in the 2 out parameters to make the process work?
Thank you!

You could declare two local variables in the trigger and pass those for the OUT parameter. The question then becomes whether you care about the returned values, and if so what to do with them.

Related

Call a stored procedure with OUT parameter within another stored procedure in SAP HANA

I am currently trying to send an Email from a stored procedure I have created using the native sys.staticserver_sendemail_dev function.
But both the procedures have OUT parameters declared when I try to invoke the email procedure in my I get an error stating the parameters are not declared.
I wanted to know how to call a stored procedure without parameters inside another stored procedure.
I understood from your question, that you have two stored procedures, where one calls the other and both have out parameters. This is a valid constellation. Please find a minimum example, which works on SAP HANA Cloud:
CREATE OR REPLACE PROCEDURE TEST_INNER (OUT i INTEGER)
AS
BEGIN
SELECT COUNT(*) INTO i FROM DUMMY;
END;
CREATE OR REPLACE PROCEDURE TEST_OUTER (OUT another_i INTEGER)
AS
BEGIN
DECLARE outparam INTEGER;
CALL TEST_INNER(:outparam);
another_i = :outparam;
END;
CALL TEST_OUTER(?);
If this does not solve your issue, you need to provide more details as well as minimal code snippet similar to the one above to reproduce the issue.

SQL Exception Handling (not in stored procedure)

I have some MariaDb maintenance scripts that have the form:
DELIMITER //
CREATE PROCEDURE SAMPLE_TASK(OUT RESULT BOOLEAN)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SELECT 'Error running SAMPLE_TASK';
SHOW ERRORS;
SET RESULT=FALSE;
END;
-- DO SOMETHING HERE
SET RESULT=TRUE;
END //
DELIMITER ;
DELIMITER //
CREATE PROCEDURE RUN_TASKS()
BEGIN
DECLARE SUCCESS BOOLEAN DEFAULT TRUE;
IF (SUCCESS) THEN
CALL SAMPLE_TASK(SUCCESS);
END IF;
IF (SUCCESS) THEN
CALL SAMPLE_TASK2(SUCCESS);
END IF;
END //
DELIMITER ;
CALL RUN_TASKS();
The gist of it is that there are a series of tasks that are broken out into stored procedures. We want to execute each in turn aborting if we encounter an error.
This has worked well for us until now due to the fact one of our tasks we want to add will modify triggers, and it seems that creating a trigger within a stored procedure is not supported.
Since we can't add triggers in the stored procedures we are looking to do it outside of them, such as by adding a CREATE TRIGGER statement after the call to RUN_TASKS. The problem we have with that is that we can't find a way to handle errors at that level. From what I've been able to find declaring handlers can only be done at the procedure level, and MariaDb doesn't seem to offer try/catch like some some other DB products.
So the questions are: 1) Does anyone know how to create a trigger from within a stored procedure? 2) How do you add error handling outside of a stored procedure? Thanks

How to prompt for user input on PLSQL procedure

I'm having trouble getting user input inside of a PLSQL procedure. Everywhere I have looked I've come to the conclusion that is not possible or a PLSQL procedure it not made for user input.
My code:
create or replace
PACKAGE LAB5 AS
daysShow NUMBER;
PROCEDURE show_bizdays2(p_startDate DATE DEFAULT SYSDATE, p_bizDayShow NUMBER);
PROCEDURE show_bizdays2(p_startDate DATE DEFAULT SYSDATE);
FUNCTION Get_Descr(f_sectionId NUMBER) RETURN VARCHAR2;
END LAB5;
Description:
In this code the first procedure accepts two parameters a date and the amount of business days to show preceding that date. Works fine.
The second procedure overloads the first and is supposed to be exactly the same however it takes one parameter and prompts for the user input in the procedure. Or as described in my notes "ONE input parameter - Start Date and will prompt user to enter how many days are needed to show."
My Question(s)
Can you prompt for user input inside of a procedure?
Can I somehow use a global variable in the package that prompts the user when the overloaded procedure is called?
Similar to sql you can use & operater for getting input from user.
Example :
Declare
Table_nm:='&tblnm';
Begin
Execute immediate ('drop table '¦¦' '¦¦table_nm¦¦' '¦¦' purge') ;
End;

PL/SQL To Run Simple SQL Commands

Using basic SQL, I'm populating a table from another DB. This uses basic Delete statements to remove old data and Insert statements with a FROM clause using a DBLink. I'm attempting to transfer this to a package and have come up with this:
Package:
CREATE OR REPLACE
PACKAGE LOADDATA AS
procedure POPULATETABLE;
END LOADDATA;
PL/SQL (Package Body):
CREATE OR REPLACE
PACKAGE BODY LOADDATA AS
procedure POPULATETABLE AS
BEGIN
DELETE FROM DATATRANSFER;
INSERT INTO DATATRANSFER
SELECT VALUENUM, DATACONTENT, sysdate AS TRANSFER_DATA
FROM TRANSFERTABLE#DATALINK;
COMMIT;
NULL;
END POPULATETABLE;
END LOADDATA;
And to run the command, I would run:
exec LOADDATA.POPULATETABLE();
My question is should the procedure have an input/output parameter or declared variables? It has compiled and worked correctly but I'm unsure if I'm following PL/SQL methodology.
There is no rule to provide parameters.
Additonally you can insert record to log table which will store the start date, end date, number of records inserted and number of records deleted in case you need to track the batch execution periodically.
Also if this package is called by some web page or some application then you may need to create an exception block and send a Error Message as an output parameter in a User Readable Form.
EDIT:
Package Specification
CREATE OR REPLACE
PACKAGE LOADDATA AS
procedure POPULATETABLE(out_variable OUT VARCHAR2);
END LOADDATA;
Package Body
CREATE OR REPLACE
PACKAGE BODY LOADDATA AS
procedure POPULATETABLE(out_variable OUT VARCHAR2) AS
BEGIN
DELETE FROM DATATRANSFER
-- <TODO:INSERT records deleted and date into a log table>
INSERT INTO DATATRANSFER
SELECT VALUENUM, DATACONTENT, sysdate AS TRANSFER_DATA
FROM TRANSFERTABLE#DATALINK;
-- <TODO:INSERT records inserted and date into a log table>
COMMIT;
NULL;
-- Assign out_variable as success if comletes successfully
out_variable := 'SUCCESS';
EXCEPTION
-- WHEN OTHERS catches all exceptions Oracle error message is displayed in SQLERRM
WHEN OTHERS THEN
-- Assign out_variable with Error message if errors out
out_variable := 'Error :'||SQLERRM;
END POPULATETABLE;
END LOADDATA;

Oracle triggers and stored procedures

I need to make for my webApp a trigger to execute a stored procedure on Oracle. But i'm very new to Oracle and I'm still getting the hang of it. I can make a simple Trigger with a sequence to auto-increment a value from a table, but that's it.
Is there any good tutorials and examples available on this specific subject? I tried searching here, but i have only found a very generic question: How can i learn Stored Procedure and Trigger?. But i can be more specific: I need this trigger to run a stored procedure that generates a new code for my user, adding data to this code. The procedure is done, i just don't know how to use it in a trigger, pass the parameters, and how to insert/update values from the oracle trigger itself.
Help will be much appreciated.
Assuming your function to generate the code is named f_generate_code() and your table is named foobar and the column that should be populated is name code you'd do it like this:
create or replace trigger trg_update_code
before insert or update on foobar
for each row
begin
:new.code := f_generate_code();
end;
/