I have a view in Snowflake that uses session variables (date ranges) within it. I want to call the view from a procedure and define the session variables based on the arguments passed to the procedure. Unfortunately the below isn't working....any ideas?
CREATE PROCEDURE TEST_PROCEDURE(DATE_FROM_a DATE, DATE_TO_a DATE)
RETURNS TABLE()
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
SET DATE_FROM = :DATE_FROM_a;
res resultset default (SELECT TOP 100 * FROM v_TEST);
BEGIN
return table(res);
END;
$$
;
The way it's written in your test, it's not actually executing the SET command statement. You can move the SET command statement to after the BEGIN. That will set the session variable. Note that setting session variables in stored procedures is only supported when executing with callers rights.
create or replace table v_test (s string);
CREATE or replace PROCEDURE TEST_PROCEDURE(DATE_FROM_a DATE, DATE_TO_a DATE)
RETURNS TABLE()
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
res resultset default (SELECT TOP 100 * FROM v_TEST);
BEGIN
SET DATE_FROM = :DATE_FROM_a;
return table(res);
END;
$$
;
call test_procedure('2012-12-12', '2020-05-01');
select $DATE_FROM;
Related
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
I want to create stored procedure for select statment below is procedure i have created but it giving data ouput blank
CREATE OR REPLACE PROCEDURE public.deactivate_unpaid_accounts()
LANGUAGE 'sql'
AS $BODY$
select * from employees where salary=10000
$BODY$;
CALL deactivate_unpaid_accounts();
Procedures (which weren't available in 9.5 to begin with) are not intended to return result sets.
If you want to return a result, you should use a function in Postgres.
CREATE OR REPLACE FUNCTION public.deactivate_unpaid_accounts()
returns setof employees
LANGUAGE sql
AS $BODY$
select *
from employees
where salary=10000;
$BODY$;
Then use it like this:
select *
from deactivate_unpaid_accounts();
I need to write a procedure in Redshift that will write to a table, but the table name comes from the input string. Then I declare a variable that puts together the table name.
CREATE OR REPLACE PROCEDURE my_schema.data_test(current "varchar")
LANGUAGE plpgsql
AS $$
declare new_table varchar(50) = 'new_tab' || '_' || current;
BEGIN
select 'somestring' as colname into new_table;
commit;
END;
$$
This code runs but it doesn't create a new table, no errors. If I remove the declare statement then it works, creating a table called "new_table". It's just not using the declared variable name.
It's hard to find good examples because Redshift is postgresql and all the postgresql pages say that it only has functions, not procedures. But Redshift procedures were introduced last year and I don't see many examples.
Well, when you are declaring a variable "new_table", and performing a SELECT ..INTO "new_table", the value is getting assigned to the variable "new_table". You will see that if you return your variable using a OUT parameter.
And when you remove the declaration, it simply work as a SELECT INTO syntax of Redshift SQL and creates a table.
Now to the solution:
Create a table using the CREATE TABLE AS...syntax.
Also you need to pass the value of declared variable, so use the EXECUTE command.
CREATE OR REPLACE PROCEDURE public.ct_tab (vname varchar)
AS $$
DECLARE tname VARCHAR(50):='public.swap_'||vname;
BEGIN
execute 'create table ' || tname || ' as select ''name''';
END;
$$ LANGUAGE plpgsql
;
Now if you call the procedure passing 'abc', a table named "swap_abc" will be created in public schema.
call public.ct_tab('abc');
Let me know if it helps :)
I am trying to write a stored procedure in AWS Redshift SQL and one of my parameters needs the possibility to have an integer list (will be using 'IN(0,100,200,...)' inside there WHERE clause). How would I write the input parameter in the header of the procedure so that this is possible (if at all?)
I've tried passing them in as a VARCHAR "integer list" type thing but wasn't sure then how to parse that back into ints.
Update: I found a way to parse the string and loop through it using the SPLIT_PART function and store all of those into a table. Then just use a SELECT * FROM table with the IN() call
What I ended up doing was as follows. I took in the integers that I was expecting as a comma-separated string. I then ran the following on it.
CREATE OR REPLACE PROCEDURE test_string_to_int(VARCHAR)
AS $$
DECLARE
split_me ALIAS FOR $1;
loop_var INT;
BEGIN
DROP TABLE IF EXISTS int_list;
CREATE TEMPORARY TABLE int_list (
integer_to_store INT
);
FOR loop_var IN 1..(REGEXP_COUNT(split_me,',') + 1) LOOP
INSERT INTO int_list VALUES (CAST(SPLIT_PART(split_me,',',loop_var) AS INT));
END LOOP;
END;
$$ LANGUAGE plpgsql;
So I would call the procedure with something like:
CALL test_string_to_int('1,2,3');
and could do a select statement on it to see all the values stored into the table. Then in my queries the need this parameter I ran:
.........................
WHERE num_items IN(SELECT integer_to_store FROM int_list);
I'm working with netezza database and have a requirement to insert a Y flag for stores in California. I wrote the below procedure
CREATE OR REPLACE PROCEDURE MY_NEW_PROCEDURE() RETURNS BOOL
EXECUTE AS OWNER LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
rec RECORD;
BEGIN
FOR rec in SELECT * from test_table
LOOP
if rec.state_code ='CA'
EXECUTE IMMEDIATE 'INSERT INTO test_table (california_stores)' || 'values('y')';
END LOOP;
END;
END_PROC;
when I call the procedure using call MY_NEW_PROCEDURE() I get an error at line EXECUTE IMMEDIATE. I'm not sure what change I need to make here.
Don't know about netezza, but below is the procedure I used to test this (using SQL developer).
Works fine for me, although it would make more sense to update the row to set california_stores to 'Y'rather than insert a new row with california_stores = 'Y' for each calafornia store that you have.....
CREATE OR REPLACE PROCEDURE "MY_NEW_PROCEDURE" as
rec test_table2%rowtype;
BEGIN
FOR rec in (SELECT * from test_table2) LOOP
if rec.state_code = 'CA' then
EXECUTE IMMEDIATE 'INSERT INTO test_table2 (california_stores)' || 'values(''y'')';
end if;
END LOOP;
END;
You didn't post the second error, but it looks to me like your insert statement isn't going to do what you want anyway. If the rec variable contains the attribute state_code and you're inserting a single value to test_table then the record will simply be empty except for a 'Y' in california_stores.
I'm going to guess that you're getting an error now either because of the spacing in the insert statement insert into test_table (california_stores)values('y') or because you didn't terminate the execute statement with a semicolon. The plsql for that line should be
execute immediate 'insert into test_table (california_stores) values (''y'');';