Snowflake stored procedure conditional force error - stored-procedures

I want the procedure to fail in case of any conditions been met.
Is there a way to conditionally exit the Snowflake stored procedure with error.

RAISE could be used.
Raises an exception.
-- Stored Procedure - Snowflake Scripting
CREATE OR REPLACE PROCEDURE test_proc(ARG INT)
RETURNS INT
LANGUAGE SQL
AS
DECLARE
my_exception EXCEPTION (-20002, 'Raised MY_EXCEPTION.');
BEGIN
IF (ARG = 2) THEN
RAISE my_exception;
END IF;
RETURN ARG;
END;
Test:
CALL test_proc(1);
-- 1
CALL test_proc(2);
-- -20002 (P0001): Uncaught exception of type 'MY_EXCEPTION' on line 5 at position 8:
-- Raised MY_EXCEPTION.

Related

SnowScripting: SQL compilation error: syntax error line 6 at position 13 unexpected '<EOF>'

I'm new with Snowflake and creating a procedure in Snowflake using Snow Scripting. What could possibly be wrong?
create or replace procedure test_procedure(p_dob date)
returns varchar
language sql
as
declare
v_age NUMBER;
begin
v_age := datediff(year, p_dob, current_date);
return 'Your age is '||v_age::varchar;
end;
Error msg: SQL compilation error: syntax error line 6 at position 17 unexpected ''.
The code is all right using Snowsgihgt UI, though it should be CURRENT_DATE() instead of CURRENT_DATE. To make it run using ClassicUI is should be delimited with $$:
create or replace procedure test_procedure(p_dob date)
returns varchar
language sql
as
$$
declare
v_age NUMBER;
begin
v_age := datediff(year, p_dob, current_date());
return 'Your age is '||v_age::varchar;
end;
$$;
call test_procedure('2022-01-01');
More at: Using String Constant Delimiters Around a Block in a Stored Procedure

Dynamic SQL calling another stored procedure in Teradata

I've seen in the help guides that you cannot use a call statement in a teradata dynamic sql statement without output parameter.
I assume this implies I can, If the proc has an output parameter.
has anyone done this?
Scenario -
I have a table that at some point I'll expand out in terms of fields for logic on when things should run, and this table is managed elsewhere -
CREATE TABLE DB.SP_Test
(
ProcName VARCHAR(250)
,ProcRun VARCHAR(1)
);
now I added chrTest as an output however, I am still getting an error on run (no compile error)
The error :-
SQL_State SQL_Exception
T7689 Invalid dynamic SQL statement.
REPLACE PROCEDURE DB.Test_Control (OUT chrTest VARCHAR(250) )
SQL SECURITY INVOKER
LMain:
BEGIN
DECLARE sqlProcRun VARCHAR(20000);
DECLARE CONTINUE HANDLER
FOR SqlException
BEGIN
-----------------------------------------------------------------------------
DECLARE strExceptionText VARCHAR(250);
GET DIAGNOSTICS EXCEPTION 1 strExceptionText = Message_Text;
INSERT INTO DB.PROC_ERROR VALUES
(
'Test_Control'
,:SqlState
,strExceptionText
,Current_Timestamp
)
;
END;
-----------------------------------------------------------------------------
SET sqlProcRun ='';
L0:
FOR procs_run_cursor AS select_list
CURSOR FOR
SELECT Trim(ProcName) AS ProcName
FROM DB.SP_Test
DO
/*creating a lost of call statements to run*/
SET sqlProcRun = sqlProcRun ||'CALL DB.'||procs_run_cursor.ProcName|| '();';
END FOR L0;
EXECUTE IMMEDIATE sqlProcRun;
END;

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'

Aginity Stored Procedure Error

This may be a layman question. Still I surfed on the web and couldn't get through.
I am getting following error when run simple stored Procedure in Aginity
CREATE OR REPLACE PROCEDURE test()
RETURNS VARCHAR(10)
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
BEGIN
RETURN "SUCCESS"
END
END_PROC;
No error given when running the above.
Get the error ONLY when execute as follows
EXECUTE TEST();
Error:
ERROR [01000] NOTICE: plpgsql: ERROR during compile of TEST near line 3
ERROR [HY000] ERROR: missing ; at end of SQL statement
Thanks
CREATE OR REPLACE PROCEDURE test()
RETURNS VARCHAR(10)
LANGUAGE NZPLSQL AS
BEGIN_PROC
-- No need a DECLARE when you don have to declare anything
BEGIN
RETURN "SUCCESS" ; -- you just need a semi colon!
END; -- also here
END_PROC;

Test if a Procedure Throws an Exception in DUnitX

I am working with the DUnitX framework, and am trying to test if the procedure throws an exception.
Currently I have the following test procedure:
procedure TAlarmDataTest.TestIdThrowsExceptionUnderFlow;
begin
Input := 0;
Assert.WillRaise(Data.GetId(input), IdIsZeroException, 'ID uninitialized');
end;
When I go to compile I get an error 'There is no overloaded version of 'WillRaise' that can be called with these arguments.'
Is there a better way to check if the procedure is raising a custom exception, or should I use a try, except block that passes if the exception is caught?
The first parameter of WillRaise is TTestLocalMethod. That is declared as:
type
TTestLocalMethod = reference to procedure;
In other words, you are meant to pass a procedure that WillRaise can call. You are not doing that. You are calling the procedure. Do it like this:
Assert.WillRaise(
procedure begin Data.GetId(input); end,
IdIsZeroException,
'ID uninitialized'
);
The point being that WillRaise needs to invoke the code that is expected to raise. If you invoke the code then the exception will be raised whilst preparing the parameters to be passed to WillRaise. So, we need to postpone execution of the code that is expected to raise until we are inside WillRaise. Wrapping the code inside an anonymous method is one simple way to achieve that.
For what it is worth, the implementation of WillRaise looks like this:
class procedure Assert.WillRaise(const AMethod : TTestLocalMethod;
const exceptionClass : ExceptClass; const msg : string);
begin
try
AMethod;
except
on E: Exception do
begin
CheckExceptionClass(e, exceptionClass);
Exit;
end;
end;
Fail('Method did not throw any exceptions.' + AddLineBreak(msg),
ReturnAddress);
end;
So, WillRaise wraps the call to your procedure in a try/except block, and fails if the desired exception is not raised.
If you are still struggling with understanding this then I suspect you need to brush up your knowledge of anonymous methods. Once you get on top of that I'm sure it will be obvious.

Resources