Snowflake - Processing aborted due to error - stored-procedures

i am getting error while calling below procedure
create or replace procedure get_net_profit_based_on_partition_value(part_value varchar)
returns table (branch_id integer, city varchar, net_profit float, net_profit_part float )
language sql
as
declare
res resultset default (select branch_id, city,net_profit, 100 * ratio_to_report(net_profit) over (partition by :part_value) as net_profit_part from store_sales order by city);
begin
return table(res);
end;
and when calling the procedure
call get_net_profit_based_on_partition_value('city');
Getting below error:
000603 (XX000): SQL execution internal error:
Processing aborted due to error 300002:3405954919; incident 7068082.
I already checked that this select statement alone would work, but its failing in the procedure
Can anybody help on this?

Because your input variable is referencing an object, not a value, I think you need to use the keyword "identifier" e.g.
res resultset default (select branch_id, city,net_profit, 100 * ratio_to_report(net_profit) over (partition by identifier(:part_value)) as net_profit_part from store_sales order by city);

Related

Set a variable value in stored procedure and use in following query

How can I set a variable in stored procedure and use it in following query to be executed.
create or replace procedure sp1()
returns table (dealer_id varchar, dealershipgroup_name varchar)
language sql
as
$$
declare
create_query varchar;
res resultset;
MISSING_DEALER NUMBER(38,0) default 0;
begin
MISSING_DEALER := 100;
select_query := 'WITH CTE AS(
SELECT dealer_id,
CASE WHEN dealer_id=:MISSING_DEALER then \'Abc\'
WHEN dealershipgroup IS NULL then \'\'
ELSE dealershipgroup end as dealershipgroup FROM TBL )
select * from CTE';
res:= (execute immediate : select_query);
return table(res);
end;
$$;
call sp1();
Could someone please suggest how can I use MISSING_DEALER in the query. I am currently getting the following error
Uncaught exception of type 'STATEMENT_ERROR' on line 28 at position 9 : SQL compilation error: error line 8 at position 26 Bind variable :MISSING_DEALER not set
You need to concatenate the string parts of your SQL statement with the variable. This is covered in the documentation if you look at the end of the section here

Anyone knows why LPAD function returns an error when it is called during UNLOAD command inside Redshift stored procedure?

I'm trying to call the LPAD function during the UNLOAD command inside a Redshift stored procedure and it keeps returning an error: Amazon Invalid operation: syntax error at or near "9" . Can anyone help me address this error?
The column that LPAD is applied to is VARCHAR data type. Basically, I'm adding leading "0" to records that are less than 9 character long.
If it matters, I'm using Aginity Pro as the query editor while connecting to Redshift. Here is an example stored procedure:
CREATE OR REPLACE PROCEDURE schemaname.sp_example ()
LANGUAGE plpgsql
AS
$$
DECLARE _CurrentDate VARCHAR(10);
_UnloadQuery VARCHAR(65000);
BEGIN
WITH CTE_CurrentDate AS (SELECT TO_CHAR(CAST(GETDATE() AS DATE), 'YYYYMMDD') AS CurrentDateParm)
SELECT CurrentDateParm INTO _CurrentDate FROM CTE_CurrentDate;
_UnloadQuery := '
UNLOAD ('''||
'
SELECT B.column_name
FROM tbl_a a
INNER JOIN tbl_b B
on LPAD(a.column_name,'''||$9||''',''0'') = B.column_name
GROUP BY B.column_name
'
||'''
)
to '''||'s3://address_'||_CurrentDate||'.CSV'||'''
credentials '''||'aws_access_key_id=xxx'||';'||'aws_secret_access_key=xxx'||'''
Header
ALLOWOVERWRITE
delimiter '''||','||'''
addquotes
PARALLEL OFF
';
EXECUTE _UnloadQuery;
END;
$$;

Redshift Stored Procedure - [Amazon](500310) Invalid operation: syntax error at or near "$1";

My Agenda is to store the counts of the 2 tables ( being passed in the parameter ) and then do some more operations upon comparing the both.
PROBLEM -
Stored Procedure throwing Error :
CREATE OR REPLACE PROCEDURE dev.gp_count_matching_20191204(actual_tablename character varying(256), bkp_tablename character varying(256))
LANGUAGE plpgsql
AS $$
DECLARE
actual_table_name varchar(256);
backup_table_name varchar(256);
actual_count_query varchar(1024);
actual_count int;
backup_count_query varchar(1024);
backup_count int;
BEGIN
call dev.gp_test_error_handling_tablename_format(actual_tablename);
call dev.gp_test_error_handling_tablename_format(bkp_tablename);
actual_count:=(select count(*) as counts from actual_tablename);
--raise info 'Actual Table Name - %, Actual Table Count - %',actual_tablename,actual_count;
end;
$$
This throws the following Error while creating the stored procedure-
An error occurred when executing the SQL command:
CREATE OR REPLACE PROCEDURE dev.gp_count_matching_20191204(actual_tablename character varying(256), bkp_tablename character varying(256))
LANGUAGE pl...
[Amazon](500310) Invalid operation: syntax error at or near "$1";
1 statement failed.
Execution time: 0.99s
If I comment out the actual_count:=(select count(*) as counts from actual_tablename);
then the Stored Procedure gets created Successfully.
I guess it has something to do with me using the parameter ( since $1 points the first parameter ) in the query.
Since I am pretty new with Stored procedure, I unable to figure out the exact problem.
Thanks in Advance.
You need to use EXECUTE when running dynamic SQL. In your example the query is in parentheses but nothing is making it execute. To execute the query into a variable you using the INTO syntax
sql := 'SELECT …'
EXECUTE sql_var INTO result_var;
Please see the example Stored Procedures in our GitHub repo "Amazon Redshift Utils". https://github.com/awslabs/amazon-redshift-utils/tree/master/src/StoredProcedures
There are several examples that use dynamic SQL, such as https://github.com/awslabs/amazon-redshift-utils/blob/master/src/StoredProcedures/sp_split_table_by_range.sql
You can also use the below-given syntax:
SELECT INTO Count count(*) from table_name;
By doing this you are inserting the value of count(*) into variable Count. It works.

Getting invalid identifier and SQL ignored errors in stored procedure in Oracle

I am trying to create a stored procedure in order to insert some data into some table in Oracle 11g.
For this purpose, I need to read the last amount from the latest insert for that user, and then add it to my new value and save the changes as a new row and if any kind of exception is occurred just rollback. This is what I have come up with so far:
CREATE OR REPLACE PROCEDURE MYTESTDB.INSERT_INTO_TESTBANK
(
ID IN TBLTESTBANK.ID%TYPE,
USERID IN TBLTESTBANK.USERID%TYPE,
TYPE IN TBLTESTBANK.TYPE%TYPE,
AMOUNT IN TBLTESTBANK.AMOUNT%TYPE,
DATETIMESTAMP IN TBLTESTBANK.DATETIMESTAMP%TYPE,
TRANSACTION_ID IN TBLTESTBANK.IDTRANS%TYPE,
TOTAL_MONEY IN TBLTESTBANK.TOTALMONEY%TYPE,
COMPUTED_HASH IN TBLTESTBANK.HASH%TYPE
)
IS
BEGIN
DECLARE
LastAmount TBLTESTBANK.TOTALMONEY%TYPE;
BEGIN
SELECT TBLTESTBANK.TOTALMONEY INTO LASTAMOUNT
FROM
(
SELECT TBLTESTBANK.ID
FROM TBLTESTBANK tblbnk
WHERE tblbnk.USERID = USERID
order by max(tblbnk.DATETIMESTAMP)
)
where ROWNUM<2;
EXCEPTION WHEN NO_DATA_FOUND
THEN LastAmount := 0;
END;
LastAmount := LastAmount+ AMOUNT;
INSERT INTO TBLTESTBANK (ID, USERID, TYPE, LastAmount,
DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
)
VALUES (ID, USERID, TYPE, AMOUNT, DATETIMESTAMP, TRANSACTION_ID, TOTAL_MONEY, COMPUTED_HASH);
COMMIT;
EXCEPTION WHEN OTHERS
THEN
ROLLBACK;
END;
/
Whenever I try to test it, I get a red wiggly line under the first SELECT , and then he TESTBANK.ID in the inner select statements. For the select command it says, sql statement is ignored, and for the TESTBANK.ID it says invalid identifier!
It also doesn't let me add two variables, and keeps saying LastAmount must be declared.
And these are the errors I get :
Error(19,7): PL/SQL: SQL Statement ignored
Error(22,16): PL/SQL: ORA-00904: "TBLTESTBANK"."ID": invalid identifier
Error(32,3): PLS-00201: identifier 'LASTAMOUNT' must be declared
Error(32,3): PL/SQL: Statement ignored
Error(34,3): PL/SQL: SQL Statement ignored
Error(34,47): PL/SQL: ORA-00904: "LASTAMOUNT": invalid identifier
You have two problems:
In your select statement:
SELECT TBLTESTBANK.ID
FROM TBLTESTBANK tblbnk
WHERE tblbnk.USERID = USERID
order by max(tblbnk.DATETIMESTAMP)
You have given the table TBLTESTBANK the alias tblbnk therefor you must use the alias throughout the statement:
SELECT tblbnk.ID -- use the correct alias here
FROM TBLTESTBANK tblbnk
WHERE tblbnk.USERID = USERID
order by max(tblbnk.DATETIMESTAMP)
Second:
in the INSERT statement you have to list columns not values.
INSERT INTO TBLTESTBANK (ID, USERID, TYPE, LastAmount,
DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
)
should be:
INSERT INTO TBLTESTBANK (ID, USERID, TYPE, AMOUNT, --- column name instead of variable name
DATETIMESTAMP, IDTRANS, TOTALMONEY, HASH
)
And then of course you need to use LastAmount in the values part, not AMOUNT
In general it's not a good idea to have variables with the same name as columns of tables that you use in the procedure. It's easy to shadow a variable with a column. You should rename the variables to avoid any problems there.
Edit (I didn't notice this at first).
You also have an error in the structure of the code. A stored procedure (or function) does not have a DECLARE section:
Your declaration needs to look like this:
CREATE OR REPLACE PROCEDURE MYTESTDB.INSERT_INTO_TESTBANK
(
....
)
IS
-- no DECLARE
-- variables right after the IS keyword
LastAmount TBLTESTBANK.TOTALMONEY%TYPE;
BEGIN
...
END;
You can try below select query to get latest record.
SELECT TB.TOTALMONEY INTO LASTAMOUNT
FROM
TESTBANK TB
WHERE
TB.USERID=USERID
AND
DATETIMESTAMP= (SELECT MAX (TB2.DATETIMESTAMP) FROM TESTBANK TB2
WHERE TB2.USERID=USERID);

db2 stored procedure to create a select query dynamically

I am new to IBM db2 stored procedure, what I am trying to do is to get the values of a column from a table and build a select query based on these values, this is what I have tried, not sure how to proceed
CREATE TYPE currencySymbols AS VARCHAR(20) ARRAY[100]#
CREATE PROCEDURE ins_curr_ano(IN crsymbol VARCHAR(20), IN cost1 integer, IN cost2 integer, IN teirId integer)
BEGIN
DECLARE currencies currencySymbols;
DECLARE maxCount INTEGER DEAFULT 0;
set currencies = ARRAY[SELECT distinct(CURR_SYMBOL) as currencySymbols FROM CURRENCY_MAPPING];
set maxCount = CARDINALITY(currencies);
for i in 1..maxCount loop
dbms_output.put_line(i);
end loop;
END#
Below is the error I am getting:
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0104N An unexpected token "loop" was found following "for i in
1..maxCount". Expected tokens may include: "(". LINE NUMBER=13.
SQLSTATE=42601
That for ... loop statement in your code has PL/SQL syntax, while everything else has DB2 SQL PL syntax. You cannot mix the two in the same routine.

Resources