PL/SQL procedure compiles successfully but does not print out values when I execute - stored-procedures

So i created a procedure with one input parameter and it compiles successfully but when i call it, it says "PL/SQL procedure successfully completed" but no values are printed
I have tried different ways to execute procedures and none of them have worked.
This is my code below:
CREATE OR REPLACE PROCEDURE vendorInfo (vendorID in NUMBER) AS
V_NAME VENDORS.VENDOR_NAME%TYPE;
V_CITY VENDORS.VENDOR_CITY%TYPE;
I_ID INVOICES.INVOICE_ID%TYPE;
I_TOTAL INVOICES.INVOICE_TOTAL%TYPE;
I_P_TOTAL INVOICES.PAYMENT_TOTAL%TYPE;
I_C_TOTAL INVOICES.CREDIT_TOTAL%TYPE;
STATUS VARCHAR2(15);
CURSOR vendor_cursor IS
SELECT INVOICE_ID,INVOICE_TOTAL,PAYMENT_TOTAL,CREDIT_TOTAL FROM
INVOICES
WHERE VENDOR_ID = vendorID;
BEGIN
SELECT VENDOR_NAME,VENDOR_CITY INTO V_NAME,V_CITY
FROM VENDORS
WHERE VENDOR_ID = vendorID;
DBMS_OUTPUT.PUT_LINE('VENDOR NAME:'|| V_NAME || ' VENDOR
CITY:'|| V_CITY);
OPEN vendor_cursor;
LOOP
FETCH vendor_cursor INTO I_ID,I_TOTAL,I_P_TOTAL,I_C_TOTAL;
EXIT WHEN vendor_cursor%NOTFOUND;
IF (I_TOTAL - I_P_TOTAL - I_C_TOTAL) = 0 THEN
STATUS := 'PAID';
ELSE
STATUS := 'NOT_PAID';
END IF;
DBMS_OUTPUT.PUT_LINE('INVOICE ID:' || I_ID ||' INVOICE
TOTAL:'|| I_TOTAL || ' STATUS:' || STATUS);
END LOOP;
CLOSE vendor_cursor;
END vendorInfo;
/
begin
vendorInfo(95);
end;
/

You have to enable output.
If you're running this piece of code in SQL*Plus or SQL Developer, you'd - before calling the procedure - run
set serveroutput on --> this
begin
vendorInfo(95);
end;
/
If you're using some other GUI (you tagged the question with PL/SQL Developer tag - I don't use it so I can't tell for sure), then you'll have to enable it somehow. In TOAD, for example, click the button in "DBMS Output" pane:

Related

Return log of activities inside a Stored Procedure in Teradata

The requirement is to get the log of all the DML statements executed inside a Stored Procedure in teradata. This Stored procedure is being called inside a shell script using BTEQ. The ask is to capture the log of all activities performed inside the shell into a log file in unix. If any error occurs, that also needs to be captured.
The Stored Procedure contains 20 Merge SQLs and i want to see how many rows got affected and how long each statement took. I tried calling the individual merges through BTEQ(instead of calling it in a Stored Procedure), but there is significant time gain if its called inside an SP. Right now, all i can see is that the Stored procedure has been completed successfully.
replace procedure SP_Test()
BEGIN
MERGE INTO T1 using T2 on T1.C1 = T2.C1
WHEN NOT MATCHED THEN INSERT (C1,C2,C3) VALUES (T2.C1,T2.C2,T3.C3)
WHEN MATCHED
THEN UPDATE
SET
C1 = CASE statement 1
C2 = CASE statement 2
c3 = CASE statement 3 ;
END;
inside the BTEQ block of test.sh shell script,
bteq << EOF >>LOgFILE.txt 2>&1
.LOGON source/user,password;
.COMPILE FILE = sp_merge.txt;
.IF ERRORCODE <> 0 THEN .GOTO QUITNOTOK
call SP_Test();
.IF ERRORCODE <> 0 THEN .GOTO QUITNOTOK
.LABEL QUITOK
.LOGOFF
.QUIT 0
.LABEL QUITNOTOK
.QUIT 2
EOF
Log File currently
**** Procedure has been executed.
**** Total elapsed time was 2 minutes and 47 seconds.
Expected Output
**** Merge completed. 5641191 rows affected.
5641191 rows inserted, no rows updated, no rows deleted.
**** Total elapsed time was 2 minutes and 45 seconds.
You can do one thing.
Write another procedure and keep an insert statement like this below :
REPLACE PROCEDURE <DB_USER>. log_process_run_message ( IN in_n_process_run_id DECIMAL(18,0) ,
IN in_v_process_name VARCHAR(30) ,
IN in_v_message_txt VARCHAR(50000) ,
IN in_d_message_ts TIMESTAMP(6)
)
BEGIN
BT; -- Begin Transaction
INSERT INTO <SCHEMA_NAME>.cop_process_run_message_op
(
process_name ,
message_txt ,
message_ts
)
VALUES (
in_v_process_name ,
in_v_message_txt ,
in_d_message_ts
);
ET; -- End Transaction
END;
In your main procedure include an exit handler;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET lv_sql_state = SQLSTATE;
SET ln_sql_code = SQLCODE;
SET out_status = 'FAILED';
ROLLBACK;
SET lv_my_mesg = 'Error in : ' || lv_my_mesg || ' - SQLSTATE: ' || lv_sql_state || ', SQLCODE: ' || CAST(ln_sql_code AS CHAR);
CALL <DB_USER>.log_process_run_message (ln_run_id,lv_err_component,lv_my_mesg,CURRENT_TIMESTAMP(6));
END;
Also define the below variable in your main procedure
SET lv_err_component='ur proc name'
Now call this procedure inside your main procedure after every merge statement:
SET lv_my_mesg ='Merge 1 completed '||CAST(CURRENT_TIMESTAMP(0) AS CHAR(19));
CALL <DB_USER>.log_process_run_message (lv_err_component,lv_my_mesg,CURRENT_TIMESTAMP(6));
What this will do is, it will insert a record after successful execution of your merge statements and in case there is an error it will
execute the call statement in the exit handler and will document your error message as well in case there is any.Let me know if this helps.

will IF SIGNAL SQLSTATE in mariadb exit stored procedure?

I don't quite understand how MariaDB signals work.
I have a stored procedure that takes a string as input. I am testing that string for valid characters. If invalid characters are found then I want to send a signal that the error was invalid. Will a stored procedure immediately exit if a SIGNAL SQLSTATE '......' SET MESAGE_TEXT='......' is raised? Or will it complete the procedure before issuing the signal?
When just using IF...THEN statements it does not seem to work.
CREATE PROCEDURE `testP`()
BEGIN
IF testStringSecurity('he;llo world') != 0 THEN
SELECT 'INVALID CHARACTERS';
END IF;
SELECT 'GOOD TO GO';
END;
Always returns GOOD TO GO. It seems that you must wrap in IF ... THEN ... ELSE like so to get a valid case. Though setting a signal is different.
CREATE PROCEDURE `testP`()
BEGIN
IF testStringSecurity('he;llo') != 0 THEN
SELECT 'INVALID CHARACTERS';
ELSE
SELECT 'GOOD TO GO';
END IF;
END
Using a SIGNAL does seem to interrupt execution immediately.
CREATE PROCEDURE `testP`()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 #sqlstate = RETURNED_SQLSTATE,
#errno = MYSQL_ERRNO, #text = MESSAGE_TEXT;
SET #full_error = CONCAT("ERROR ", #errno, " (", #sqlstate, "): ", #text);
SELECT #full_error;
END;
DECLARE EXIT HANDLER FOR NOT FOUND
BEGIN
SELECT CONCAT('ERROR: ',#str,' RETRUNED NOT FOUND EXCEPTION.');
END;
IF testStringSecurity('he;llo') != 0 THEN
SIGNAL SQLSTATE '42000'
SET MESSAGE_TEXT = 'ERROR: Invalid string';
END IF;
SELECT 'GOOD TO GO';
END
Returns 'ERROR 1644 (42000): ERROR: Invalid string'

Dynamic Stored Procedure in Oracle

Gurus, I have stored procedure to has to executed on a dynamic table. Here is how the stored procedure looks like.
create or replace PROCEDURE EFX_RECON_UPDATE_SPROC(
FILENAME IN VARCHAR2 ,
SOURCE IN VARCHAR2 )
AS
TABLE_NAME VARCHAR2(200);
query_str VARCHAR2(500);
cnt NUMBER(10);
BEGIN
-- Create dynamic table for each fullfilment system.
TABLE_NAME := SOURCE||'_BRM_OMC_RECON_T';
query_str :='SELECT count(*) from ' || SOURCE || '_BRM_OMC_RECON_T where PROCESSINGFILENAME='''||FILENAME||''';';
EXECUTE IMMEDIATE query_str;
query_str:='MERGE INTO '||TABLE_NAME||' T
USING (
SELECT
ERRORCODE, PROCESSINGFILENAME,
RECORDNUMBER from ERROR_UPLOAD_T
) TMP
ON (T.RECORDNUMBER = TMP.RECORDNUMBER and
T.PROCESSINGFILENAME= TMP.PROCESSINGFILENAME and
T.PROCESSINGFILENAME='''||FILENAME||''')
WHEN MATCHED THEN
UPDATE SET
T.STATUS = ''ERROR'',
T.ERRORSOURCE = ''BRM'',
T.ERRORCODE = TMP.ERRORCODE';
EXECUTE IMMEDIATE query_str;
COMMIT;
END EFX_RECON_UPDATE_SPROC;
I get this error while executing the stored procedure. The problem is with FILENAME and I have enclosed it in ' quot.
ORA-00933: SQL command not properly ended
ORA-06512: at "PIN149.EFX_RECON_UPDATE_SPROC", line 12
According to the error message the problem is on this line:
EXECUTE IMMEDIATE query_str;
It should be:
EXECUTE IMMEDIATE query_str INTO cnt;
And the semicolon should be removed from the SELECT string.
Although the variable cnt is not used elsewhere so I'm not sure what that statement is supposed to accomplish.

PL SQL Procedure warning compiled Error PLS-00103

I'm starting with PL/SQL, this is my first Procedure and I find it difficult to compile; I have tried so many different versions, I carry the last attempt. I don't understand why SQLDEVELOPER say me: "procedure compiled (with errors)".
The compiler say me:" Errore(10,1): PLS-00103: Trovato il simbolo (find) "DECLARE" instead: begin function pragma procedure subtype type current cursor delete exists prior "
If there are other errors (also logical) please tell me. I would like to improve.
Thank you all for the answers
My Procedure:
create or replace PROCEDURE calcola_giorn (giornata IN INTEGER) is
-- si tenga presente che in realtà giornata=idPartita
somma NUMBER;
idcal NUMBER;
nometorn VARCHAR2;
idformaz NUMBER;
nomesquadr VARCHAR2;
DECLARE;
SELECT idcalendario INTO idcal FROM partita WHERE id= giornata;
SELECT nometorneo INTO nometorn FROM calendario WHERE id= idcal;
CURSOR formazioni_di_giornata IS
SELECT id, nomesquadra FROM formazione where idpartita= giornata;
CURSOR giocatori_di_giornata IS
SELECT votogiocatore FROM schiera WHERE idformazione= idformaz;
Begin
OPEN formazioni_di_giornata;
FOR tupla_formazione IN formazioni_di_giornata LOOP
somma:=0;
FETCH formazioni_di_giornata INTO idformaz, nomesquadr;
OPEN giocatori_di_giornata;
FOR tupla_giocatore IN giocatori_di_giornata LOOP
somma:= somma + tupla_giocatore.votogiocatore;
END LOOP;
CLOSE giocatori_di_giornata;
UPDATE partecipa SET punti= somma WHERE ( (nomesquadra= nomesquadr) AND (nometorneo= nometorn));
END LOOP;
CLOSE formazioni_di_giornata;
EXCEPTION WHEN OTHERS THEN raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END calcola_giorn;
Varchar limit should be defined, like varchar2(100)
Replace DECLARE; with BEGIN
All your cursors should go before BEGIN
Put END; for the procedure
You can try compiling after making these changes.

Detect if a table exists

In SQL Server you can write SQL to check if a table exists. How can I do that for ADS?
I have a need to write some Delphi code to say if table exists do this else this...
The system procedure sp_GetTables can tell you what tables exist in the directory that you connected to:
EXECUTE PROCEDURE sp_GetTables( NULL, NULL, NULL, 'TABLE' )
A non-SQL solution would be to use the AdsCheckExistence API.
I'm not ADS user, so I can't answer in detail.
See http://devzone.advantagedatabase.com/dz/webhelp/Advantage10.1/index.html
The're is system.tables view with information about tables.
I suppose you also can write SQL query to check a table.
I like Peter's answer, but depending on what it is you need to do, you might be looking for a TRY, CATCH, FINALLY statement.
TRY
// Try to do something with the table
select top 1 'file exists' from "non_existing_table";
CATCH ADS_SCRIPT_EXCEPTION
// If a "7041 - File does not exist" error ocurrs
IF __errcode = 7041 THEN
// Do something else
select 'file does not exist' from system.iota;
ELSE
// re-raise the other exception
RAISE;
END IF;
END TRY;
Delphi code:
function TableExists(AConnection: TADOConnection; const TableName: string): boolean;
var
R: _Recordset;
begin
if AConnection.Connected then
try
R := AConnection.Execute('Select case when OBJECT_ID(''' + TableName + ''',''U'') > 0 then 1 else 0 end as [Result]', cmdText, []);
if R.RecordCount > 0 then
Result := (R.Fields.Items['Result'].Value = 1);
except on E:exception do Result := false;
end;
this simple function use existing TADOConnection
end;

Resources