CREATE OR REPLACE PROCEDURE proc_test1(p_1 varchar)
LANGUAGE plpgsql
AS $$
DECLARE
V_TEST integer := 0;
BEGIN
select count(*)
from mytab
into V_TEST
WHERE X =P_1;
RAISE NOTICE 'COUNT IS:(%)',V_TEST;
EXCEPTION
WHEN OTHERS THEN
null;
END;
$$
;
In Amazon Redshift, can I not call this stored proc in this way ?
call proc_test1(p_1 => 'x')
also, why does RAISE with a semicolon fails ? the below error handler says RAISE; - the error i get is invalid operation: syntax error at or near ;
CREATE OR REPLACE PROCEDURE risk.proc_test1(p_1 varchar)
LANGUAGE plpgsql
AS $$
DECLARE
V_TEST integer := 0;
BEGIN
select count(*)
from risk.mytab
into V_TEST
WHERE X =P_1;
RAISE NOTICE 'COUNT IS:(%)',V_TEST;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
$$
;
call proc_test1(p_1 => 'x')
Are you asking about the syntax of calls, or are you asking about named parameters?
The doc doesn't mention it so no it isn't supported.
https://docs.aws.amazon.com/redshift/latest/dg/r_CALL_procedure.html
I guess with regards to the RAISE error, you are missing required parameters
https://docs.aws.amazon.com/redshift/latest/dg/c_PLpgSQL-statements.html#r_PLpgSQL-messages-errors
RAISE level 'format' [, variable [, ...]];
All of these things are in the documentation.
Related
Working with Amazon Redshift having issue at the END IF point:
CREATE OR REPLACE PROCEDURE IF_CON()
AS $$
DECLARE
BEGIN
IF(SELECT EXISTS(SELECT clientid FROM ods_epremis.new_old_merge)) THEN
BEGIN
UPDATE ods_epremis.new_old_merge SET patientencounter_id=(SELECT max(patientencounter_id)
FROM ods_epremis.new_old_merge)+1
WHERE new_old_merge.clain_oid =(SELECT top 1 claim_oid from ods_epremis.new_old_merge)
INSERT INTO ods_epremis.CLM_REM_MAPPING_PATIENT_ENCOUNTER
SELECT * from ods_epremis.new_old_merge
where claim_oid=(select top 1 claim_oid from ods_epremis.new_old_merge order by claim_oid)
END IF
END
$$ LANGUAGE plpgsql;
Your nesting is: IF / BEGIN / END IF / END
It should probably be: IF / BEGIN / END / END IF
This keeps the BEGIN/END transaction inside the IF.
Also, based on examples from Structure of PL/pgSQL - Amazon Redshift, commands should end with semi-colons (;):
CREATE OR REPLACE PROCEDURE record_example()
LANGUAGE plpgsql
AS $$
DECLARE
rec RECORD;
BEGIN
FOR rec IN SELECT a FROM tbl_record
LOOP
RAISE INFO 'a = %', rec.a;
END LOOP;
END;
$$;
My goal is to create a stored procedure that loops through a select statement that will identify tables requiring a vacuum. I will call it from Lambda if I can get it to work. These are my ideas and code so far.
CREATE OR REPLACE PROCEDURE vac_an (rs_out INOUT refcursor)
AS $$
BEGIN
OPEN rs_out FOR SELECT 'VACUUM FULL ' + "schema" + '.' + "table" + ';' AS command
FROM svv_table_info
WHERE (unsorted > 5 OR empty > 5)
AND size < 716800;
END;
$$ LANGUAGE plpgsql;
This is a start. It compiles, but it would not execute the actual command that the cursor builds, which is:
VACUUM FULL SCHEMA.TABLE;
I guess I could call it with this:
CALL sample_cursor_test ();
My second line of thinking was something like this:
CREATE PROCEDURE vac_an()
AS $$
DECLARE
tlist RECORD;
BEGIN
FOR tlist IN EXECUTE 'SELECT 'VACUUM FULL ' + "schema" + '.' + "table" + ';' AS command FROM svv_table_info WHERE (unsorted > 5 OR empty > 5) AND size < 716800;'
LOOP
EXECUTE tlist;
END LOOP;
END;
$$ LANGUAGE plpgsql;
However that gives me :
ERROR: missing "LOOP" at end of SQL expression
Where: compile of PL/pgSQL function "vac_an" near line 4
I feel like the code is almost there I just need to loop through this cursor:
SELECT 'VACUUM FULL ' + "schema" + '.' + "table" + ';' AS command
FROM svv_table_info
WHERE (unsorted > 5 OR empty > 5)
AND size < 716800;
And execute the output line by line.
Can you please help?
You cannot call VACUUM from within a transaction, which means you cannot call VACUUM from within a procedure, since a procedure is inherently a transaction.
I have searched around on Google and here for an answer to this, and found nothing.
What I want to be able to do is something like:
DECLARE thisName string;
SET thisName = CurrentProcedure();
There is no way to fetch function name, but below procedure could help you to get procedure name from call stack.
It is a bit silly but there is no way to fetch call stack without throwing and catching an exception:
-- Returns name of the procedure which calls this procedure.
-- Returns NULL if called from top level of a script (not from a procedure).
CREATE OR REPLACE PROCEDURE yourDataset.CurrentProcedure(OUT name STRING)
BEGIN
RAISE USING MESSAGE = 'error on purpose';
EXCEPTION WHEN ERROR THEN
IF ARRAY_LENGTH(##error.stack_trace) >= 2 THEN
SET name = ##error.stack_trace[OFFSET(1)].location;
END IF;
END;
CREATE OR REPLACE PROCEDURE yourDataset.yourWorkProcedure()
BEGIN
DECLARE name STRING;
CALL yourDataset.CurrentProcedure(name);
SELECT name;
END;
CALL yourDataset.yourWorkProcedure();
I followed https://dwgeek.com/redshift-stored-procedure-return-result-set-working-example.html/ step of creating a stored procedure using a temporary table but facing the error above.
CREATE OR REPLACE PROCEDURE sample_return_table(tmp_table INOUT varchar(256))
AS '
DECLARE
row record;
BEGIN
EXECUTE ' DROP table if exists ' || tmp_table;
EXECUTE ' CREATE temp TABLE ' || tmp_table || ' AS SELECT DISTINCT table_schema FROM information_schema.tables ';
END;
'
LANGUAGE plpgsql;
Error:
[Amazon](500310) Invalid operation: syntax error at or near "DROP"
Position: 132; [SQL State=42601, DB Errorcode=500310]
1 statement failed.
May I know what is the issue ?
Here is a sample Stored Procedure from Overview of stored procedures in Amazon Redshift:
CREATE OR REPLACE PROCEDURE test_sp1(f1 int, f2 varchar)
AS $$
BEGIN
RAISE INFO 'f1 = %, f2 = %', f1, f2;
END;
$$ LANGUAGE plpgsql;
Notice that use of $$ to identify the content of the procedure, whereas your code is using '.
The problem with using ' is that it is also being used inside the procedure (eg just before DROP) and is therefore confusing Redshift.
Try changing to an unused sequence (such as $$) to avoid this problem.
I had an issue where due to database charset special characters would get weird codes assigned to them, then by getting select ascii(substr(declinereasondesc, 30,1)) from DECLINEREASON t
where declinereasonid = 7; I got code (49827) for £ in db charset. I then tried to update the records in database.
Problem that I am getting is that data does not get saved to DB or selecting into value to varchar2(6); somehow changes it and it does not match REGEXP_REPLACE any-more.
It did error when I tried using varchar2(1) which should value, which could be a hint.
declare c varchar2(6);
begin
select ascii(substr(declinereasondesc, 30,1)) into c from DECLINEREASON t
where declinereasonid = 7;
begin
update DECLINEREASON set declinereasondesc = REGEXP_REPLACE(declinereasondesc, '(.+)('||c||')(\d+)', '\1\3 (GBP)');
commit;
end;
end;
/
commit;
Update: tried declare c number; no errors but didn't update values ether
This one was caused by me being stupid - forgot to wrap c in chr(c).
declare c number;
begin
select ascii(substr(declinereasondesc, 30,1)) into c from DECLINEREASON t
where declinereasonid = 7;
begin
update DECLINEREASON set declinereasondesc = REGEXP_REPLACE(declinereasondesc, '(.+)('||chr(c)||')(\d+)', '\1\3 (GBP)');
commit;
end;
end;
/
commit;